Холст HTML5: вычисление точки x, y при повороте

Я разрабатываю приложение Canvas для HTML5, и он включает чтение xml файла, который описывает положение стрелок, референций и других фигур, которые мне нужно рисовать на холсте.

Пример компоновки XML:

<arrow left="10" top="20" width="100" height="200" rotation="-40" background-color="red"/> 
<rect left="10" top="20" width="100" height="200" rotation="300" background-color="red"/> 

Если объект вращается, он включает вычисление положения точки (называемое P новым положением объекта после вращения) при повороте вокруг другой точки (слева, сверху). Я пытаюсь придумать общую функцию/формулу, которую я могу использовать для вычисления этой точки P, но моя математика немного слаба, и я не могу определить, какую формулу дуги/касательной я намерен использовать.

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

enter image description here

В приведенном выше примере: точка (14,446) - левая, верхняя точка и точка (226,496) - это средняя точка объекта, когда НЕ повернуты так, что точка = (левая + ширина /2, верхняя + высота /2) и синяя точка - это средняя точка при повороте. Я знаю, как вычислить длину линии между точками (14,446) и (226,496), но не как вычислить голубую точку x, y - BTW: длина этой линии совпадает с длиной между синей точкой и (14446)

len = sqrt( (496-446)^2 + (226-14)^2 );
    = 227.56;

Ответ 1

Это довольно просто. При вращении вокруг начала координат системы координат угла Тэта (x, y) изменяются как

x' = x * cos(Theta) - y * sin(Theta);
y' = x * sin(Theta) + y * cos(Theta); 

Итак, все, что вам нужно, это перевести точку поворота в одну из точек, которые у вас есть. Давайте напишем его более упрощенным способом: (x1, y1) = (14,446) и (x2, y2) = (226,496). Вы пытаетесь "вращать" (x2, y2) вокруг (x1, y1). Вычислить (dx2, dy2) в новой системе координат с началом в (x1, y1).

(dx2,dy2) = (x2-x1,y2-y1);

Теперь поверните (положительные углы против часовой стрелки):

dx2' = dx2 * cos(165 Degrees) - dy2 * sin(165 Degrees);
dy2' = dx2 * sin(165 Degrees) + dy2 * cos(165 Degrees);

Последний шаг - перевести координаты точки из начала координат в (x1, y1) обратно в исходное (0,0);

x2' = dx2' + x1;
y2' = dy2' + y1;

ps: прочитайте также это:) http://en.wikipedia.org/wiki/Rotation_matrix и не забывайте, что большинство тригонометрических функций в разных языках программирования в основном относятся к радианам.

pps: и я надеюсь, что я вас не испугал - спросите, есть ли у вас какие-либо вопросы.

Ответ 2

Я думаю, что в вашем случае вы должны будете вычислить это положение вращения со следующей системой уравнений:

x = R * Math.cos(angle - angle0);
y = R * Math.sin(angle - angle0);
angle  = deg * Math.PI / 180;
angle0 = Math.atan(y0/x0);

R длина вектора радиуса yor (len в вашем примере).
deg угол в градусах, в которые вы вращаетесь, например, 120 & deg; x и y координаты конечной позиции, которую вы ищете.
angle - фактический угол поворота (в раде, а не в градусах).
angle0 - исходная угловая точка была повернута относительно релятивистской оси X. Нам нужно предварительно вычислить его с помощью Math.atan.

Не тестировались. Так что попробуй. Но идея такая же - использовать тригонометрические функции.