web-dev-qa-db-fra.com

Faire pivoter un point sur un autre point (2D)

J'essaie de créer un jeu de cartes où les cartes se déroulent. Maintenant, pour l'afficher, j'utilise 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);

je peux donc facilement créer mon effet de ventilateur. Le problème est alors de savoir quelle carte est sous la souris. Pour ce faire, j'ai pensé à faire un test de collision de polygones. Je ne suis pas sûr de savoir comment faire pivoter les 4 points de la carte pour constituer le polygone. J'ai essentiellement besoin de faire la même opération qu'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

118
jmasterx

Oh, c’est facile… soustrayez d’abord le point de pivot (cx, cy), puis faites-le pivoter, puis rajoutez 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;
}
292
Nils Pipenbrinck

Si vous faites pivoter le point (px, py) Autour du point (ox, oy) Selon 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.

64
six face

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

enter image description here

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

enter image description here

où (x ', y') sont les coordonnées du point après rotation et l'angle thêta, l'angle de rotation (doit être exprimé 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), supposons le point A (a, b) (point pivot). Premièrement, nous traduisons le point à faire pivoter, c'est-à-dire (x, y) en origine, en soustrayant les coordonnées du point de pivotement (x - a, y - b). Ensuite, nous effectuons la rotation et obtenons les nouvelles coordonnées (x ', y') et enfin, nous traduisons le point arrière en ajoutant les coordonnées du point de pivotement aux nouvelles coordonnées (x '+ a, y' + b).

Après la description ci-dessus:

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

Utilisation de votre prototype de fonction: (x, y) -> (p.x, p.y); (a, b) -> (cx, cy); thêta -> 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);
}
44
Ziezi
float s = sin(angle); // angle is in radians
float c = cos(angle); // angle is in radians

Pour une rotation dans le sens des aiguilles d'une montre:

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;
21
vinay kumar sahu