Search code examples
mathdata-structures3dspace-efficiency

Efficient way to store 3D normal vector using two floats


I need to store 3D normal vectors, that is vectors (x, y, z) such that x^2 + y^2 + z^2 = 1. But due to space constraints I can only use 2 floats to store it. So by storing only x and y, the third component can be computed as sqrt(1 - x^2 - y^2), i.e. one square root, two products and two subtractions.

What would be the most efficient way to store the vectors, so that reading them is as fast as possible, and if possible without bias towards one spatial direction?

Edit

Now using the values (a, b) with a = x - y and b = x + y.


Solution

  • You could satisfy your space constraint by storing the vectors via spherical coordinates. As is well known, each point on the unit sphere, i.e., each unit vector, has at least one pair of spherical coordinates characterizing it.


    Or if you want something convoluted: The complex square function maps the unit disk to a double cover of it. So you could use the left half-disk for the upper half-sphere and the right half-disk for the lower half-sphere.

    SphereFromDisk(a,b)
        a2=a*a; b2=b*b; r2=a2+b2; // assert r2 <= 1
        x = a2 - b2;
        y = 2*a*b
        z = sqrt(1-r2*r2)
        if(a<0 or (a=0 and b<0) z=-z
        return (x,y,z)