Three.js和Cesium.js中坐标

在了解Three.js和Cesium.js前先了解并弄清楚图形学关于空间的基本概念流程:

计算机图形学

 图形学中涉及到多个坐标空间,这些空间之间的变换是图形渲染中的核心部分。下面是一些常见的图形学空间及其变换顺序:

  1. 对象空间(Object Space)

    • 这是模型的原始坐标空间,模型的顶点数据是在这个空间中定义的。
    • 变换:通常通过模型变换(Model Transformation)来改变模型在对象空间中的位置、旋转和缩放。
  2. 世界空间(World Space)

    • 模型在场景中的位置,旋转和缩放都是在世界空间中定义的。
    • 变换:世界变换(World Transformation)。
  3. 观察空间(View Space 或 Camera Space)

    • 这是从相机视角看到的场景。
    • 变换:视图变换(View Transformation)或摄像机变换。
  4. 裁剪空间(Clip Space)

    • 在这里进行透视除法,得到规范化设备坐标。
    • 变换:透视变换(Perspective Transformation)。
  5. 规范化设备坐标空间(Normalized Device Coordinates,NDC)

    • 所有的顶点坐标都被映射到[-1, 1]的范围内。
    • 变换:规范化。
  6. 屏幕空间(Screen Space)

    • 最后一步变换,将NDC坐标映射到屏幕像素坐标。
    • 变换:视口变换(Viewport Transformation)。

变换的顺序通常是从对象空间开始,经过模型变换,然后是世界变换,接着是视图变换,透视变换,规范化,最后是视口变换。

在图形管线中,几何数据首先被转换到世界空间(World Space),然后到相机空间(Camera Space),接着进行投影变换,得到裁剪空间的坐标。这个裁剪空间的坐标在[-w, w]范围内,其中w是顶点的齐次坐标的w分量。

裁剪空间中的坐标之后会经过视口变换(Viewport Transformation),将其映射到屏幕空间,最终渲染到屏幕上。

在裁剪空间中,可以进行裁剪操作,例如剔除不在视锥体内部的顶点,这样可以提高渲染效率。

在计算裁剪空间坐标时,通常使用齐次坐标来表示顶点位置,这样可以简化透视除法的计算。透视除法将裁剪空间中的坐标转换为规范化设备坐标(Normalized Device Coordinates,NDC),其x、y和z坐标范围在[-1, 1]之间。

案例参考GAMES101 04 games101-变换(模型、视图、投影)-CSDN博客

Three.js

Canvas画布空间(规范化设备空间)(-1,1)

Canvas画布布局和全屏

threejs渲染输出的结果就是一个Cavnas画布,canvas画布也是HTML的元素之一,这意味着three.js渲染结果的布局和普通web前端习惯是一样的。

通过renderer.domElement属性可以访问threejs的渲染结果,也就是HTML的元素canvas画布。

12. Canvas画布布局和全屏 | Three.js中文网

屏幕空间

 坐标转化(屏幕坐标转标准设备坐标)[transformI]

// .offsetY、.offsetX以canvas画布左上角为坐标原点,单位px
const px = event.offsetX;
const py = event.offsetY;
//屏幕坐标px、py转WebGL标准设备坐标x、y
//width、height表示canvas画布宽高度
const x = (px / width) * 2 - 1;
const y = -(py / height) * 2 + 1;

纹理贴图UV坐标空间

顶点UV坐标可以在0~1.0之间任意取值,纹理贴图左下角对应的UV坐标是(0,0)右上角对应的坐标(1,1)

UV纹理空间转到Canvas画布空间(裁剪空间) [transformII]

物体坐标空间

 局部坐标(x,y,z)

坐标转换流程
   模型转换:(不同坐标系)

  局部坐标 -> 世界坐标 -> 观察空间坐标 -> 裁剪空间坐标 -> 屏幕空间坐标

我们将 观察空间坐标系 和 裁剪空间坐标系 之间的转换统一处理,最终得到 标准设备坐标系

  局部坐标 Inverse MVP ->世界坐标 -> MVP标准设备坐标 transformI->屏幕空间坐标

纹理转换:(不同坐标系)

    纹理坐标 (transformII)-->裁剪空间坐标(Inverse MVP)->世界坐标

  ->  (MVP)标准设备坐标  ->(Inverse transformII)纹理坐标

MVP矩阵API
const viewMatrix = orthoCamera.matrixWorldInverse;//视图矩阵:世界到相机的变换矩阵。
const projectionMatrix = orthoCamera.projectionMatrix;//投影矩阵:三维到二维屏幕。
orthVpMatrix = new THREE.Matrix4();
orthVpMatrix.multiplyMatrices(projectionMatrix, viewMatrix);//为先投影,后视图

