I seem to be struggling with calculating the angle between image elements on a 2D screen.

The goal is to effectively draw a line with a rectangle by rotating it toward the object and then setting the height equal to the distance between the objects. The only problem is that whenever I calculate the angle like this:

var vecA = this.entity.getPosition().normalize();
var vecB = this.target.getPosition().normalize();
var dot = vecA.dot(vecB);
var angleInRadians = Math.acos(dot);
var angle = angleInRadians * pc.math.RAD_TO_DEG;
console.log(angle);
this.entity.rotateLocal(0,0,angle);

The resulting angle is off by about 50 degrees. Am I going about this the wrong way?

I did some additional testing, and unfortunately 50 degrees is not the only offset. They seem to be random. One idea is that it could be calculating on the wrong axis, but that seems unlikely. I placed two elements at 0 on the Y axis and experimented with different distances. The angles still seemed random, and it never actually came out to 90 degrees. Not even close

@eproasim First you could get vector IJ which is equal to positionJ - positionI,then you could get the angle between vector IP (which is (0,1,0) in this case) and vector IJ(don’t forget to normalize) by dot product just like what you did.you can give it a try and see if it works

It’s much much closer now! Thank you for the assistance! I think I’m going wrong in calculating a vector somewhere though. Here is what I have now.

var yVec = new pc.Vec3(0,1,0).normalize();
var vecA = this.entity.getPosition().normalize();
var vecB = this.target.getPosition().normalize();
var posVector = vecB.sub(vecA).normalize();
var dot = posVector.dot(yVec);
var angleInRadians = Math.acos(dot);
var angle = angleInRadians * pc.math.RAD_TO_DEG;
console.log(angle);
this.entity.rotateLocal(0,0,angle);

The result is only off by a few degrees, and I have confirmed that my pivots are in the center of the circles. Any ideas?

Thank you very much for the assistance. It worked! Like in LeXXik’s example, I did have to declare a new pc.Vec3() variable ahead of time then use .copy() later in the script to calculate my rotation based on getLocalPosition(). Not using .copy() will move the target to the origin entity’s position.

I think that’s because UI elements belonging to a 2D screen are always positioned in local space in relation to that screen. And the screen is rendered in screen space, so a world position like the one returned by the getPosition() method doesn’t really make sense in this case.