#include #include struct vector_s; typedef struct vector_s vector; // A vector holds x, y, and z positions. struct vector_s { float x, y, z; }; // Computes the magnitude of the given vector. float vmag(vector v) { return sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); } // Computes the dot product of vectors v1 and v2. float vdot(vector v1, vector v2) { return ( (v1.x * v2.x) + (v1.y * v2.y) + (v1.z * v2.z) ); } // Computes the magnitude of the projection of vector 'proj' onto vector 'onto'. float vprojection(vector proj, vector onto) { return vdot(proj, onto) / vmag(onto); } // Take a vector and return a new vector scaled by a constant factor. vector vscale(vector src, float scale) { vector result = { .x = 0, .y = 0, .z = 0 }; result.x = src.x * scale; result.y = src.y * scale; result.z = src.z * scale; return result; } // Take a vector and edit it so that its length is 1. void vnorm(vector v) { // This is wrong!!! float m = vmag(v); m += (m == 0); v.x /= m; v.y /= m; v.z /= m; } // Take a vector and edit it so that its length is 1. void vnorm_alt(vector *v) { // This works! float m = vmag(*v); m += (m == 0); v->x /= m; v->y /= m; v->z /= m; } // Test these methods int main(int argc, char **argv) { vector v1 = { .x = 2, .y = 0, .z = 0 }; vector v2 = { .x = 1, .y = 1, .z = 0 }; fprintf(stdout, "V1: %.3f, %.3f, %.3f\n", v1.x, v1.y, v1.z); fprintf(stdout, "V2: %.3f, %.3f, %.3f\n\n", v2.x, v2.y, v2.z); fprintf(stdout, "V1 mag: %.3f\n", vmag(v1)); fprintf(stdout, "V2 mag: %.3f\n\n", vmag(v2)); fprintf(stdout, "V1 dot V2: %.3f\n", vdot(v1, v2)); fprintf(stdout, "V2 proj V1: %.3f\n\n", vprojection(v2, v1)); // Scale by 1/2 so it should be [1, 0, 0] vector vscaled = vscale(v1, 0.5); fprintf(stdout, "Vscaled: %.3f, %.3f, %.3f\n", vscaled.x, vscaled.y, vscaled.z); fprintf(stdout, "Vscaled mag: %.3f\n\n", vmag(vscaled)); // Now normalize v2 vnorm(v2); fprintf(stdout, "V2 normalized? %.3f\n", vmag(v2)); fprintf(stdout, "V2: %.3f, %.3f, %.3f\n\n", v2.x, v2.y, v2.z); // Now really normalize v2 vnorm_alt(&v2); fprintf(stdout, "V2 normalized! %.3f\n", vmag(v2)); fprintf(stdout, "V2: %.3f, %.3f, %.3f\n\n", v2.x, v2.y, v2.z); }