orthVpMatrix.getInverse()//获取逆矩阵

Matrix4: 用于创建和操作 4x4 矩阵。

// 创建一个单位矩阵

const matrix = new THREE.Matrix4();

// 平移物体

matrix.makeTranslation(x, y, z);

// 旋转物体

matrix.makeRotationX(angle);

// 缩放物体

matrix.makeScale(scaleX, scaleY, scaleZ);

Object3D.matrix: 用于表示物体的变换矩阵。

// 创建一个立方体

const geometry = new THREE.BoxGeometry();

const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

const cube = new THREE.Mesh(geometry, material);

// 设置物体的位置、旋转和缩放 cube.position.set(x, y, z);

cube.rotation.set(rx, ry, rz); cube.scale.set(sx, sy, sz);

ShaderMaterial.uniforms: 用于向着色器传递 uniform 变量,包括 MVP 矩阵。

// 创建着色器材质

const material = new THREE.ShaderMaterial

({ uniforms:

{ // 传递 MVP 矩阵给着色器

modelViewProjectionMatrix: { value: new THREE.Matrix4() }

},

vertexShader: vertexShaderCode,

fragmentShader: fragmentShaderCode });

以上是一些常用的 MVP 矩阵相关的 API 和方法,可以通过它们来创建和操作模型的视图和投影变换。

Cesium

Cesium中常用的坐标有两种:WGS84地理坐标系笛卡尔空间坐标系。其中,WGS84地理坐标系包括:WGS84经纬度坐标系(没有实际的对象)和 WGS84弧度坐标系(Carto-graphic);笛卡尔空间坐标系包括:笛卡尔空间直角坐标系(Cartesian3)、平面坐标系(Cartesian2),4D笛卡尔坐标系(Cartesian4)。

三维

WGS-84坐标实例创建icon-default.png?t=N7T8https://blog.csdn.net/qq_27814951/article/details/131645978?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171431375216800186598178%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171431375216800186598178&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-131645978-null-null.142^v100^control&utm_term=cesium%E4%B8%AD%E5%9D%90%E6%A0%87%E7%B3%BB%E5%8F%8A%E5%85%B6%E8%BD%AC%E6%8D%A2&spm=1018.2226.3001.4187#1.WGS-84%E5%9D%90%E6%A0%87%E5%AE%9E%E4%BE%8B%E5%88%9B%E5%BB%BA

Cartographic

(1)通过弧度创建实例:new Cesium.Cartographic(lng, lat, height)     //lng, lat为弧度,height为高度(m)

(2)通过弧度创建实例:Cesium.Cartographic.fromRadians(lng, lat, height)   //lng, lat为弧度,height为高度(m)

(3)通过角度创建实例:Cesium.Cartographic.fromDegrees(lng, lat, height)    //lng, lat为角度,height高度(m)

弧度与角度转换:

  1. // 弧度转角度

  •  Cesium.Math.toDegrees()
  1. //角度转弧度

  •  Cesium.Math.toRadians()

世界坐标系(笛卡尔)实例创建icon-default.png?t=N7T8https://blog.csdn.net/qq_27814951/article/details/131645978?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171431375216800186598178%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171431375216800186598178&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-131645978-null-null.142^v100^control&utm_term=cesium%E4%B8%AD%E5%9D%90%E6%A0%87%E7%B3%BB%E5%8F%8A%E5%85%B6%E8%BD%AC%E6%8D%A2&spm=1018.2226.3001.4187#2.%E4%B8%96%E7%95%8C%E5%9D%90%E6%A0%87%E7%B3%BB%E5%AE%9E%E4%BE%8B%E5%88%9B%E5%BB%BA

Cartesian3

(1)通过笛卡尔空间直角坐标系创建实例:new Cesium.Cartesian3(x, y, z) 

经纬度转Cartesian3

(2)通过弧度创建实例:Cesium.Cartesian3.fromRadians(lng, lat, height)    //lng, lat为弧度,height为高度(m)

(3)通过角度创建实例:Cesium.Cartesian3.fromDegrees(lng, lat, height)    //lng, lat为角度,height为高度(m)

Cesium中的坐标系统及其转换-CSDN博客

