CounterClockwise Angle between two 3d vectors

Hi all,

I am creating hexagonal sphere and trying to get clockwise angle of three tiles.


(The blue tiles is just ranomly generated)

For example, I want to get clockwise angle between cn and cp based on cp axis.

p is center of tile no.10.
c is center of tile no.11.
n is center of tile no.12.

I’ve tried “angleTo” function, but only get the inner angle(0~180).


let cp = new THREE.Vector3(p[0] - c[0], p[1] - c[1], p[2] - c[2]);
let cn = new THREE.Vector3(n[0] - c[0], n[1] - c[1], n[2] - c[2]);
let a = cn.angleTo(cp);
console.log((a * 180) / Math.PI);

Also, tried “setFromCoplanarPoints”, but I think the nomal plane is not working as I expected.


let normal = new THREE.Plane().setFromCoplanarPoints(
  new THREE.Vector3(c[0], c[1], c[2]),
  new THREE.Vector3(p[0], p[1], p[2]),
  new THREE.Vector3(n[0], n[1], n[2])
).normal;
console.log((normal.z * a * 180) / Math.PI);

Finaly, I’ve tried to calculated Euler Angle, but could not figure out what the next step is…

//http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/index.htm
var qrot = new THREE.Quaternion();
qrot.setFromUnitVectors(cp.normalize(), cn.normalize());
let sqw = qrot._w * qrot._w;
let sqx = qrot._x * qrot._x;
let sqy = qrot._y * qrot._y;
let sqz = qrot._z * qrot._z;
let heading = Math.atan2(2 * qrot._y * qrot._w - 2 * qrot._x * qrot._z, 1 - 2 * qrot._y * qrot._y - 2 * qrot._z * qrot._z);

**The initial tiles and next tile have fixed position.

None of those approches not working. I might miss some axis settings or calculation. I would greatly appreciate if you could give some advice.

[UPDATE]
Is there way to distinguish the degree A and degree B?

[SOLVED] by @rrrr_rrrr
get the cross product of the two vectors and use the right hand rule to determine the direction of the angle.

let p = new THREE.Vector3(p.x, p.y, p.z); // previous tile 
let c = new THREE.Vector3(c.x, c.y, c.z); //current tile
let n = new THREE.Vector3(n.x, n.y, n.z); // next tile

let cp = p.sub(c).normalize();
let cn = n.sub(c).normalize();

let angle = ((cp.clone().cross(cn).z < 0 ? -1 : 1)*Math.acos(cp.dot(cn))*180/Math.PI);

Thank you in advance for your help.

let a = cn.angleTo(cp);
console.log( Math.max( 2*Math.PI - a, a ) * 180 / Math.PI );
2 Likes

Hi @rrrr_rrrr , thank you for your reply.
I tried it, but stil get the same degree. For example of above image,
Degree A has to be 120, and Degree B has to be -120 or 240.

Hello,
Why don’t we get the cross product of the two vectors and use the right hand rule to determine the direction of the angle.

If z component of cross-product vector is negative then is clockwise.

Angle_1.html (1.1 KB)

[ Edit ] fixed the broken link in the attachment.

3 Likes

Thank you @rrrr_rrrr

It works perfectly! :partying_face:

1 Like

You are welcome.

Thank you rrrr_rrrr, this solution worked well for me calculating vertex positions in a room with obtuse and acute wall angles and slanted ceilings.
As I worked out, to use on a flat plane, just test the direction of the y vector instead (up in threejs) as above.

This method doesn’t seem to be giving accurate output for vectors with less than 20 degree angle. Is anyone else facing this issue?