javascript - Three.js 获取具有给定世界方向坐标的场景向量的对象相对局部方向

标签 javascript vector three.js rotation

我在场景中有一个给定的向量 V。该矢量由世界坐标 (VWx,VWy,VWz) 定义。请注意,它是方向向量而不是位置向量。

在场景中,我还有一个具有随机方向(和位置)的 Object3D。

我希望找到方向向量 V 的局部(即相对于 Object3D)坐标 (VLx,VLy,VLz)。

我尝试了以下代码(从 this question 中 WestLangley 的答案推断),但它似乎没有给出正确的结果。

var VW = new THREE.Vector3(10,20,30); 
var VL = new THREE.Vector3(0,0,0); 

givenObject.updateMatrixWorld();

var ob_WorldQuaternion = new THREE.Quaternion(); 
ob_WorldQuaternion  = givenObject.getWorldQuaternion();

var ob_InvWorldQuaternion = new THREE.Quaternion(); 
ob_InvWorldQuaternion = ob_WorldQuaternion.inverse();

VL = VW.applyQuaternion( ob_InvWorldQuaternion);

编辑(1) 请注意,THREE.js Object3D 方法 .worldToLocal(vector) 不适合,因为它仅用于转换位置向量,而不是方向向量。

EIDT(2) This jsfiddle说明了一个示例应用程序。绿色圆锥体是绿色盒子的子项。该应用程序试图保持绿色锥体与白色世界锥体指向相同的世界方向。

最佳答案

(我之前答案的改进版本)。

This jsfiddle说明了对齐子锥体的 3 种方法。

红色圆锥体相对于其父框具有固定方向。

绿色锥体已对齐,使其 z 轴与白色世界锥体对齐。

蓝色锥体的 XYZ 轴与白色世界锥体的 XYZ 轴对齐。

代码(来自 init 函数):-

cone_geometry = new THREE.CylinderGeometry(3, 40, 120, 40, 10, false);

//... The following mod is as recommended by WestLangley's answer at:-
//... http://stackoverflow.com/questions/13757483/three-js-lookat-seems-to-be-flipped
//... cone.LookAt(PosX) will then point the cone Z-axis towards PosX
//... (assuming cone.position and PosX are relative to the same coordinate system).

cone_geometry.applyMatrix( new THREE.Matrix4().makeRotationX( Math.PI / 2 ) );

核心代码(来自更新/动画功能):-

    worldCone.lookAt(target.position); 

    var worldVec =  new THREE.Vector3();
    worldVec.copy(target.position).sub(worldCone.position);

    worldBox.rotation.x += 0.01;
    worldBox.rotation.y += 0.03;
    worldBox.rotation.z += 0.02;

    var localVec =  new THREE.Vector3();
    localVec = F_get_LocalDirectionVector_relativeTo_Object3D_of_WorldDirectionVector 
( worldBox, worldVec, localVec) ;

    //=================================================================
    function F_get_LocalDirectionVector_relativeTo_Object3D_of_WorldDirectionVector 
( givenObject, WDV, LDV)
          {
              givenObject.updateMatrixWorld(); 

             //FLABBY method: - works but verbose and excessive object creation
             /*
              var ob_InvWorldQuaternion = new THREE.Quaternion(); 
              ob_InvWorldQuaternion = ob_WorldQuaternion.inverse(); 
              LDV.copy( WDV ).applyQuaternion( ob_InvWorldQuaternion );        
              */

              //LEAN method: copies WDV value into LDV 
              //then applies inverse world quaternion of givenObject.

              LDV.copy( WDV )
              .applyQuaternion( 
              givenObject.getWorldQuaternion().inverse() 
              );  

              return LDV;
      } 
      //=================================================================

//... Apply localVec 
//... Get the localCone_G to point in the direction of the LocalVec

 var localCone_G_target_pos = new THREE.Vector3();

 //... LHS becomes sum of two RHS vectors
 localCone_G_target_pos.addVectors( localCone_G.position, localVec );

//... ORIENT THE CHILD CONES

//...Cone_R has fixed orientation relative to parent cube
localCone_R.lookAt(1,0,0); 

//... Cone_G has z-vector pointing in the same direction as world cone
localCone_G.lookAt(localCone_G_target_pos); 

//... Cone_B has its' xyz axes aligned with the world cone
localCone_B.lookAt(1,0,0);
localCone_B.quaternion.multiply( worldBox.getWorldQuaternion().inverse()  ); 
localCone_B.quaternion.multiply( worldCone.quaternion );

关于javascript - Three.js 获取具有给定世界方向坐标的场景向量的对象相对局部方向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35663737/

相关文章:

javascript - 单SPA项目拆分

c++ - STL:存储引用或值?

javascript - qgis2thirdjs导出3D map 代码修改后出现空白页

javascript - 如何以像素为单位获取ThreeJS网格对象的可见宽度和高度

javascript - 如何在 Google 应用程序脚本中将数组显示到 HTML 侧边栏

javascript - 从图 block 服务器返回的 map 不完整,缩放级别可用的图 block 数量比文档指示的要多

vector - 在不重新分配的情况下将 Vec 转换为 FFI 的正确方法是什么?

c++ - 为什么可以从函数返回 'vector'?

javascript - 在 Three.js 中计算自定义几何体的光

javascript - Handlebars : What is the best way to pass multiple parameters to a registerHelper function?