Figuring out rotation based on 3 points

Hello,

I am using the geometry object for this.
https://threejs.org/docs/index.html#api/en/core/Geometry


I have 3 3d points defined by X,Y,Z.

Point A is the location I am using to translate my geometry to.
thing.translate ( x : Float, y : Float, z : Float ) :

Points B & C are 3d points that I would like to use to calculate the rotatateX, rotatateY & rotatateZ.
Points A, B & C could be anywhere in 3d space so long as they were not all co-linear. Points A & B would be the Y axis of the original object before it was transformed.

Would any one be able to help me out with the maths here. Thanks for any help.

-Mike.

You could try calculating the needed quaternion rotations in world space based on the two axes and apply them successively after repositioning.

A snippet which would work for nested geometries:
https://jsfiddle.net/amitlzkpa/tkg54zbh/
It would need slight modification if your objects are not nested under Object3Ds.

1 Like

@amitlzkpa That demo looks like exactly what i was looking for. Thanks!

I distilled the example down to a single function however I am working with the result of a THREE.ExtrudeGeometry() function that needs to have the translation applied.

I am hoping that there is an easy way to modify this function to handle geometry. Not buffer Geometry.

async function repos(shapeMoving, p1, p2, p3) {
    console.log(shapeMoving);
    await shapeMoving.position.set(p1.x, p1.y, p1.z);


    // align the local up axis of the shapeMoving

    // get the object's local up axis
    // read parent objects orientation and apply it object's up axis
    // any other axis can also be used as a source axis here
    var srcV = new THREE.Vector3();
    var qt1 = new THREE.Quaternion();
    shapeMoving.getWorldQuaternion(qt1);
    srcV.copy(shapeMoving.up).applyQuaternion(qt1);
    // calculate the target orientation for the object up axis
    var tgtV = p2.clone().sub(p1);
    tgtV.normalize();
    // calculate the quternion that would be required for the orientation
    // based on the reference vectors
    var qt2 = new THREE.Quaternion().setFromUnitVectors(srcV, tgtV);
    // apply the rotation to the shapeMoving; that'll also align the axis helper
    await shapeMoving.applyQuaternion(qt2);




    // align the local side axis so it falls on the plane of the 3 pts


    // get the side axis in world space
    var pt1 = shapeMoving.localToWorld(new THREE.Vector3(0, 0, 1));
    var srcV = shapeMoving.position.clone().sub(pt1);
    await srcV.normalize();

    // get the normal of the plane the points lie in
    var plane = new THREE.Plane().setFromCoplanarPoints(p1, p2, p3);
    var tgtV = plane.normal.clone();
    await tgtV.normalize();

    // calculate the transformation and apply it
    var qt = new THREE.Quaternion().setFromUnitVectors(srcV, tgtV);
    await shapeMoving.applyQuaternion(qt);
}

It should work the same with Geometry as well I think.
https://jsfiddle.net/amitlzkpa/v457pokw/

What is the error does it show for you?

As a sidenote, you wouldn’t need to use await on applyQuaternion, normalize etc. Any reason why you are doing that?

The thing I am attempting to apply translations to is not an THREE.Object3D().

In my application I am using THREE.Geometry(). THREE.Geometry seems to have to have the following methods to moving and rotating the geometry.

https://threejs.org/docs/#api/en/core/Geometry

.rotateX ( radians : Float ) : Geometry
Rotate the geometry about the X axis. This is typically done as a one time operation but not during the render loop.
Use Object3D.rotation for typical real-time mesh rotation.

.rotateY ( radians : Float ) : Geometry
Rotate the geometry about the Y axis. This is typically done as a one time operation but not during the render loop.
Use Object3D.rotation for typical real-time mesh rotation.

.rotateZ ( radians : Float ) : Geometry
Rotate the geometry about the Z axis. This is typically done as a one time operation but not during the render loop.
Use Object3D.rotation for typical real-time mesh rotation.

.translate ( x : Float, y : Float, z : Float ) : Geometry
Translate the geometry. This is typically done as a one time operation but not during the render loop.
Use Object3D.position for typical real-time mesh translation.

The JS Fiddle demo no longer seems to be working.

Fixed it here: https://jsfiddle.net/twgmpnf7/

BTW: The demo broke because three.js files from different releases were included (which is actually a no-go). Now, three.js and OrbitControls are both from r123.