web-dev-qa-db-ja.com

別のポイントを中心としたポイントの回転(2D)

私はカードがファンアウトするカードゲームを作ろうとしています。今すぐ機能を持っているAllegro APIを使用してそれを表示するには:

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

これにより、ファン効果を簡単に作成できます。問題は、どのカードがマウスの下にあるかを知ることです。これを行うには、ポリゴンの衝突テストを行うことを考えました。多角形を構成するためにカード上の4つのポイントをどのように回転させるかわからないだけです。基本的に、Allegroと同じ操作を行う必要があります。

たとえば、カードの4つのポイントは次のとおりです。

card.x

card.y

card.x + card.width

card.y + card.height

次のような関数が必要です。

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

ありがとう

118
jmasterx

ああ、それは簡単です。最初にピボットポイント(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;
}
292

ポイント(px, py)をポイント(ox, oy)の周りに角度thetaだけ回転すると、次のようになります。

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

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

これは、2Dでポイントを回転させる簡単な方法です。

64
six face

画面上の座標系は左利きです。つまり、x座標は左から右に増加し、y座標は上から下へ。原点、O(0、0)は画面の左上隅にあります。

enter image description here

時計回り回転原点の周り座標(x、y)を持つ点の次の式で与えられます:

enter image description here

ここで、(x '、y')は、回転後のポイントの座標と角度theta、回転角度(ラジアン単位である必要があります。つまり、PI/180を掛けます)。

原点O(0,0)とは異なる点を中心に回転を実行するには、点A(a、b)(ピボット点)を使用します。最初に、ピボットポイントの座標(x-a、y-b)を差し引くことにより、回転するポイント、つまり(x、y)を原点に戻します。次に、回転を実行して新しい座標(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);
}
44
Ziezi
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;
21