Rotation d'un point autour d'un autre point (2D)

J'essaie de faire un jeu de cartes où les cartes se fanent. En ce moment pour l'afficher Im en utilisant L'API Allegro qui a une fonction:

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

Donc, avec cela, je peux faire mon effet de ventilateur facilement. Le problème est alors de savoir quelle carte est sous la souris. Pour ce faire, j'ai pensé à faire un polygone d'essai de choc. Je ne suis pas sûr de savoir comment faire pivoter les 4 points sur la carte pour constituer le polygone. J'ai essentiellement besoin de faire la même opération que Allegro.

Par exemple, les 4 points de la carte sont:

card.x

card.y

card.x + card.width

card.y + card.height

J'aurais besoin d'une fonction comme:

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

Merci

101
demandé sur dirkgently 2010-02-14 02:08:02

4 réponses

Oh, c'est facile.. soustrayez d'abord le point de pivot (cx,cy), puis faites-le pivoter, puis ajoutez à nouveau le point.

Non testé:

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;
}
250
répondu Nils Pipenbrinck 2016-03-03 21:10:35

Si vous tournez point (px, py) autour du point (ox, oy) par l'angle thêta vous obtiendrez:

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

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

C'est un moyen facile de faire pivoter un point en 2D.

58
répondu six face 2013-09-11 09:52:31

Le système de coordonnées à l'écran est gaucher, c'est-à-dire que la coordonnée x augmente de gauche à droite et la coordonnée y augmente de haut en bas. L'origine O(0, 0) est dans le coin supérieur gauche de l'écran.

entrez la description de l'image ici

Un dans le sens des aiguilles rotation autour de l'origine d'un point de coordonnées (x, y) est donnée par les équations suivantes:

entrez la description de l'image ici

Où (x', y') sont les coordonnées de le point après rotation et l'angle thêta, l'angle de rotation (doit être en radians, c'est-à-dire multiplié par: PI / 180).

Pour effectuer une rotation autour d'un point différent de L'origine O (0,0), disons point A(A, B) (point de pivot). Tout d'abord, nous traduisons le point à faire pivoter, c'est - à - dire (x, y) à l'origine, en soustrayant les coordonnées du point de pivot, (x-a, Y-b). Ensuite, nous effectuons la rotation et obtenons les nouvelles coordonnées (x', y') et finalement nous traduisons le point en arrière, par ajout des coordonnées du point pivot aux nouvelles coordonnées (x '+ a, y ' + b).

Suivant la description ci-dessus:

Un 2D dans le sens des aiguilles d'une montre degrés thêta rotation du point (x, Y) autour du point (a, B) est:

En utilisant votre prototype de fonction: (x, y) -> (p. x, P. y); (a, b) -> (cx, cy); THETA -> angle:

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);
}
31
répondu Ziezi 2016-09-08 19:53:53
float s = sin(angle); // angle is in radians
float c = cos(angle); // angle is in radians

Pour rotation dans le sens horaire:

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

Pour une rotation dans le sens antihoraire:

float xnew = p.x * c - p.y * s;
float ynew = p.x * s + p.y * c;
17
répondu vinay kumar sahu 2017-11-09 02:38:18