Вращение точки вокруг другой точки (2D)


Я пытаюсь сделать карточную игру, где карты веером. Прямо сейчас, чтобы отобразить его Im с помощью API Allegro, который имеет функцию:

al_draw_rotated_bitmap(OBJECT_TO_ROTATE,CENTER_X,CENTER_Y,X
        ,Y,DEGREES_TO_ROTATE_IN_RADIANS);

Так что с этим я могу сделать мой эффект вентилятора легко. Проблема в том, чтобы знать, какая карта находится под мышью. Для этого я решил сделать тест на столкновение полигонов. Я просто не уверен, как повернуть 4 точки На карте, чтобы составить многоугольник. Мне в основном нужно сделать ту же операцию, что и Аллегро.

например, 4 очки карты:

card.x

card.y

card.x + card.width

card.y + card.height

мне нужна функция типа:

POINT rotate_point(float cx,float cy,float angle,POINT p)
{
}

спасибо

4 101

4 ответа:

О, это легко.. сначала вычтите точку поворота (cx, cy), затем поверните ее, а затем снова добавьте точку.

непроверенные:

POINT rotate_point(float cx,float cy,float angle,POINT p)
{
  float s = sin(angle);
  float c = cos(angle);

  // translate point back to origin:
  p.x -= cx;
  p.y -= cy;

  // rotate point
  float xnew = p.x * c - p.y * s;
  float ynew = p.x * s + p.y * c;

  // translate point back:
  p.x = xnew + cx;
  p.y = ynew + cy;
  return p;
}

если вы вращаете точку (px, py) вокруг точки (ox, oy) по углу тета вы получите:

p'x = cos(theta) * (px-ox) - sin(theta) * (py-oy) + ox

p'y = sin(theta) * (px-ox) + cos(theta) * (py-oy) + oy

это простой способ повернуть точку в 2D.

система координат на экране-левша, т. е. x координата увеличивается слева направо, а y координата возрастает сверху вниз. Происхождении, о(0, 0) находится в верхнем левом углу экрана.

enter image description here

A по часовой стрелке поворот вокруг происхождения точки с координатами (x, y) задается следующим образом уравнения:

enter image description here

где (x', y') - координаты точки после поворота и угол тета, угол поворота (должен быть в радианах, т. е. умножен на: PI / 180).

чтобы выполнить вращение вокруг точки, отличной от начала координат O(0,0), скажем, точка A(a, b) (точка поворота). Сначала мы переводим точку поворота, т. е. (x, y) обратно в начало координат, вычитая координаты точки поворота, (x-a, y - си.) Затем мы выполняем поворот и получаем новые координаты (x', y') и, наконец, мы переводим точку обратно, добавляя координаты точки поворота к новым координатам (x' + a, y' + b).

после приведенного выше описания:

2D по часовой стрелке тэта градусов поворот точки (x, y) вокруг точки (a, b) - это:

используя ваш прототип функции: (Х, Y) -> (стр. X, С. Г); (А, B) -> (СХ, Су); тэта -> угол:

POINT rotate_point(float cx, float cy, float angle, POINT p){

     return POINT(cos(angle) * (p.x - cx) - sin(angle) * (p.y - cy) + cx,
                  sin(angle) * (p.x - cx) + cos(angle) * (p.y - cy) + cy);
}
float s = sin(angle); // angle is in radians
float c = cos(angle); // angle is in radians

для вращения по часовой стрелке :

float xnew = p.x * c + p.y * s;
float ynew = -p.x * s + p.y * c;

для вращения против часовой стрелки:

float xnew = p.x * c - p.y * s;
float ynew = p.x * s + p.y * c;