If you do a lot of graphics development, you're sure to use lots of vector math. A while ago I wrote some C++ extensions to Apple's GLKit Math utilities, but haven't had a chance to explain why they would be helpful, and how they can improve your graphics code.

So, say you have a simple numerical solver that keeps track of the position of a ball over time written in straight C or Objective-C. You might have some code that looks like this:

###Scalar math

```
float ball_x, ball_y, ball_z;
...
ball*x = ball_x + change_x * dt;
ball*y = ball_y + change_y * dt;
ball_z = ball_z + change_z \* dt;
```

###Structs

That's a tad awkward, so defining a struct to contain x,y,z floats together makes a lot of sense:

```
typedef struct {
float x, y, z;
} vector3;
vector3 ball;
...
ball.x = ball.x + change.x _ dt;
ball.y = ball.y + change.y _ dt;
ball.z = ball.z + change.z * dt;
```

##Functions operating on structs

Well that's kind of better, but I want to do the same operation on every coordinate, and I don't want to keep peppering around these identical bits of code everywhere, so I'll define some convenience functions:

```
typedef struct {
float x,y,z;
} vector3;
vector3 ball;
vector3 mulVectorScalar(vector3 a, float k) {
vector3 r;
r.x = a.x _ k;
r.y = a.y _ k;
r.z = a.z \* k;
return r;
}
vector3 addVector(vector3 a, vector3 b) {
vector3 r;
r.x = a.x + b.x;
r.y = a.y + b.y;
r.z = a.z + b.z;
return r;
}
...
ball = addVector(ball, mulVectorScalar(b, dt))
```

We can even do some optimizations for the processor architecture that we're running on. For instance, ARMv7 (available on recent iOS devices) has a set of extensions called "NEON" that allow operations on multiple data simultaniously at a hardware level.

For iOS 5's new GLKit framework, Apple created a set of functions like our `addVector`

that use NEON vector instructions to accelerate operations on vectors and matrices without having to pepper your own code with ifdefs.

From `<GLKit/GLKVector2.h>`

:

```
static inline GLKVector2 GLKVector2Add(GLKVector2 vectorLeft, GLKVector2 vectorRight)
{
#if defined(ARM_NEON)
float32x2*t v = vadd_f32(*(float32x2*t *)&vectorLeft,
_(float32x2_t _)&vectorRight);
return _(GLKVector2 _)&v;
#else
GLKVector2 v = { vectorLeft.v[0] + vectorRight.v[0],
vectorLeft.v[1] + vectorRight.v[1] };
return v;
#endif
}
```

The problem now is that these function names `addVector`

and `mulVectorScalar`

have taken the place of much more intuitive operators like `+`

and `*`

. Also, if we decide that the ball only needs to be a 2-element vector instead of a 3-element vector, we would need to switch all of the places where we update its position to new functions and new structs.

If we switch over to c++ land, we have a tool (operator overloading) that will let us have something both concise and efficient.

```
#import "GLKMath_cpp.h"
GLKVector2 ball;
...
ball = ball + change \* dt;
```

This is implemented in GLKVector2_cpp.h as follows:

```
#import <GLKit/GLKVector2.h>
...
inline GLKVector2 operator + (const GLKVector2& left, const GLKVector2& right) {
return GLKVector2Add(left, right);
}
inline GLKVector2 operator * (const float& left, const GLKVector2& right) {
return GLKVector2MultiplyScalar(right, left);
}
...
```

So, if you don't mind switching to c++, you can make your vector math a lot clearer to read (and hopefully reduce typos). If you notice anything amiss in with these headers or anything you think should be added, please create an issue or send a pull request on github

Fork on GitHub