← Back to index

Reflect a line off another line

A ray fired from a fixed origin toward the mouse. The mirror line is placed on the right with a random orientation. At the hit point the surface normal is perpendicular to the line, and the reflection is the same d − 2(d·n)n as for the circle.

See also: Reflect a line off a circle — same reflection formula, different surface; Line-segment intersection — same ray/segment math.

Pseudocode

// 1. Ray-segment intersection
//    ray:     P + t * D,        t >= 0
//    segment: A + u * S,        S = B - A,    u in [0, 1]
denom = D.x * S.y - D.y * S.x
if (denom == 0) return null            // parallel
t = ((A.x - P.x) * S.y - (A.y - P.y) * S.x) / denom
u = ((A.x - P.x) * D.y - (A.y - P.y) * D.x) / denom
if (t < 0 || u < 0 || u > 1) return null
hit = P + D * t

// 2. Reflect direction about the line's normal
tangent = normalize(S)
n = (-tangent.y, tangent.x)      // perpendicular
reflected = D - n * (2 * (D . n))

Source

const ox = 20, oy = 150            // ray origin

const dx = mouseX - ox
const dy = mouseY - oy

// (ax, ay) -> (bx, by) is the mirror line, placed at a random angle on the right
const sx = bx - ax
const sy = by - ay
const denom = dx * sy - dy * sx
if (denom !== 0) {
    const t = ((ax - ox) * sy - (ay - oy) * sx) / denom
    const u = ((ax - ox) * dy - (ay - oy) * dx) / denom
    if (t > 0 && u >= 0 && u <= 1) {
        const hx = ox + dx * t
        const hy = oy + dy * t

        // perpendicular to the line, normalised
        const lx = bx - ax, ly = by - ay
        const llen = Math.sqrt(lx * lx + ly * ly)
        const nx = -ly / llen
        const ny =  lx / llen

        const dDotN = dx * nx + dy * ny
        const rdx = dx - 2 * dDotN * nx
        const rdy = dy - 2 * dDotN * ny
    }
}