#математика #android #java #геометрия
Рисую на Canvas равнобедренный треугольник посередине экрана. Рисую от центра треугольника (места пересечения медиан). Соответственно, известны экранные координаты центра треугольника и размер треугольника. Нужно иметь возможность поворачивать треугольник на произвольный (рандомный) угол по часовой стрелке. Делаю так: // Исходные данные float angle = 90; // Угол на который будем поворачивать треугольник final float height = 60; // Высота треугольника final float width = 36; // Ширина треугольника float centerX = 540; // Координаты центра треугольника на экране float centerY = 960; // Вычисляем экранные координаты всех вершин до поворота // l1, l2, l3 - это расстояние от центра треугольника до вершины // это расстояние вычисляю по формуле √ ((X2-X1)²+(Y2-Y1)²) float x1 = centerX; float y1 = centerY - height / 2; float l1 = (float) Math.sqrt(Math.pow(centerX - x1, 2) + Math.pow(centerY - y1, 2)); float x2 = centerX + width / 2; float y2 = centerY + height / 2; float l2 = (float) Math.sqrt(Math.pow(centerX - x2, 2) + Math.pow(centerY - y2, 2)); float x3 = centerX - width / 2; float y3 = y2; float l3 = l2; // Вычисляем координаты вершин с учетом поворота треугольника float alpha1 = (float) (Math.atan(y1 / x1) - angle); x1 = (float) (centerX + l1 * Math.cos(alpha1)); y1 = (float) (centerY + l1 * Math.sin(alpha1)); float alpha2 = (float) (Math.atan(y2 / x2) - angle); x2 = (float) (centerX + l2 * Math.cos(alpha2)); y2 = (float) (centerY + l2 * Math.sin(alpha2)); float alpha3 = (float) (Math.atan(y3 / x3) - angle); x3 = (float) (centerX + l3 * Math.cos(alpha3)); y3 = (float) (centerY + l3 * Math.sin(alpha3)); Код сделал развернутым, чтобы было понятнее, в релизе оптимизирую. Проблема в том, что координаты после поворота вычисляются неверно. Что я делаю не так? Как вычислить новые координаты после поворота треугольника?
Ответы
Ответ 1
Поворот вокруг начальной точки на угол A, описываемый формулой: Xn = Xc * cos(A) - Yc * sin(A) Yn = Xc * sin(A) + Yc * cos(A) где Xc, Yc - координаты относительно центра поворота; Xn, Yn - новые координаты. Все что остается перейти к новой системе координат с нулевой точкой в центре треугольника выполнить поворот и потом вернуться к старой системе координат. Переход к новой системе координат выполняет по формуле: Xn = X - Ox Yn = Y - Oy Т.е. для Вашего случая получаем для каждой точки нужно сделать преобразования: x1 = (x1 - centerX) * cos(angle) - (y1 - centerY) * sin(angle) + centerX; y1 = (x1 - centerX) * sin(angle) + (y1 - centerY) * cos(angle) + centerY; Для больших подробностей откуда такие формулы и т.д. погуглите тему аффинные преобразования.Ответ 2
Вы неверно вычисляете координаты поворота. Посмотрите на формулу (19) поворота осей здесь Ну и кроме того как верно сказал @Nofate ♦ - у вас неверно заданы углы. Надо задавать в радианах: angle*Math.PI/180Ответ 3
Вы учитываете, что тригонометрические функции в java.lang.Math оперируют радианами, а не градусами? Чтобы не мучиться - задавайте исходные координаты относительно нуля. Затем поворачивайте: xNew = x*cos(angle) - y*sin(angle) yNew = x*sin(angle) + x*cos(angle) И потом позиционируйте относительно центра экрана.
Комментариев нет:
Отправить комментарий