Visualization of "Mirrors"

Visualization of “Mirrors”

Last week, we came up with the idea of creating a set of mirrors that react to a guest’s presence by turning away from them so that they are never able to see themselves in the mirror. In order to better explain the concept, we decided to make a Unity-based visualization. The concept is simple enough, and I was able to whip up a visualization pretty quickly.

But as the idea grew, we decided that it might be interesting to have the mirrors do more than simply face away from a single guest. Our first idea was to have the mirror face away from as many guests as possible (limited primarily by the Kinect’s skeleton-tracking limits). This turned out to be a much more interesting math problem than I initially thought.

In this scenario, the mirrors each have to be constantly aware of all the “open angles,” defined as angles at which nobody looking at the mirrors can see their reflections. In the original visualization, I simply had the mirror turn in a random direction until it found an open angle; in this scenario, however, choosing a random direction and turning until it finds an acceptable angle would neither be efficient nor desirable behavior.

Using the Kinect’s depth-tracking and skeleton-tracking abilities, I can find the 3D position of a given guest’s head. I assume a “tolerance” (“intolerance” might have been a better name) of 20 degrees (probably overkill), meaning that if the angle of incidence of the guest’s reflection is less than 20 degrees, the guest can see himself. This means that every guest imposes a 40 degree “dead zone” on the mirror. The mirror’s maximum/minimum rotation are +/- 55 degrees from its resting position (0 degrees, pointing straight forward).

My goal was to use the positional information of each guest to calculate the set(s) of open angles within its 110 degree range, then have the mirror move towards one of those sets.

Conceptually, this problem is actually pretty easy. Drawing a number line and blocking off certain regions on the line is sufficient in conceptualizing the process. The challenge came in translating that into code.

One of the simplest ways to define a range of numbers is the bracket/parentheses system, in which bracketed limits are inclusive, and parenthesized limits are exclusive. For example, [0, 20] means “zero to twenty, inclusive”; [0, 20) means “zero to twenty, including zero and excluding twenty”; and (0, 20) means “zero to twenty, exclusive”; etc. It’s easy to use this system to define the set(s) of open angles. For instance, if a guest is standing directly in front of a mirror, the blocked off angles are (-20, 20), and the open angles are { [-55, -20], [20, 55] }. So how do I define this in code?

I decided that the easiest way to represent an ordered series of ranges was to use a sorted list. What’s nice about these lists is that they’re ordered (like a number line), and they hold key-value pairs, which I could easily interpret as lower and upper limits, respectively.

As I said earlier, each person in front of the mirror defines a set of blocked off angles; this set has a lower and upper limit. So for each person in front of the mirror, I generate a key-value pair that represents this lower and upper limit. Then, I simply find the “inverse” of this set of blocked angles to find the set of open angles.

Voila!