Angles

So your trig library wants radians, but your designers are working in degrees. And what units is this number that our stupid middleware returned to us in? Hey who wrote the UI renderer? He doesn’t work here any more? Do you know what units these angles are supposed to be in? It’s acting kind of weird. Oh it depends?!

I’ve found the easiest solution to tracking the units of angular measurements is to just lay down the law and say that everything’s going to be done internally in radians, with conversions to degrees and back done only on the human-readable side of things. The problem is enforcement (even in a project of one – it’s amazing what corners you’ll cut at 4AM, only to curse yourself a month later when you’re forced to stay up till 5AM fixing the bug your laziness created). Luckily, the compiler can help.

struct angle
{
	float rad_val;
 
	inline float rads( void ) const { return rad_val; }
	inline float degs( void ) const
	{
		return rad_val * (180.0F / 3.14159265358979323846F);
	}
 
	// overload the relevant operators
};
 
inline angle rads( float rad_val )
{
	angle ret = { rad_val };
	return ret;
}
 
inline angle degs( float deg_val )
{
	angle ret = { deg_val * (3.14159265358979323846F / 180.0F) };
	return ret;
}
 
inline float sin( angle a ) { return sinf( a.rad_val ); }
//etc

And there it is. Just use the angle type to store angular measurements and the compiler will force you to explicitly (and clearly) deal with the units at all the points between your code and the rest of the project (external files, middleware, designers, etc). If a value is coming in, you look at its units and call the matching global function (degs or rads). If you need to pass the value along, you call the appropriate member function (or go straight to rad_value).

This type isn’t there to hide what the data is or how its being stored. It’s just there to make people think and do things cleanly up front.

Leave a Reply

Your email address will not be published. Required fields are marked *