gpt4 book ai didi

javascript - 找到旋转点的 Angular ,使其面向 3d 空间中的另一个点

转载 作者:搜寻专家 更新时间:2023-11-01 04:29:31 25 4
gpt4 key购买 nike

假设我有两个向量:

V1 = { x:3.296372727813439,y:-14.497928014719344,z:12.004105246875968 }

V2 = { x: 2.3652551657790695, y: -16.732085083053185, z: 8.945905454164146 }

如何确定 v1 需要旋转多少 Angular 才能直视 v2?

换成英语:说我确切地知道我在太空中的位置,以及另一个人在太空中其他地方的确切位置......从数学上讲,我怎么能弄清楚我的手指应该以什么 Angular 指向他们?

Here's what my axis looks like

我当前的(不正确的)公式

v2.x -= v1.x; // move v2 (vector 2) relative to the new origin
v2.y -= v1.y;
v2.z -= v1.z;

v1.x = 0; // set v1 (vector 1) as the origin
v1.y = 0;
v1.z = 0;

var r = Math.sqrt(Math.pow(v2.x,2) + Math.pow(v2.y,2) + Math.pow(v2.z,2));
var θ = Math.acos((Math.pow(v2.x,2) + Math.pow(v2.z,2))/(r*Math.sqrt(Math.pow(v2.x,2) + Math.pow(v2.z,2))));
var ϕ = Math.acos(v2.x/Math.sqrt(Math.pow(v2.x,2) + Math.pow(v2.z,2)));

然后我用 theta 和 phi 旋转 v1。

v1.rotation.y = θ;
v2.rotation.x = ϕ;

但这给了我错误的旋转。

θ = 0.6099683401012933

φ = 1.8663452274936656

但是如果我使用 THREE.js 并使用 lookAt 函数,它会吐出这些旋转,效果很好:

y/θ: -0.24106818240525682

x/φ: 2.5106584861123644

提前感谢所有帮助!我不能在我的最终结果中使用 THREE.js,我正在尝试使用纯 vanilla JS,以便我可以将它移植到另一种语言。

最佳答案

使用矩阵怎么样?我认为 v1 是您的观点,并期待 v2。矩阵是显示方向的好方法。欧拉 Angular 是方向的另一种解释。

我的想法是构建一个从对象空间到世界空间的转换矩阵,你想做的可以分三步翻译:

  1. 开始时,相机在世界空间原点,相机旋转为(0,0,0) 世界空间与物体空间相同。 v1'(0,0,0)
  2. 我们将相机转换为v1(3.296372727813439,-14.497928014719344,12.004105246875968),对象空间与世界空间有偏移,但对象空间轴与世界空间轴平行,相机旋转仍然是(0 ,0,0).
  3. 我们让相机看 v2,如您所见,相机旋转会改变。

如果我能构建一个表示上述所有 Action 的转换矩阵,我就能得到方向。

  1. 首先,计算平移矩阵:因为平移是一个仿射变换,所以我们需要用一个4x4的矩阵来表示平移。我们可以很容易地得到矩阵: translation matrix
  2. 我们使用基轴来获取旋转矩阵。

    您可能需要设置相机向上矢量。默认值为 (0,1,0)。在对象空间中,基z轴可以通过v1-v2计算。

    z = (v1.x-v2.x,v1.y-v2.y,v1.z-v2.z).normalize()

    x向量:我们知道基向量是垂直于z-up平面的向量,我们通过叉积得到x向量向上和 z

    x = up.crossproduct(z)

    y向量,y垂直于z-x平面。

    y = z.product(x)

    我们可以将旋转矩阵构建为 3 x 3 矩阵:

    rotation matrix

    然后,我们终于得到了变换矩阵:

    transformation matrix

    我们可以使用矩阵表示相机方向。如果您需要欧拉 Angular 或四元数。有一些方法可以在它们之间进行转换。你可以在本书中找到:3D Math Primer for Graphics and Game Developmen

    Three.js 实现的LookAt() 功能和我的一样。

    这里是three.js源码,我加了一些注释:

    function lookAt( eye, target, up ) //eye : your camera position; target :     which point you want to look at; up : camera up vector
    {

    if ( x === undefined ) {

    x = new Vector3();
    y = new Vector3();
    z = new Vector3();

    }

    var te = this.elements; //this.elements is a 4 x 4 matrix stored in a list.

    z.subVectors( eye, target ).normalize(); // set z vector with the direction from your camera to target point.

    if ( z.lengthSq() === 0 ) {

    z.z = 1;

    }

    x.crossVectors( up, z ).normalize(); // set the x vector by cross product up and z vector, you know cross product would get a //vector which perpendicular with these two vectors.

    if ( x.lengthSq() === 0 ) {

    z.z += 0.0001; // if z is ZERO vector, then, make a little addition to z.z
    x.crossVectors( up, z ).normalize();

    }

    y.crossVectors( z, x ); // set y by cross product z and x.

    // using basic axises to set the matrix.
    te[ 0 ] = x.x; te[ 4 ] = y.x; te[ 8 ] = z.x;
    te[ 1 ] = x.y; te[ 5 ] = y.y; te[ 9 ] = z.y;
    te[ 2 ] = x.z; te[ 6 ] = y.z; te[ 10 ] = z.z;

    return this;

    };
    // now you get the transformation matrix, you can set the rotation or orientation with this matrix.

您可以像 three.js 那样用列表实现 Matrix。

我还有一个想法——球面极坐标系。球坐标总是记为 (r,Θ,Φ),Θ 是航向 Angular ,Φ 是俯仰 Angular 。您需要做的是将 v1 和 v2 笛卡尔坐标转换为球坐标。因为spherical的第二个和第三个元素是 Angular ,所以我们可以计算v1和v2之间的 Angular 位移。然后,将此位移添加到相机旋转中。

这是我的代码(假设你的相机在世界原点(0,0,0)):

//convert v1 and v2 Cartesian coordinates to Spherical coordinates;
var radiusV1 = Math.sqrt( Math.pow(v1.x) + Math.pow(v1.y) + Math.pow(v1.z));
var headingV1 = Math.atan2(v1.x , v1.z);
var pitchV1 = Math.asin(-(v1.y) / radiusV1);

var radiusV2 = Math.sqrt( Math.pow(v2.x) + Math.pow(v2.y) + Math.pow(v2.z));
var headingV2 = Math.atan2(v2.x , v2.z);
var pitchV2 = Math.asin(-(v2.y) / radiusV2);

//calculate angular displacement.
var displacementHeading = headingV2 - headingV1;
var displacementPitch = pitchV2 - pitchV1;

//make this displacement as an addition to camera rotation.
camera.rotation.x += displacementPitch;
camera.rotation.y += displacementHeading;

顺便说一句,3D数学非常有帮助,值得学习,我引用的所有公式或概念都可以在书中找到。

希望对您有所帮助。

关于javascript - 找到旋转点的 Angular ,使其面向 3d 空间中的另一个点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42536597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com