Вычисление угла между линией, определяемой двумя точками

В настоящее время я разрабатываю простую 2D-игру для Android. У меня есть неподвижный объект, который находится в центре экрана, и я пытаюсь заставить этот объект вращаться и указывать на область на экране, к которой прикасается пользователь. У меня есть постоянные координаты, которые представляют центр экрана, и я могу получить координаты точки, которую пользователь нажимает. Я использую формулу, изложенную в этом форуме: Как получить угол между двумя точками?

Solutions Collecting From Web of "Вычисление угла между линией, определяемой двумя точками"

Предположения: x – горизонтальная ось и увеличивается при движении слева направо. y – вертикальная ось и увеличивается от нижнего кверху. (touch_x, touch_y) – это точка, выбранная пользователем. (center_x, center_y) – это точка в центре экрана. theta измеряется против часовой стрелки от оси +x . Затем:

 delta_x = touch_x - center_x delta_y = touch_y - center_y theta_radians = atan2(delta_y, delta_x) 

Изменить : вы упомянули в комментарии, что y увеличивается сверху вниз. В таком случае,

 delta_y = center_y - touch_y 

Но было бы правильнее описать это как выражение (touch_x, touch_y) в полярных координатах относительно (center_x, center_y) . Как упоминал ChrisF, идея принятия «угла между двумя точками» не определена.

Мне нужна была аналогичная функциональность, поэтому после многократного волочения я придумал функцию ниже

 /** * Fetches angle relative to screen centre point * where 3 O'Clock is 0 and 12 O'Clock is 270 degrees * * @param screenPoint * @return angle in degress from 0-360. */ public double getAngle(Point screenPoint) { double dx = screenPoint.getX() - mCentreX; // Minus to correct for coord re-mapping double dy = -(screenPoint.getY() - mCentreY); double inRads = Math.atan2(dy, dx); // We need to map to coord system when 0 degree is at 3 O'clock, 270 at 12 O'clock if (inRads < 0) inRads = Math.abs(inRads); else inRads = 2 * Math.PI - inRads; return Math.toDegrees(inRads); } 

Несколько ответов здесь попытались объяснить проблему «экрана», где top left0,0 а bottom right (положительный), screen width, screen height . Большинство сеток имеют ось Y как положительную над X не ниже.

Следующий метод будет работать со значениями экрана вместо значений «сетки». Единственное отличие от исключенного ответа состоит в том, что значения Y инвертированы.

 /** * Work out the angle from the x horizontal winding anti-clockwise * in screen space. * * The value returned from the following should be 315. * <pre> * x,y ------------- * | 1,1 * | \ * | \ * | 2,2 * </pre> * @param p1 * @param p2 * @return - a double from 0 to 360 */ public static double angleOf(PointF p1, PointF p2) { // NOTE: Remember that most math has the Y axis as positive above the X. // However, for screens we have Y as positive below. For this reason, // the Y values are inverted to get the expected results. final double deltaY = (p1.y - p2.y); final double deltaX = (p2.x - p1.x); final double result = Math.toDegrees(Math.atan2(deltaY, deltaX)); return (result < 0) ? (360d + result) : result; } 

Если вы считаете, что координата y обращена, просто отрицайте значение (значения). Получает ли ответ больше смысла?

«Начало находится в верхнем левом углу экрана, а Y-координата увеличивается вниз, а X-координата увеличивается вправо, как обычно. Думаю, мой вопрос становится, мне нужно преобразовать координаты экрана в декартовы координаты Перед применением вышеуказанной формулы? "

Если вы вычисляли угол, используя декартовы координаты, и обе точки были в квадранте 1 (где x> 0 и y> 0), ситуация была бы идентична координатам пиксельных пикселей (за исключением перевернутого Y. Если вы Отрицайте Y, чтобы получить его правую сторону, он становится квадрантом 4 …). Преобразование координат пиксельных пикселей в декартовы не меняет угол.