Поворот точки вокруг другой точки (2D) - PullRequest
116 голосов
/ 14 февраля 2010

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

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 ]

289 голосов
/ 14 февраля 2010

О, это просто ... сначала вычтите опорную точку (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;
}
64 голосов
/ 27 февраля 2013

Если повернуть точку (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.

44 голосов
/ 03 сентября 2015

Система координат на экране левосторонняя, то есть координата x увеличивается слева направо, а координата y увеличивается сверху вниз. Начало координат O (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 - b). Затем мы выполняем вращение и получаем новые координаты (x ', y') и, наконец, переводим точку обратно, добавляя координаты точки поворота к новым координатам (x '+ a, y' + b).

В соответствии с приведенным выше описанием:

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

Использование прототипа вашей функции: (x, y) -> (p.x, p.y); (a, b) -> (cx, cy); тета -> угол:

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);
}
21 голосов
/ 08 августа 2014
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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...