(4)   // 方法:借助ellipsoid对象,先转换成弧度再转换
var cartographic = Cesium.Cartographic.fromDegrees(lng, lat, height); //单位:度,度,米 
var cartesian3 = ellipsoid.cartographicToCartesian(cartographic)

  3.WGS-84坐标实例和世界坐标系实例相互转换icon-default.png?t=N7T8https://blog.csdn.net/qq_27814951/article/details/131645978?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171431375216800186598178%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=171431375216800186598178&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-2-131645978-null-null.142^v100^control&utm_term=cesium%E4%B8%AD%E5%9D%90%E6%A0%87%E7%B3%BB%E5%8F%8A%E5%85%B6%E8%BD%AC%E6%8D%A2&spm=1018.2226.3001.4187#3.WGS-84%E5%9D%90%E6%A0%87%E5%AE%9E%E4%BE%8B%E5%92%8C%E4%B8%96%E7%95%8C%E5%9D%90%E6%A0%87%E7%B3%BB%E5%AE%9E%E4%BE%8B%E7%9B%B8%E4%BA%92%E8%BD%AC%E6%8D%A2

(1)世界坐标转WGS-84坐标:

  • Cesium.Cartographic.fromCartesian(cartesian3);

(2)WGS-84坐标转世界坐标:

  • Cesium.Cartographic.toCartesian(cartographic);

二维 

Cartesian2->Cartesian3
  • 应用:屏幕坐标转场景坐标-获取倾斜摄影或模型点击处的坐标

 Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene,cartesian3);

viewer.screenSpaceEventHandler.setInputAction(function (event) {
    // 获取屏幕坐标;Cartesian2平面坐标格式
    const windowPosition = event.position; 
    const ray = viewer.camera.getPickRay(windowPosition); //相交的射线
 
    // 获取世界坐标系地表坐标,考虑地形,不包括模型,倾斜摄影模型表面;
    const cartesian = viewer.scene.globe.pick(ray, viewer.scene); 
    
    // 获取倾斜摄影模型或其他三维模型点击位置的世界坐标系场景坐标
    const cartesian = viewer.scene.pickPosition(windowPosition); 
 
    // 获取世界坐标系椭球面坐标,不考虑地形,模型,倾斜摄影模型表面等;
    const cartesian = viewer.scene.camera.pickEllipsoid(windowPosition);     
}) 

空间变换

Cesium为我们提供了很有用的变换工具类:Cesium.Cartesian3(相当于Point3D)Cesium.Matrix3(3x3矩阵,用于描述旋转变换)Cesium.Matrix4(4x4矩阵,用于描述旋转加平移变换),Cesium.Quaternion(四元数,用于描述围绕某个向量旋转一定角度的变换)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/4565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python快速入门1数据类型(需要具有编程基础)

