I want to get an arrow from the point with the direction to another point.
Before begin, I'm using this method to get the arrow according to the yaw:
public static String getArrow(double yaw) {
if (22.50 < yaw && yaw < 67.50) return "⬉";
else if (67.50 < yaw && yaw < 112.5) return "⬅";
else if (112.50 < yaw && yaw < 157.5) return "⬋";
else if (157.50 < yaw && yaw < 202.5) return "⬇";
else if (202.50 < yaw && yaw < 247.5) return "⬊";
else if (247.50 < yaw && yaw < 292.5) return "➡";
else if (292.50 < yaw && yaw < 337.5)
return "⬈";
return "⬆";
}
I started by using a method like that:
public static String getArrowTo(Location position, Vector direction, Location watched) {
Vector a = watched.clone().subtract(position).toVector().normalize();
double angle = Math.acos(a.dot(direction));
return getArrow(Math.toDegrees(angle));
}
But each time that the point was on left, the arrow show the forward arrow. So, I made something when it's on left, but it's not fixed even with this trick. Actually I'm using:
public static String getArrowTo(Location position, Vector direction, Location watched) {
Vector a = watched.clone().subtract(position).toVector().normalize();
double angle = Math.acos(a.dot(direction));
if (isLeft(position, position.clone().add(direction), watched.toVector()))
angle = 360 - angle;
return getArrow(Math.toDegrees(angle));
}
public static boolean isLeft(Location a, Location b, Vector c) {
return ((b.getX() - a.getX()) * (c.getZ() - a.getZ()) - (b.getZ() - a.getZ()) * (c.getX() - a.getX())) > 0;
}
The isLeft
method comes from here.
PS: the class used are Location
and Vector
, here showed for spigot 1.19 but I'm using 1.8.8.
The left method seems to don't enough work in my case (I don't know why). By adding angle = angle < 0 ? (360 + angle) : angle
it should works better but it never goes below 0. It's always in 0-180 range.
I tested the MBo solution: it find the right, but that's all. The front is something known as back, the right is also on the left etc..
How can I fix it ?