Not using vlen

vlen is the obvious way to measure distances in quake, but most of the time the result isn’t used directly, just compared to another distance. If you only use vlen in an inequality you can skip the function entirely.

The bit of maths you need for this trick is the dot product. The dot product is a function which takes two vectors and outputs a float. For vectors called a and b, the output is

   a_x * b_x + a_y * b_y + a_z * b_z;

We can calculate it in QuakeC in a single operation:

   a * b;

A bit of maths tells us the dot product is always equal to

   vlen(a) * vlen(b) * cos(theta)

where theta is the angle between the vectors a and b.

What interests us today is taking the dot product of a vector with itself, which gives us

   vlen(a) * vlen(a) * cos(0)

Since cos(0) is equal to 1, the dot product a * a is equal to vlen(a) * vlen(a) and we can swap one for the other.

If we started with code like

   if(vlen(a) < 120)
      PopUp(self);

Because we know vlen is never negative, we can safely change it to this:

   if(vlen(a) * vlen(a) < 120 * 120)
      PopUp(self);

To finish this off, we can do this:

   if(a * a < 120 * 120)
      PopUp(self);

I like leaving the constant on the right like that, so it’s easy to read what distance we’re actually comparing to – but does it matter for performance? The answer depends on which compiler you use. The original compilers would compute 120 * 120 each time, current ones will perform the multiplication at compile time, so there’s no impact on performance.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s