reflection across a line

概要

点\((x_0, y_0)\) と 点\((x_1, y_1)\) を通る直線 を対称軸として ある点\((p, q)\) の線対称とする点を求める。

ベクトル \((p - x_0, q - y_0)\) と \((x_1 - x_0, y_1 - y_0)\) の なす角を \(\theta\) とする時、

  • \(\displaystyle \left( \begin{array}{c} x_0 \\ y_0 \end{array} \right) + R(2\theta) \left( \begin{array}{c} p - x_0 \\ q - y_0 \end{array} \right)\)

を求める。 (\(R(\theta)\)は\(2 \times 2\)の回転行列)

内積、外積から \(\cos \theta\), \(\sin \theta\) を求めた上で \(\cos 2\theta\), \(\sin 2\theta\) を求め、回転行列を計算する。

実装

def reflection(line, point):
    x0, y0, x1, y1 = line
    p, q = point
    x1 -= x0; y1 -= y0
    p -= x0; q -= y0
    cv = p*x1 + q*y1
    sv = p*y1 - q*x1
    cv2 = cv**2 - sv**2
    sv2 = 2*cv*sv
    dd = (p**2 + q**2)*(x1**2 + y1**2)
    if dd == 0:
        return x0 + p, y0 + q
    return x0 + (cv2 * p - sv2 * q) / dd, y0 + (sv2 * p + cv2 * q) / dd

# example
print(reflection((0, 2, 2, 1), (0, 0)))
# => (1.6, 3.2)

Verified

  • AOJ: "CGL_1_B: Reflection": source (Python3, 0.05sec)

  • AOJ: "2596: Points and Lines": sourcce (Python3, 0.03sec)