数据类型: Python 3.0版本中常见的数据类型有六种: 不可变数据类型可变数据类型Number(数字)List(列表)String(字符串)Dictionary(字典)Tuple(元…

【InternLM】基于弱智吧数据的微调数据构造实验

1. 数据处理流程 在AI领域有句名言:数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已。可见数据对整个AI的决定性影响,在模型开源化的今天,很多厂商的模型结构都大同小异,那影响最终模型的一大决定因…

4.28java项目小结

这几天完成了用户修改资料模块的功能,实现了修改用户头像,昵称等信息,并且对数据库进行了操作,大致画了好友资料的页面的内容,这两天尽量完成表的创建,建立多对多的关系,实现好友的添加功能。

.DevicData-P-XXXXXXXX勒索病毒数据怎么处理|数据解密恢复

引言: 随着信息技术的飞速发展,网络安全问题日益凸显,其中勒索病毒以其独特的攻击方式和巨大的破坏性引起了广泛关注。.DevicData-P-XXXXXXXX勒索病毒就是近期出现的一种新型勒索病毒,它利用强大的加密算法和巧妙的传播手段&…

HNCTF 2022 week1 题解

自由才是生活主旋律。 [HNCTF 2022 Week1] Interesting_include <?php //WEB手要懂得搜索 //flag in ./flag.phpif(isset($_GET[filter])){$file $_GET[filter];if(!preg_match("/flag/i", $file)){die("error");}include($file); }else{highlight_…

求解素数环问题

注&#xff1a;这里我的代码是以第一位为最大数n为首元素不动的 思路&#xff1a; 首先我们分析问题要以较小规模的样例进行分析&#xff0c;例如n3时 第一步&#xff1a;深入搜索 我们先不管后面怎么样&#xff0c;当前的首要目标是先确定第一个元素的值&#xff0c;可知有…

windows电脑改造为linux

有个大学用的旧笔记本电脑没啥用了&#xff0c;决定把它改成linux搭一个服务器&#xff1b; 一、linux安装盘制作 首先要有一个大于8G的U盘&#xff0c;然后去下载需要的linux系统镜像&#xff0c;我下的是ubuntu&#xff0c;这里自选版本 https://cn.ubuntu.com/download/d…

今日arXiv最热NLP大模型论文:韩国团队提出ResearchAgent系统,模仿人类产出论文idea

你是否还在苦于想发论文却没有idea&#xff1f; 在浩瀚无边的文献中苦苦寻找却又无从下手&#xff1f; 那些看似与你研究相关的文章&#xff0c;要么已经被人研究得透彻无比&#xff0c;要么与你的方向南辕北辙&#xff0c;让你倍感挫败。 不要慌&#xff0c;让AI来助你一臂之…

日期类的实现,const成员

目录 一&#xff1a;日期类实现 二&#xff1a;const成员 三&#xff1a;取地址及const取地址操作符重载 一&#xff1a;日期类实现 //头文件#include <iostream> using namespace std;class Date {friend ostream& operator<<(ostream& out, const Dat…

C语言中的三大循环

C语言中为我们提供了三种循环语句&#xff0c;今天我就来与诸君细谈其中之奥妙。循环这一板块总结的内容较多&#xff0c;而且&#xff0c;很重要&#xff01;&#xff08;敲黑板&#xff01;&#xff01;&#xff01;)&#xff0c;所以诸君一定要对此上心&#xff0c;耐住性子…

系统服务(22年国赛)—— nmcli命令部署VXLAN

前言&#xff1a;原文在我的博客网站中&#xff0c;持续更新数通、系统方面的知识&#xff0c;欢迎来访&#xff01; 系统服务&#xff08;22年国赛&#xff09;—— VXLAN服务部署https://myweb.myskillstree.cn/118.html 目录 题目&#xff1a; AppSrv 关闭防火墙和SEli…

Linux 双击sh脚本运行无反应或一闪而退【已解决】

这里写目录标题 一、问题描述二、解决思路1. 开启终端&#xff0c;使用命令行运行.sh脚本文件2. 终端中运行可以&#xff0c;但双击之后运行闪退 (遇到了个这个奇奇怪怪的问题) 三、分析记录3.1 .bashrc设置变量的作用域3.2 环境变量冲突覆盖问题. 四、相关知识点4.1 环境变量配…

CSS详解(一)

1、css工作中使用场景 美化网页&#xff08;文字样式、背景样式、边框样式、盒子模型、定位、动画、&#xff09;&#xff0c;布局页面&#xff08;flex布局、响应式布局、媒体查询&#xff09; 2、CSS 规则 通常由两个主要部分组成选择器和样式声明 2.1选择器 选择器指定了…

C语言-用二分法在一个有序数组中查找某个数字

1.题目描述 有15个数按由大到小顺序放在一个数组中&#xff0c;输入一个数&#xff0c;要求用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组中&#xff0c;则输出“无此数” 二.思路分析 记录数组中左边第一个元素的下标为left&#xff0c;记录数组右边第一个…

Spring AI聊天功能开发

一、引入依赖 继承父版本的springboot依赖&#xff0c;最好是比较新的依赖。 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.4</version><relativePat…

【JavaScript】转化为布尔值boolean的几种情况

1 转化为布尔值boolean时为false的6种情况 下面6种值转化为布尔值时为false&#xff0c;其他转化都为true&#xff1a; 1、undefined2、null&#xff08;代表空值&#xff09;3、0&#xff08;数字0布尔值为false&#xff0c;字符串"0"布尔值为true) (数字0转布尔类…

C++笔试强训day10

目录 1.最长回文字符串 2.买卖股票的最好时机(一) 3.过河卒 1.最长回文字符串 链接 一开始没认真看题目&#xff0c;直到提交了好几遍没过还是没去检查题目&#xff0c;一直检查代码逻辑&#xff0c;哎呦&#xff0c;难受了。 我以为是收尾字母相同就行了。 错误代码&…

为什么二维数组初始化第一维数组长度可以为空,第二维不可以为空呢?

注意&#xff0c;数组第二维的长度声明永远不能省略。这是因为C语言中的二维数组元素在c编译程序为其分配的连续存储空间中是按行存放的&#xff0c;即存在完整第一行后存第二行&#xff0c;然后再第三行&#xff0c;以此类推。存放时系统必须知道每一行有多少个元素才能正确计…

一文讲解Android车载系统camera架构 - EVS

Android的camera开发中&#xff0c;使用最多的是camera2 以及现在Google主推的cameraX 架构&#xff0c;而这两个架构主要针对的是手机移动端上camera的流程。 而今天介绍的EVS(Exterior View System)架构是不同于camera2上的手机架构&#xff0c;针对Automotive的版本&#x…

软文伪原创工具有哪些,推荐3款强大的软文伪原创工具

软文作为一种重要的营销和传播手段&#xff0c;受到了越来越多的关注。而随着科技的不断发展&#xff0c;各种软文生产的工具相续出现&#xff0c;如&#xff1a;软文伪原创工具&#xff0c;它能为人们提供便捷、高效的文章生产方式&#xff0c;也及可以节省文章写作的时间与精…