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') の座標を求める必要があります。そこで、線分P-P'が鏡となる直線と交わる点をRとします。
線分P-R-P'は鏡となる直線に垂直であり、その方向は直線の法線ベクトル (a, b) と一致します。点P(x, y) と点R(xm, ym) の位置関係から、鏡像P'は次の等式を満たします。
(x' − x) / a = (y' − y) / b = −2(ax + by + c) / (a² + b²)
この共通の値を t とおくと、鏡像の座標は以下の式で求められます。
x' = x + a × t
y' = y + b × t
つまり、点Pから法線方向へ、直線までの距離の2倍だけ移動した位置が鏡像P'になります。この計算は定数回の演算で済むため、時間計算量は O(1) です。
C++での実装例
#include <iostream>
using namespace std;
// 点(x, y)の直線 ax + by + c = 0 に関する鏡像を求める関数
void findMirrorImage(double a, double b, double c, double x, double y){
// 鏡像への移動量 t を計算
double t = -2 * (a * x + b * y + c) / (a * a + b * b);
// 鏡像の座標を求める
double xm = t * a + x;
double ym = t * b + y;
cout << "(" << xm << "," << ym << ")";
}
int main(){
double a = -1.0;
double b = 1.0;
double c = 0.0;
double x = 1.0;
double y = 0.0;
cout << "Image of point (" << x << ", " << y << ") using mirror (" << a << ")x + (" << b << ")y + (" << c << ") = 0, is :";
findMirrorImage(a, b, c, x, y);
return 0;
}
出力
Image of point (1, 0) using mirror (-1)x + (1)y + (0) = 0, is :(0,1)
実行結果の解説
このプログラムでは、直線 −x + y = 0(すなわち y = x)を鏡として、点 (1, 0) の鏡像を求めています。出力の通り、鏡像は (0, 1) となり、x座標とy座標が入れ替わった位置に正しく映っていることが確認できます。
-
C++で解くミラーリフレクション(鏡面反射)問題のアルゴリズムと実装
ミラーリフレクション問題とは4つの壁すべてに鏡が張られた正方形の部屋を考えてみましょう。南西の角以外の各角には、0、1、2という番号が付けられたレシーバー(受光器)が設置されています。この正方形の部屋の一辺の長さは p であり、南西の角から発射されたレーザー光線は、最初に東側の壁に当たります。その位置は、0番のレシーバーから距離 q の地点です。このとき、光線が最初に到達するレシーバーの番号を求めるのが本問題です。例えば、p = 2、q = 1 の場合を考えてみます。光線は壁で反射を繰り返し、最終的に左側の壁へ戻ってきたときに初めてレシーバー2に到達します。したがって、出力は 2 となります。
-
C++で括弧文字列からイコールポイント(等分点)を見つける方法
この記事では、C++を使って括弧の文字列からイコールポイント(等分点)を求める方法を解説します。 イコールポイントとは? イコールポイントとは、あるインデックス i において、その位置より前にある開き括弧「(」の数と、その位置以降にある閉じ括弧「)」の数が等しくなる地点のことです。 例として、次の括弧文字列を考えてみましょう。 (()))( ()()() )) ) → 元の文字列は (()))(()()()))) この文字列を詳しく観察すると、インデックス0〜9の範囲に含まれる開き括弧は5個、インデックス9〜14の範囲に含まれる閉じ括弧も5個あります。したがって、インデックス9がこの文字列の