C++で点を別の点を中心として回転させる方法
原点を中心とした点の回転
点Xを原点を中心として角度θだけ反時計回りに回転させるには、以下の式を使用します。
原点を中心にθだけ反時計回りにXを回転する式: X * polar(1.0, θ)
ここで使われている polar 関数は、<complex> ヘッダーファイルで定義されている複素数用の関数で、大きさ(絶対値)と位相角から複素数を生成するために使用されます。polar(mag, angle) を呼び出すと、対応する複素数が返されます。複素数を平面上の点として扱うことで、回転のような幾何学的な操作を簡潔に記述できるのがポイントです。
点Yを中心とした点Xの回転
ある点を別の点を中心に回転させたい場合は、平行移動(トランスレーション)という考え方を利用します。平行移動とは、すべての座標が特定の方向へ一斉に移動する変換のことです。
XをYを中心に回転させる手順
平行移動: すべての点からYを引き算することで、Yを新しい原点に移動させます。これにより、Xは X-Y となります。
回転: 上記の公式を使って、新しい原点を中心に (X-Y) を回転させます。つまり (X-Y) * polar(1.0, θ) を計算します。
逆平行移動: 最後に、すべての点にYを足し戻すことで、座標系をもとの位置に戻します。
XをYを中心に回転させた結果の点: (X-Y) * polar(1.0, θ) + Y
この3つのステップを組み合わせることで、任意の点を中心とした回転を簡単に実装できます。それでは、実際のコードを見てみましょう。
コード例
#include <iostream>
#include <complex>
using namespace std;
typedef complex<double> point;
#define x real()
#define y imag()
int main(){
// 点Pを点Qを中心に回転させる
point X(5.0, 3.0);
point Y(2.0, 4.0);
// 回転角は90度
double theta = 3.14/2;
point Xnew=(X-Y) * polar(1.0, theta) + Y;
cout << "rotating X 90 degrees anti-clockwise about Y becomes:";
cout << "(" << Xnew.x << ", " << Xnew.y << ")" << endl;
return 0;
}
実行結果
rotating X 90 degrees anti-clockwise about Y becomes:(3.00239, 6.9992)
このように、C++では複素数ライブラリを活用することで、回転行列を自分で実装することなく、わずか数行のコードで点の回転処理を実現できます。ゲーム開発やグラフィックスプログラミングなど、幾何学的な計算が必要な場面で非常に役立つテクニックなので、ぜひ覚えておきましょう。
-
C++で2次元平面上の点の鏡像(鏡映点)を求める方法
この記事では、2次元平面上の点Pと、直線の方程式 ax + by + c = 0 の係数 a・b・c が与えられたときに、この直線を鏡とした点Pの鏡像(鏡映点)をC++で求める方法を解説します。 問題を理解するための例 入力 P = (2, 1), a = 1, b = -1, c = 0 出力 (1, 2) 説明 与えられる直線は y = x です。この直線を鏡として点 (2, 1) を反射すると、x座標とy座標が入れ替わった位置 (1, 2) が鏡像となります。平面の様子は下図の通りです。 解法アプローチ この問題を解くには、鏡像となる点P(x, y) の座標を求める必要があり
-
C++で二分木が別の二分木の部分木(サブツリー)であるかを判定する方法
はじめに二つの二分木が与えられたとき、小さい方の木がもう一方の二分木の部分木(サブツリー)として含まれているかどうかを判定する方法を解説します。例として、以下のような二つの木を考えてみましょう。この場合、2番目の木は1番目の木の部分木となっています。判定アルゴリズムの考え方この性質を確認するためには、大きい方の木を後順走査(post-order traversal)でたどり、各ノードを根とする部分木が2番目の木と完全に一致するかどうかを順番に調べます。一致する部分木が一つでも見つかれば、2番目の木は1番目の木の部分木であると判定できます。判定の流れは以下の通りです。1. 部分木側がNULLであ