Icon Rotation via Double Reflection

This is a demonstration how any rotation of a vector s can be achieved by two successive reflections.

A reflection of vector s at vector u is achieved by first projecting s onto u and then adding the difference betwen s and the projection.

A reflection of vector s at vector u followed by a reflection at vector v results in a rotation of s in the plane spanned by vectors u and v.

The angle of the rotation is twice as large as the angle between vector u and vector v.

In general to construct a rotation of angle α you just need to construct two vectors that enclose an angle α / 2 and then use them as reflectors for the subject vector.

The pair of vector u and v is called a rotor.

Notice that only the relative orientation between u and v affect the rotation result. Try drag the arc segment called rotor below to change the direction of both reflectors at once.

Options
The Subject together with the pair (First, Second) of reflection vectors of the rotor.
FFXYSubjectSubjectFirst ReflectorFirst ReflectorSecond ReflectorSecond Reflectorrotor
The Subject is decomposed into the component Projected onto First reflector and the orthogonal component. The Reflected vector is recomposed from those components.
FFFFXYSubjectSubjectFirst ReflectorFirst ReflectorProjectedProjectedReflectedReflected
The First reflection is then reflected again. This time it is Projected onto the Second Reflector. The result is the Rotated vector.
FFFFXYSubjectSubjectSecond ReflectorSecond ReflectorProjectedProjectedRotatedRotatedFirst ReflectionFirst Reflection
Drawing the angles between the interim results shows that the angle between Subject and Rotated is the sum of two angles. The one angle is twice the difference between Subject and First Reflector. The second angle is twice the difference between the First Reflection and the Rotated result.
XYFFFFFFSecond ReflectorSecond ReflectorSubjectSubjectFirst ReflectorFirst ReflectorFirst ReflectionFirst ReflectionRotatedRotated

Take a look at the implementation below. No trigonometric use of sin or cos is needed to perform the rotations.

The construction of any transformation by only composing reflections sits at the core of Geometric Algebra.

// dot ~ similarity in direction
const dot = (a, b) => a.x * b.x + a.y * b.y
// det ~ deviation in direction
const det = (u, v) =>  u.x * v.y - u.y * v.x

const len2 = (v) => dot(v,v)
const len = (v) => Math.sqrt(len2(v))

const scale = (s,v) => ({x: s * v.x, y: s * v.y})
const norm = (v) => scale(1 / len(v), v)

const add = (u, v) => ({x: u.x + v.x, y: u.y + v.y})
const subtract = (u, v) => add(u, scale(-1, v))

const project = (t, s) => scale(dot(t, s) / len2(s), s)

const reflect = (r,s) => {
  const projected = project(s, r);
  const reflected = subtract(scale(2, projected), s);
  return reflected;
}

const rotate =
  (a, b, s) => reflect(b, reflect(a, s))

const rotateHalf =
  (a, b, s) => rotate(scale(0.5, add(a, b)), b, s)
    

3 Dimensions

The same approch also works for 3 dimensions and higher dimensions.

Below you can see the subject vector rotated in the plane spanned by the first and second reflector.

The reflection at the first reflector mirrors the subject onto the first reflection on the opposite side of the plane. The following reflection at the second reflector brings the vector back to the original side of the plane. So the orientation between the subject and the rotation plane is restored.

During this zic-zac motion across the plane the vector still rotates along the plane in the except same ways as in the 2d case above.

Circular Reflections

XY