Java: определить угол между двумя точками

ОК, во-первых, приношу извинения, так как я знаю, что этот вопрос задавался раньше более одного раза. Однако даже после просмотра других вопросов и ответов я не смог заставить это работать в моей ситуации. См. пример ниже: Рис. 1

Все, что я просто пытаюсь сделать, это определить угол между P1 и P2, предполагая, что 0 градусов соответствует показанному выше, чтобы я мог указать стрелку между 2 в правильном направлении. Поэтому я делаю что-то вроде этого...

Point p1 = new Point(200,300); Point p2 = new Point(300,200);
double difX = p2.x - p1.x; double difY = p2.y - p1.y;
double rotAng = Math.toDegrees(Math.atan2(difY,difX));

Что получается: -45, где должно быть 45? Однако это не просто случай, я не думаю, что он возвращает отрицательный результат, например, если я изменил P1 на 300 300 (ниже P2), тогда угол должен быть равен 0, но возвращается как -90.

Поэтому мне просто интересно, может ли кто-нибудь указать, что я делаю неправильно, чтобы рассчитать это, или это вообще возможно сделать так?


person Jocelyn Wilde    schedule 25.03.2015    source источник
comment
Вы должны поместить это в функцию и вычислить и сравнить с вашими ожиданиями углы для точек O и P2, которые находятся ближе друг к другу. Основная идея использовать atan2 хороша.   -  person Lutz Lehmann    schedule 25.03.2015
comment
Хм, 0 не должен быть точкой, я ожидаю, что 0 градусов будет указывать на точку P1. Сейчас экспериментирую с методом/функцией для этого, хотя и с установкой P1 как 0,0, но не уверен, что это то, что вы имели в виду: o   -  person Jocelyn Wilde    schedule 25.03.2015
comment
Нет, я имел в виду расположение вокруг отметки 0 или O.   -  person Lutz Lehmann    schedule 25.03.2015
comment
О, извините, да, это имеет больше смысла. так что позиция/метка 0,0, я думаю, в этом случае будет 200 200.   -  person Jocelyn Wilde    schedule 25.03.2015


Ответы (3)


atan2(Y,X) вычисляет в стандартной декартовой системе координат с положительной ориентацией против часовой стрелки угол точки (X,Y) относительно луча, проходящего через (1,0). Это означает, что X — это координата вдоль луча нулевого угла, в вашей ситуации X=-difY, а Y — это координата в направлении (малых) положительных углов, что дает, с вашим предпочтением изображенному углу 45°, Y=difX . Таким образом

double rotAng = Math.toDegrees(Math.atan2(difX,-difY));
person Lutz Lehmann    schedule 25.03.2015

Вы путаете систему координат, используемую в геометрии, и систему координат, используемую на экране компьютера. В геометрии вы правильно понимаете, что 0,0 — это точка в левом нижнем углу. Однако 0,0 на экране слева - верхний угол.

Теперь поверните изображение в соответствии с координатами экрана и убедитесь, что угол рассчитан правильно.

Итак, в общем случае вы можете выбрать одно из следующих решений: 1. пересчитать координаты ваших точек в экранные координаты и обратно. 2. если ваша проблема заключается только в углах, вы можете добавить π/2 (90 градусов) к вашему результату.

person AlexR    schedule 25.03.2015
comment
Ой? Об этом я не подумал и, вероятно, объяснил бы это. В ходе своих экспериментов я пытался просто добавить 90 к результату, но это не всегда дает правильный ответ. Пока не уверен, как следовать вашему совету, так как нужно изучить, как преобразовать координаты точек в экранные... ^ - person Jocelyn Wilde; 25.03.2015
comment
Преобразование простое. Х такой же. Y есть (высота экрана - y). - person AlexR; 25.03.2015
comment
но это не всегда дает правильный ответ еще в каком случае? - person weston; 25.03.2015
comment
@AlexR при чем здесь высота экрана? Эти точки можно рассматривать как направления, поэтому достаточно их просто отрицать. - person weston; 25.03.2015
comment
@AlexR Оооо, конечно, извините, что вы говорите, что позиция y просто перевернута. Я попробую это спасибо. Уэстон: Я пытался изменить результат вычисления atan2, например, добавить к нему 90. Я думаю, что это работало в большинстве случаев, но поскольку P1 и P2 не исправлены, иногда это не срабатывало. Нужно проверить еще раз, если я был неправ. - person Jocelyn Wilde; 25.03.2015
comment
Спасибо @Alex и Weston, ваши объяснения помогли мне понять, что я делал неправильно, так что теперь это работает :) - person Jocelyn Wilde; 25.03.2015

С вашей линией double difX = p2.x - p1.x; double difY = p2.y - p1.y; вы вычисляете свой угол от p2 до 0, поэтому -45 является правильным ответом. Попробуйте поменять местами p1 с p2.

Кроме того, если P1 изменить на 300 300, тогда у вас будет угол от 0 (от 0 до P1 и от P1 до P2). Угол действительно 90 или -90 в зависимости от того, видите ли вы от P2 до 0 или от 0 до P2.

person JFPicard    schedule 25.03.2015
comment
Так что, похоже, спасибо за указание на это, что LutzL также сделал ниже, и это то, что я в итоге сделал, и теперь, кажется, работает. Спасибо! - person Jocelyn Wilde; 25.03.2015