坐标系

(1)【世界坐标系】是一个特殊的坐标系,它建立了描述其他坐标系所需要的参考框架。泛称全局坐标系或宇宙坐标系。关于世界坐标系的典型问题都是关于初始位置和环境的。如:

  • 每个物体的位置和方向。

  • 摄像机的位置和方向。

  • 世界中没一点的地形是什么(山丘、建筑、湖泊等)。

  • 各物体从哪里来、到哪里去(NPC的运动策略)。

(2)【物理坐标系】和特定物体关联的坐标系。每个物体都有它们独立的坐标系。当物体移动或改变方向时,和物体相关联的坐标系将随之移动或改变方向。

(3)【摄像机坐标系】和观察者密切相关。摄像机坐标系和屏幕坐标系类似,差别在于摄像机坐标系处于3D空间中。摄像机在原点,x 轴向右,z 轴向前(朝向屏幕内或摄像机方向,如果采用右手坐标系,则 z 轴向外——即从屏幕指向读者),y 轴向上(不是世界的上方而是摄像机本身的上方)。

(4)【惯性坐标系】在世界坐标系到物体坐标系的“半途“。惯性坐标系原点和物体坐标系原点重合,但惯性坐标系的轴平行于世界坐标系的轴。

(5)【坐标转换】是指在一个m维拓扑流形中一个坐标邻域到另一个坐标邻域的坐标的变换。


📐 数学公式

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
点的距离
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
三维空间中两个点 A(x1,y1,z1)B(x2,y2,z2) 之间的欧氏距离(真实距离): 
D = ((x2−x1)²+(y2−y1)²+(z2−z1)²)

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
中点坐标
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
(x,y,z) = ((x1+x2)÷2, (y1+y2)÷2, (z1+z2)÷2)

■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
3D 几何中的直线表示
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
可以通过以下两种方法计算三维笛卡尔系统中的直线方程。 求直线方程的两种方法如下:
通过点 a 并平行于给定矢量 b 的直线方程: 
r = a + λb

通过两个给定点 a 和 b 的直线方程可以表示为: 
r = a + λ(b - a)

📌 JavaScript

参考代码:index.js

/**
 * 使用欧拉角公式进行旋转
 * 您不能只在 2D 画布的坐标 [X,Y] 处绘制每个点。 您需要一种方法来表示它的深度,换句话说就是透视:进行投影。
 * - 获取点的坐标:x,y,z
 * - 使用欧拉方程执行相机旋转
 *
 * @param {Number} a - 坐标值 a
 * @param {Number} b - 坐标值 b
 * @param {Number} angle - 角度
 * @returns {Number} 返回新的坐标值
 */
function rotate(a, b, angle) {

    return [
        Math.cos(angle) * a - Math.sin(angle) * b,
        Math.sin(angle) * a + Math.cos(angle) * b
    ];
}

/**
* 2D 画布上的 3D 投影
* 欧拉角的基本思想是将角位移分解为绕三个互相垂直轴的三个旋转组成的序列。
*
* 使用左手坐标系,在标准方位上,让物体作 heading、pitch、bank旋转。
* - heading 为绕 y 轴的旋转量
* - pitch 为绕 x 轴的旋转量
* - bank 为绕 z 轴的旋转量
*
* @param {Object} obj - 点的坐标
* @returns {Object} 返回旋转后的坐标
*/
export function myAction({ x, y, z }) {

    /* heading、pitch、bank的旋转量和摄像机相关(偏航角、俯仰角、翻滚角),摄像机的三个角度改变,就会造成对象的计算后的坐标改变 */
    const camX = 0;
    const camY = 0;
    const camZ = -10;
    const camYaw = 10;  
    const camPitch = 15;
    const camRoll = 25;

    /* 转换后的新的坐标,每次转换都是基于上一次转换的值 */
    [x, z] = rotate(x, z, camYaw);
    [y, z] = rotate(y, z, camPitch);
    [x, y] = rotate(x, y, camRoll);

    x -= camX;
    y -= camY;
    z -= camZ;

    return { x, y, z };
}

测试:test.js

import { myAction } from './index';


console.log( myAction({x:10, y:30, z:45}) );
/* 输出:
{
    "x": 16.650252898073003,
    "y": 3.124573655016236,
    "z": 62.32596026739108
}
*/