# Getting the position of a directional light w.r.t. a moving object.

I have a forward vector of my object, which is a bike, and its position, and I have a directional light direction.

I would like to know where the light is with regards to the bike position/orientation, whether is it in front, on the right-hand side or on the left-hand side. The light will not move but the bike will.

Here is the code I have so far but it's not working as I expect:

Vector3 lightDirection = mDirectionaLightTransform.transform.position - Source.transform.position;
Vector3 normalizedLightDir = lightDirection.normalized;
Vector3 reflectedForward = Vector3.Reflect(normalizedLightDir, Vector3.forward);


• So to clear it up: you want to know what part of your bike is facing the light? Is your light directional? Please update your question to make it a bit more clear. – Vaillancourt Mar 4 '14 at 14:29
• @AlexandreVaillancourt yes the light is directional, and what you described is exactly what I want to do. – Ahmed Saleh Mar 4 '14 at 15:12

Please note that I don't have unity, but my example is in c# so you'll be able to follow along.

First, since your question concerns a bike (assuming it'll always be on the ground), I've taken the liberty to 'flatten' the question and use only the x and y attributes of the used directions as in this context the z is irrelevant.

The way I'd do it:

1. Compute the angle between the bike and a reference vector, in this case (1.0, 0.0) because we'll use atan2 and things get computed w.r.t that vector in atan2.
2. Rotate the light source vector (invert the light direction to get the source) by the angle computed in 1.
3. Compute the angle of the rotated source vector. This way you get the angle of the source w.r.t. the front of the bike.
4. With the last angle computed, determine where the light is w.r.t. the bike.

Now what is considered "in front" or "on the right side" is quite vague, so you'll have to set angle ranges.

Here is a code sample that illustrate the process.

struct Vec2
{
public Vec2(double aX = 0.0, double aY = 0.0) { x = aX; y = aY; }
public double x;
public double y;
}
static void Main(string[] args)
{
double angle;

angle = getAngle(new Vec2(1.0, 0.0), new Vec2(-1.0, 0.0));
System.Console.WriteLine(String.Format("Front? {0} {1}", angle, getDirection(angle)));
angle = getAngle(new Vec2(1.0, 0.0), new Vec2(1.0, 0.0));
System.Console.WriteLine(String.Format("rear? {0} {1}", angle, getDirection(angle)));
angle = getAngle(new Vec2(1.0, 0.0), new Vec2( 0.0,  1.0));
System.Console.WriteLine(String.Format("right? {0} {1}", angle, getDirection(angle)));
angle = getAngle(new Vec2(1.0, 0.0), new Vec2( 0.0, -1.0));
System.Console.WriteLine(String.Format("left? {0} {1}", angle, getDirection(angle)));

angle = getAngle(new Vec2(0.0, 1.0), new Vec2(0.0, -1.0));
System.Console.WriteLine(String.Format("Front? {0} {1}", angle, getDirection(angle)));
angle = getAngle(new Vec2(0.0, 1.0), new Vec2(0.0, 1.0));
System.Console.WriteLine(String.Format("rear? {0} {1}", angle, getDirection(angle)));
angle = getAngle(new Vec2(0.0, 1.0), new Vec2(-1.0, 0.0));
System.Console.WriteLine(String.Format("right? {0} {1}", angle, getDirection(angle)));
angle = getAngle(new Vec2(0.0, 1.0), new Vec2(1.0, 0.0));
System.Console.WriteLine(String.Format("left? {0} {1}", angle, getDirection(angle)));

}

static double getAngle(Vec2 aBikeForward, Vec2 aLight)
{
// invert the light because we want to have a source vector
Vec2 invertedLightVec = new Vec2(-aLight.x, -aLight.y);

// have both vector in the frame of the bike where it's front is pointing at (1, 0)

// get the angle of the bike with our reference (1,0); invert the angle
// because we'll use it to transform the inverted light vector.
double angleBike = -System.Math.Atan2(aBikeForward.y, aBikeForward.x);

// rotate the light by this angle
Vec2 rotatedLight = new Vec2(
invertedLightVec.x * System.Math.Cos(angleBike) - invertedLightVec.y * System.Math.Sin(angleBike)
, invertedLightVec.x * System.Math.Sin(angleBike) + invertedLightVec.y * System.Math.Cos(angleBike) );

// compute the angle of the rotated vector
return System.Math.Atan2(rotatedLight.y, rotatedLight.x);
}

static String getDirection(double aAngle)
{
{
return "front";
}