I’m coding a flocking algorithm in Java but I’m stuck at a certain point (using the Ardor3D libraries, in a 2D plane).
Basically, I need to find the angle difference to add to the current rotation. If you can only get the way it should be pointing with polar coordinates with 0 degs at north and not the difference, not to worry — I have a method which returns the angle difference taking into account the wraparound on the angle and negative angles.

At the moment, I have the following code, which clearly wouldn’t work since the algorithm has no reference to the initial rotation:
long tpf = currUpdateTimeMS - lastUpdateTimeMS;
Vector2 pos = new Vector2();
rt.getPosition(pos);
double rot = pos.angleBetween(app.getAvgBoidPos(new Vector2()).normalizeLocal());
rt.setRotation(rot);
pos.addLocal(
Math.cos((rot - MathUtils.HALF_PI)) * (tpf / 10f),
Math.sin((rot - MathUtils.HALF_PI)) * (tpf / 10f)
);
rt.setPosition(pos);
super.updateLogic();
Updated code (not working, from first answer):
long tpf = currUpdateTimeMS - lastUpdateTimeMS;
//rt.setRotation(rt.getRotation() + ((tpf / (ROT_SPEED / 2f)) % 360));
Vector2 avgpos = app.getAvgBoidPos(new Vector2());
Vector2 pos = rt.getPosition(new Vector2());
avgpos.subtractLocal(pos);
double angleRads = rt.getRotation() * FastMath.DEG_TO_RAD;
double rot = MathUtils.acos((
(avgpos.getX() * MathUtils.sin(angleRads)
) +
(avgpos.getY() * MathUtils.cos(angleRads)
)) / ((Math.pow(avgpos.getX(), 2) + Math.pow(avgpos.getY(), 2)) * 0.5));
double adegdiff = rot * FastMath.RAD_TO_DEG;
rt.setRotation(rt.getRotation() - adegdiff);
double newrot = rt.getRotation();
pos.addLocal(
Math.cos((newrot - MathUtils.HALF_PI)) * (tpf / 10f),
Math.sin((newrot - MathUtils.HALF_PI)) * (tpf / 10f)
);
rt.setPosition(pos);
super.updateLogic();
Another modification based on the other answer:
long tpf = currUpdateTimeMS - lastUpdateTimeMS;
//rt.setRotation(rt.getRotation() + ((tpf / (ROT_SPEED / 2f)) % 360));
Vector2 avgpos = app.getAvgBoidPos(new Vector2());
Vector2 pos = rt.getPosition(new Vector2());
avgpos.subtractLocal(pos);
double rot = pos.angleBetween(
app.getAvgBoidPos(new Vector2()).normalizeLocal()
) - (rt.getRotation() * MathUtils.DEG_TO_RAD);
rt.setRotation(rt.getRotation() - (rot * MathUtils.RAD_TO_DEG));
double newrot = rt.getRotation();
pos.addLocal(
Math.cos((newrot - MathUtils.HALF_PI)) * (tpf / 10f),
Math.sin((newrot - MathUtils.HALF_PI)) * (tpf / 10f)
);
rt.setPosition(pos);
super.updateLogic();
I’m not really too good at Maths problems, so code would be helpful rather than formulas 🙂
Inputs
- Current position of entity
- Current rotation of entity (polar-oriented) in degrees
Output
- Degrees or radians to add or subtract to current rotation
- … or degrees or radians expressed as polar-oriented angle
Thanks in advance if you can help 🙂
Chris
You can use the dot product to determine the cosine of the angle (in radians) between the current orientation and the point you want to face. Assume the agent doing the viewing is locate at the origin and oriented to face some direction given by the angle θ relative to the Y-Axis (i.e. 0 degrees is “up” or “north”). You want to find the angular difference θ’ between that direction and facing a point (x, y). That is given by:
Subtracting θ’ from θ will orient the agent towards the target.
If the agent is not at the origin, simply subtract the position of the agent from the object to view to bring it into the form above.