How do I rotate a triangle?

I draw an isosceles triangle in the middle of the screen on Canvas. I draw from the center of the triangle (the intersection of the medians). Accordingly, the screen coordinates of the center of the triangle and the size of the triangle are known. You need to be able to rotate the triangle at an arbitrary (random) angle clockwise. I do this:

// Исходные данные
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));

I made the code deployed to make it clearer, I optimize it in the release.

The problem is that the coordinates after the rotation are calculated incorrect. What am I doing wrong? How do I calculate the new coordinates after turning a triangle?

Author: BArtWell, 2014-06-25

3 answers

Rotate around the starting point by the angle A described by the formula:

Xn = Xc * cos(A) - Yc * sin(A)
Yn = Xc * sin(A) + Yc * cos(A)

Where Xc, Yc are the coordinates relative to the center of rotation; Xn, Yn are the new coordinates.

All that remains is to go to the new coordinate system with the zero point in the center of the triangle, perform a rotation and then return to the old coordinate system. The transition to the new coordinate system is performed by the formula:

Xn = X - Ox
Yn = Y - Oy

That is, for your case, we get for each point we need to do conversions:

x1 = (x1 - centerX) * cos(angle) - (y1 - centerY) * sin(angle) + centerX;
y1 = (x1 - centerX) * sin(angle) + (y1 - centerY) * cos(angle) + centerY;

For more details on where such formulas come from, etc., google the topic affine transformations.

 9
Author: vinnie, 2014-06-25 13:57:17

You are calculating the rotation coordinates incorrectly. Look at the formula (19) for turning the axes here

And besides as I said correctly @Nofate ♦ - your angles are set incorrectly. It should be set in radians: angle*Math.PI/180

 4
Author: Barmaley, 2014-06-25 13:11:51

You take into account that the trigonometric functions in java. lang.Math operates with radians, not degrees?

In order not to suffer - set the original coordinates relative to zero.

Then rotate:

  • xNew = x*cos(angle) - y*sin(angle)
  • yNew = x*sin(angle) + x*cos(angle)

And then position relative to the center of the screen.

 4
Author: Nofate, 2014-06-25 13:12:23