zaccaro zaccaro - 1 year ago 105
C++ Question

Analytic method for calculate a mirror angle

I have in a 3D space a fixed light ray

and a mirror
that can rotate about the fixed point
, this point is not on the same plane of the mirror, in other words the mirror plane is tangent to a sphere centered in
with a fixed radius
. With that configuration I want to find an equation that receives point
as parameter and results with the rotation of the mirror in a 3D space.

We can consider that the mirror plane has no borders (infinite plane) and it's rotation have no limits. Also, the mirror reflects only on the opposite side of its rotation point.

In the picture are two cases with different input point
, with their respective solution angles
. The pictures are in 2D to simplify the drawings, the real case is in 3D.

At the moment I am calculating the intersection with the mirror plane in a random rotation, then calculate the ray reflection and see how far is from the point (P) I want to reach. Finally iterate with some condition changing the rotation until it match.

Obviously it's an overkill, but I can't figure it out how to code it in an analytic way.

Any thoughts?

Note: I have noticed that if the mirror rotates about a point (Mrot) contained in it's plane and the ray light is reaching that point (Mrot) I can easily calculate the the mirror angle, but unfortunately is not my case.

Answer Source

First note that there is only one parameter here, namely the distance t along the ray at which it hits the mirror.

For any test value of t, compute in order

  1. The point at which reflection occurs.
  2. The vectors of the incident and reflected rays.
  3. The normal vector of the mirror, which is found by taking the mean of the normalized incident and reflected vectors. Together with 1, you now know the plane of the mirror.
  4. The distance d of the mirror to the rotation point.

The problem is now to choose t to make d take the desired value. This boils down to an octic polynomial in t, so there is no analytic formula[1] and the only solution is to iterate.[2]

Here's a code sample:

vec3 r;   // Ray start position
vec3 v;   // Ray direction
vec3 p;   // Target point
vec3 m;   // Mirror rotation point

double calc_d_from_t(double t)
    vec3 reflection_point = r + t * v;
    vec3 incident         = normalize(-v);
    vec3 reflected        = normalize(p - reflection_point);
    vec3 mirror_normal    = normalize(incident + reflected);
    return dot(reflection_point - m, mirror_normal);

Now pass calc_d_from_t(t) = d to your favourite root finder, ensuring to find the root with t > 0. Any half-decent root finder (e.g. Newton-Raphson) should be much faster than your current method.

[1] I.e. a formula involving arithmetic operations, nth roots and the coefficients.
[2] Unless the octic factorises identically, potentially reducing the problem to a quartic.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download