Zacząłem od rozwiązania z johncarls, ale potrzebowałem go dostosować, aby uzyskać dokładnie to, czego potrzebowałem. Głównie, potrzebowałem go, aby obracać się zgodnie z ruchem wskazówek zegara, gdy kąt wzrósł. Potrzebowałem również 0 stopni, by wskazać NORTH. Jego rozwiązanie zbliżyło mnie do siebie, ale zdecydowałem się również opublikować moje rozwiązanie, na wypadek gdyby pomogło to komukolwiek innemu.
Dodałem kilka dodatkowych komentarzy, które pomagają wyjaśnić moją wiedzę na temat funkcji na wypadek konieczności wprowadzenia prostych modyfikacji.
/**
* Calculates the angle from centerPt to targetPt in degrees.
* The return should range from [0,360), rotating CLOCKWISE,
* 0 and 360 degrees represents NORTH,
* 90 degrees represents EAST, etc...
*
* Assumes all points are in the same coordinate space. If they are not,
* you will need to call SwingUtilities.convertPointToScreen or equivalent
* on all arguments before passing them to this function.
*
* @param centerPt Point we are rotating around.
* @param targetPt Point we want to calcuate the angle to.
* @return angle in degrees. This is the angle from centerPt to targetPt.
*/
public static double calcRotationAngleInDegrees(Point centerPt, Point targetPt)
{
// calculate the angle theta from the deltaY and deltaX values
// (atan2 returns radians values from [-PI,PI])
// 0 currently points EAST.
// NOTE: By preserving Y and X param order to atan2, we are expecting
// a CLOCKWISE angle direction.
double theta = Math.atan2(targetPt.y - centerPt.y, targetPt.x - centerPt.x);
// rotate the theta angle clockwise by 90 degrees
// (this makes 0 point NORTH)
// NOTE: adding to an angle rotates it clockwise.
// subtracting would rotate it counter-clockwise
theta += Math.PI/2.0;
// convert from radians to degrees
// this will give you an angle from [0->270],[-180,0]
double angle = Math.toDegrees(theta);
// convert to positive range [0-360)
// since we want to prevent negative angles, adjust them now.
// we can assume that atan2 will not return a negative value
// greater than one partial rotation
if (angle < 0) {
angle += 360;
}
return angle;
}
Właśnie zauważyłem, że ATAN2 argumenty są w odwrotnej kolejności: należy atan2 (y, x) – alexm
Nie wiem co jest nie tak, ale moje zamówienie działa dobrze, w odwrotnej kolejności nie. – Aich
Możesz zmierzyć kąt między trzema punktami. Możesz założyć, że '(0, 0)' lub '(min (x1, x2), min (y1, y2)) jest jednym z punktów, ale nie możesz narysować kąta między dwoma punktami. –