1
votes

I have a given vector V in a scene. The vector is defined by World Coordinates (VWx,VWy,VWz). Note that it is a direction vector NOT a position vector.

In the scene I also have an Object3D with random orientation (and position).

I wish to find the local (i.e. relative to the Object3D) coordinates (VLx,VLy,VLz) of the direction vector V .

I have tried the following code (extrapolating from WestLangley's answer in this question) but it doesn't seem to give the right results.

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);

EDIT(1) Note that the THREE.js Object3D method .worldToLocal(vector) is not suitable because that is just for converting position vectors, not direction vectors.

EIDT(2) This jsfiddle illustrates an example application. The green cone is a child of the green box. The app is trying to keep the green cone pointing in the same world direction as the white world cone.

1
Maybe this is your issue?Wilt
@Wilt - Thx for suggestion but I'm not sure about that question and I definitely don't understand the answer given enough to apply it (in three.js) .steveOw
Maybe you can explain what you want to achieve. There might be easier ways to get to your end goal? What is the source of this direction vector?Wilt
@Wilt. I just want to make a general function of the form VL = F_get_LocalDirectionVector_relativeTo_Object3D_of_WorldDirectionVector (givenObject, VW). For example VW = world direction of the wind and Object3D = a randomly-oriented wind turbine and so VL is the wind direction relative to the turbine's xyz axes.steveOw
@Wilt I think that the original code worked OK but I was applying the result wrongly. See my answer. Thanks for your input and sorry for wasting your time.steveOw

1 Answers

1
votes

(An improved version of my earlier answer).

This jsfiddle illustrates 3 ways of aligning child cones.

Red cone has fixed orientation relative to its parent box.

Green cone is aligned so that its' z-axis is aligned to the white world cone.

Blue cone has its' XYZ axes co-aligned with the XYZ axes of the white world cone.

CODE (from the init function):-

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 ) );

CORE CODE (from the update/animate function):-

    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 );