rotateAboutPoint() Floating Point Error

I am trying to rotate a Group around the center of a backbone Mesh using the following method:

function rotateAboutPoint(obj, point, axis, theta, pointIsWorld) {
    pointIsWorld = (pointIsWorld === undefined) ? false : pointIsWorld;

    if (pointIsWorld) {
        obj.parent.localToWorld(obj.position); // compensate for world coordinate
    }
    obj.position.sub(point); // remove the offset
    obj.position.applyAxisAngle(axis, theta); // rotate the POSITION
    obj.position.add(point); // re-add the offset

    if (pointIsWorld) {
        obj.parent.worldToLocal(obj.position); // undo world coordinates compensation
    }

    obj.rotateOnAxis(axis, theta); // rotate the OBJECT}.

for (let i = 0; i < selected_bases.length; i++) {
      let visobj = nucleotides[selected_bases[i].id].visual_object;
            let temp = new THREE.Vector3();
            visobj.children[0].getWorldPosition(temp);

            //create a blue LineBasicMaterial
            var material = new THREE.LineBasicMaterial({ color: 0x800000 });
            material.linewidth = 2;
            var geometry = new THREE.Geometry();
            geometry.vertices.push(temp);
            let temp1 = new THREE.Vector3(temp.x, temp.y - 3, temp.z)
            geometry.vertices.push(temp1);
            var line = new THREE.Line(geometry, material);
            scene.add(line);
            let temp3 = new THREE.Vector3();
            temp3.copy(temp);
            temp3.normalize()
            rotateAboutPoint(visobj, temp, temp3, Math.PI/2, true);
            render();
        }

The red lines represent where the Group has been.
After a 10 iterations, the results are as desired:
canvas-2

After 100 iterations however, the Group spirals out of control:
canvas

Thank you for all of your help!

I know the reason probably is a floating point error because the rotation angle become slightly off in the beginning iterations:
[Log] THREE.WebGLRenderer – “92” (three.js, line 21174)
[Log] Euler {_x: 0.26773106727538737, _y: 0.705479647297021, _z: 1.3178321900052652, _order: “XYZ”, onChangeCallback: function, …} (translation.js, line 79)
[Log] Euler {_x: -0.7873728682361268, _y: 0.8450846853968035, _z: -2.772324270597087, _order: “XYZ”, onChangeCallback: function, …} (translation.js, line 79)
[Log] Euler {_x: -0.7409180108304473, _y: 0.09979381333926798, _z: -1.378119257569711, _order: “XYZ”, onChangeCallback: function, …} (translation.js, line 79)
[Log] Euler {_x: -5.828670879282071e-16, _y: -1.6653345369377333e-16, _z: -3.885780586188048e-16, _order: “XYZ”, onChangeCallback: function, …} (translation.js, line 79)
[Log] Euler {_x: 0.26773106727538676, _y: 0.7054796472970207, _z: 1.3178321900052643, _order: “XYZ”, onChangeCallback: function, …} (translation.js, line 79)
[Log] Euler {_x: -0.7873728682361285, _y: 0.8450846853968027, _z: -2.7723242705970867, _order: “XYZ”, onChangeCallback: function, …} (translation.js, line 79)
[Log] Euler {_x: -0.7409180108304467, _y: 0.09979381333926682, _z: -1.3781192575697119, _order: “XYZ”, onChangeCallback: function, …} (translation.js, line 79)
[Log] Euler {_x: -2.2759572004815705e-15, _y: -7.771561172376095e-16, _z: 5.551115123125693e-17, _order: “XYZ”, onChangeCallback: function, …} (translation.js, line 79)
[Log] Euler {_x: 0.2677310672753827, _y: 0.7054796472970218, _z: 1.3178321900052654, _order: “XYZ”, onChangeCallback: function, …} (translation.js, line 79)
[Log] Euler {_x: -0.7873728682361374, _y: 0.8450846853967992, _z: -2.772324270597085, _order: “XYZ”, onChangeCallback: function, …} (translation.js, line 79)

TBH, I don’t understand what you are doing in rotateAboutPoint(). Can you please provide a simple live example that shows your code in action?

This is where I got the rotateAboutPoint() function code from:

I tried to create an example on JSFiddle but it is not working. It works through my code on Visual Studio Code though and the problem of the high iterations malfunctioning does not occur. I am not sure why.
https://jsfiddle.net/Lnfzawgr/24/#&togetherjs=bEdfwVKlGC

Then my actual not working code is on https://github.com/sulcgroup/oxdna-viewer/tree/dev
More specifically:https://github.com/sulcgroup/oxdna-viewer/blob/dev/js/translation.ts

1 Like

Maybe like this: https://jsfiddle.net/f2Lommf5/9221/

The center of your group is calculated via a bounding box.

Ok, thank you!

But why do higher iterations not cause problems here but do in my original code? I do the rotations in the same way.

Sry, I don’t know that. Unfortunately, I have no time to analyze your app in detail. I suggest you start with this simple fiddle and add your app code step by step. This might help to identify the source of the problem.

Ok, thank you.