reflection across a line

概要

点 \(\mathbf{p_0} = (x_0, y_0)\) と 点 \(\mathbf{p_1} = (x_1, y_1)\) を通る直線 を対称軸として ある点 \(\mathbf{q_0} = (a_0, b_0)\) の線対称とする点 \(\mathbf{q_1}\) を求める。

まず \(\mathbf{q_0}\) の直線への写像 を \(\mathbf{q_a}\) とすると、

  • \(\displaystyle \mathbf{q_a} = \mathbf{p_0} + \frac{(\mathbf{q_0} - \mathbf{p_0}) \cdot (\mathbf{p_1} - \mathbf{p_0})}{\| \mathbf{p_1} - \mathbf{p_0} \| ^2} (\mathbf{p_1} -\mathbf{p_0})\)

で計算できる。

そして \(\mathbf{q_0}\) の線対称は \(\mathbf{q_1} = \mathbf{q_0} + 2(\mathbf{q_a} - \mathbf{q_0})\) で計算できる。

実装

def dot3(a, b, c):
    x0, y0 = a; x1, y1 = b; x2, y2 = c
    return (x1 - x0)*(x2 - x0) + (y1 - y0)*(y2 - y0)
def dist2(a, b):
    x0, y0 = a; x1, y1 = b
    return (x0 - x1)**2 + (y0 - y1)**2
def reflection(line, point):
    p0, p1 = line
    dv = dot3(p0, p1, point)
    dd = dist2(p0, p1)

    x0, y0 = p0; x1, y1 = p1
    xp, yp = point

    xm = x0 + dv * (x1 - x0) / dd
    ym = y0 + dv * (y1 - y0) / dd

    return xp + 2*(xm - xp), yp + 2*(ym - yp)

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

Verified

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

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

  • AOJ: "2569: Putter": source (Python3, 0.31sec)

  • AOJ: "1171: Laser Beam Reflections": source (Python3, 3.51sec)

参考


戻る