- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
假设我有两个向量:
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 是方向的另一种解释。
我的想法是构建一个从对象空间到世界空间的转换矩阵,你想做的可以分三步翻译:
(0,0,0)
世界空间与物体空间相同。 v1'(0,0,0)
。v1(3.296372727813439,-14.497928014719344,12.004105246875968)
,对象空间与世界空间有偏移,但对象空间轴与世界空间轴平行,相机旋转仍然是(0 ,0,0).v2
,如您所见,相机旋转会改变。如果我能构建一个表示上述所有 Action 的转换矩阵,我就能得到方向。
我们使用基轴来获取旋转矩阵。
您可能需要设置相机向上矢量。默认值为 (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 矩阵:
然后,我们终于得到了变换矩阵:
我们可以使用矩阵表示相机方向。如果您需要欧拉 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/
这个问题在这里已经有了答案: Different ways of loading a file as an InputStream (6 个答案) 关闭 8 年前。 在我的 gradle java
给定一个 User 类: class User end 我想使用 .class_eval 定义一个新常量.所以: User.class_eval { AVOCADO = 'fruit' } 如果我尝试
这可能听起来很奇怪,但我正在开发一个需要查找 div 内的元素或 div 本身的插件。 脚本根据用户选择查找元素,但内容(包括标记)是可变的。因此脚本将按如下方式查找元素: $('.block').f
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 Improve th
我需要在按我自己的函数排序的对的多集中查找并删除一个值。显然, .find 总是将迭代器返回到末尾,而不是返回到搜索到的值。有小费吗?这是函数: struct cmp { bool operato
求助!我将如何通过遍历查看字符并计算有效字符出现之前的下划线数量来查找和删除前导下划线。以及从字符串末尾向后迭代以查找任何尾随下划线。 我可以使用下面的方法来删除下划线,但是如何迭代才能找到下划线。
如果你在 $(xml) 中有下面的 xml,你会变得懒惰: $(xml).find("animal").find("dog").find("beagle").text() 在 jQuery 中是否有类
你如何找到4个文件的交集? 我用了grep -Fx -f 1.txt 2.txt 3.txt 4.txt ,但它似乎只适用于 2 个文件。同样comm -12 1.txt 2.txt无法扩展为 4 个
我已经完成了标记的姿势估计并获得了 rvec 和 tvec 值。我不知道如何找到它的中心,因为我需要绘制一个需要中心值的圆柱体。 我该怎么做? 最佳答案 标记的 tvec 是标记从原点的平移 (x,y
我有一个任务,我需要找到 2 个单链接(单对单)列表的交集。我还必须为 2 个双向链接(双重 vs 双重)列表执行此操作: 对于单链表,我使用 mergeSort() 对两个列表进行排序,然后逐项比较
我是 R 的新手,我有一个 100x100 的方阵。我想找到这个矩阵的最大特征值。我试过了 is.indefinite(x) 但是它写 is.indefinite(x) : argument x is
您好,我是 svg 和 JavaScript 的新手,当鼠标位于 svg 上方时,我试图使一些 svg 元素弹出(通过缩放),反之亦然,当鼠标离开 svg 元素时。 我已经能够通过使用转换使 svg
我正在尝试为 scala 项目编写一个类,但在多个地方使用 class、def、while 等关键字出现此错误。 它发生在这样的地方: var continue = true while (conti
我有两个 pandas 数据框,它们只取自一列并将日期列设置为索引,所以现在我有两个 Series。我需要找到这些系列的相关性。 这里有几行来自dfd: index change 2018-
我正在尝试调整我的 Vagrantfile,因此如果它丢失,它会自动在项目根目录中创建一个文件夹。创建文件夹没问题,但我无法找到创建该文件夹的位置。 我发现此信息可在 Vagrant::Environ
我正在尝试在 jquery 中找到 Test3 的位置,请有人引导我走上正确的道路。 我需要jquery来显示5 Test7 Test2 Test6 Test5 Test3 Test8 谢谢 最佳
大家早上好 我有一个像这样的图像列表: 使用 jQuery 如何查找 ul#preload 中包含特定字符串(例如“green”)的所有图像 src 类似... var new_src = j
我正在开发一个修改 Excel 文件的应用程序。 如何找到任意行中最后使用的单元格? 示例:行号 => 5 中最后使用的单元格 最佳答案 要找到一行中的最后一个单元格,您需要 Range 的 End
我刚刚陷入 react native ,需要一些帮助才能在找到 token 时导航到 protected 屏幕。我应该在哪里寻找应用程序加载时的 token ?如何在不多次调用导航的情况下导航用户一次
非常奇怪...此页面是 protected 内容还是我不知道的内容?我尝试单击下一页 anchor 。 参见this page first. 我试图用这个来抓取元素 var buttonNext =
我是一名优秀的程序员,十分优秀!