I draw an isosceles triangle in the middle of the screen on the 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 incorrectly. What am I doing wrong? How to calculate the new coordinates after turning the triangle?

  • Isn't it easier to turn the canvas? - Helisia

3 answers 3

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

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

where Xc, Yc - coordinates relative to the center of rotation; Xn, Yn - new coordinates.

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

 Xn = X - Ox Yn = Y - Oy 

Those. for your case we get for each point you need to do the conversion:

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

For more details, where are such formulas, etc. google topic affine transformations.

    You incorrectly calculate the coordinates of the rotation. Look at the formula (19) for turning the axles here.

    Well, and besides, rightly said @Nofate ♦ - your corners are incorrectly set. You must specify in radians: angle*Math.PI/180

    • one
      The vehicle first calculates the coordinates by positioning a triangle on the screen, then trying to rotate it relative to the center of the triangle, rather than the origin. So a simple rotation matrix with this order of calculation, of course, will not work. - Nofate
    • @Nofate ♦ Well, you should be ashamed of yourself: these are 2 elementary affine transformations, first a shift, then a turn ... - Barmaley
    • > this is the same 2 elementary affine transformations @Barmaley, So I also interpret that in my answer) My comment was more about the fact that the formula cannot be applied as is, as they often like to refer to answers. - Nofate

    Do you consider that trigonometric functions in java.lang.Math operate with radians, not degrees?

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

    Then turn:

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

    And then position relative to the center of the screen.