FOVE's Eye Tracker returns the gaze direction (both the combined gaze and the individual gaze) as **directional unit vectors**. They are just vectors that point in the given direction of the gaze.

As unit vectors, the magnitude is always one. This is simply a convenience as it will still point in the same direction regardless of the length.

In the HMD coordinate system, which is always used by the FOVE SDK (including C/C++/Python bindings), the gaze vectors always represent the direction of the gaze relative to the users head.

X axis represents the horizontal direction (negative left, positive right).

Y axis represent the vertical direction (negative down, positive up).

Z axis represents the forward direction (negative is behind the users head, positive is in front).

Since the users eyeball cannot rotate backwards (and if it did, we would loose tracking anyway), in practice negative Z values are never used. Also, fully to-the-right for example (1, 0, 0) is not possible. If you ever get such values, it's a bug or a very inaccurate result, and you should let us know.

When tracking is lost we return a data error in the SDK (*Data_Unreliable*), so we recommend you check error codes. Just for consistency, in these cases we set the data value to (0, 0, 1). If, in lieu of checking errors, for example if you're looking at some recorded data stream without errors saves, and you see (0, 0, 1), it generally means that there's an error. The actual likelihood of getting an exactly 100% forward result is low. It's much more likely to see numbers like z=0.9853 from real data.

Please note the FOVE Unity plugin has other coordinate systems which change the reference direction (eg. including the headset rotation or in-engine transform object). These are not discussed in this article, but the principles are the same.

## How can I take the angular difference between two different gazes?

The angle between two vectors is the inverse cosine of the dot product. So, as a simple example:

If initially the eye is looking forward, you will get a value of **V0=**(x=0, y=0, z=1).

Later, let's say the eye looks right, and you get a value of **V1=**(x=0.7, x=0, z=0.7)

**dot =** V0.x * V1.x + V0.y * V1.y + V0.z * V1.z **=** 0 * 0.7 + 0 * 0 + 1 * 0.7** = 0.7**

**angle = **acos(dot) * *radiansToDegrees* = 0.795 * 180 / PI **~= 45 degrees**

## How can I get the X / Y angles?

Since we want 2D angles, we need to discard one axis to get a 2D vector, then take the angle. To take the angle of a 2D vector we can simply use arctangent.

For X axis, discard y, and pass x/z to atan: **xangle** = atan(v.x / v.z) * *radiansToDegreesConstant* = atan(0.7 / 0.7) * 180 / PI** ~= 45 degrees**

For Y axis it is y/z to atan: **yangle** = atan(v.x / v.z) * *radiansToDegreesConstant* = atan(0/ 0.7) * 180 / PI** ~= 0 degrees**

*If your math library has it, prefer atan2 to atan*

## Comments

5 comments

Excelllllllent

But in the data sample of Fove there are two X,Y,Z

One called the position of the ray and other one is the direction of the ray which vector is the best to be used to refer to the pupil position or which you use here !

And what is the fixed origin of the eye or the initial one which the pupil can vary from it ?

I need to calculate each time the two angles of the pupil which you mentiom befor the horizontal one and vertical one , I compare the changes vector to the origin vector or the vector came befor it ?

This article explains the position and the direction: https://support.getfove.com/hc/en-us/articles/900004261163-The-FOVE-Eye-Tracker-Every-Field-Explained

The position you can mostly ignore. The origin is the midpoint between the eyes, and the position is the offset to each eye from there, which is basically a fixed 31.5 millimeters on either side. Since we're talking .3 cm or so, it matters very little when looking a objects that aren't close to the face.

Goood , thanks alot the last question so I can complete my project , I will use GetGazeVector ( ) right , it is the one which return the direction vector not the position vector

Correct, GetGazeVector() is good for your purposes.

Please sign in to leave a comment.