/// _ /// __ _____ ___| |_ ___ _ __ /// \ \/ / _ \/ __| __/ _ \| '__| /// > < __/ (__| || (_) | | /// /_/\_\___|\___|\__\___/|_| /// /// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic /// /// xolatile@chud.cyou - xector - Very slow and dumb vector library, mathematical vector, not that C++ cancer by the way... /// /// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU /// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish... /// /// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied /// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License /// for more details, if you dare, it is a lot of text that nobody wants to read... /// Description /// /// Xector (Vector), my small vector library, not to be confused with my older project Xector (Sector) which was for procedurally generating 3D /// models (based on boolean operations on 3D sectors). This library isn't optimized for performance or memory usage, instead it's for my own /// preferred programming style. It's hard to explain linear algebra to people who don't already know it (for me at least), so I won't do that, /// function names should provide you enough information. There'll be simple comments for the sake of consistency with my other libraries. /// /// If you want to use "good" linear algebra library, prefer CGLM over this, and GLM if you're into C++ rather than objectively better language /// called C. Again, reading comments in this file is useless. Include it, set the vectors, do the work. /// 2D vector structure. typedef struct { real x, y; /// Two 32-bit floating point numbers. } vector_2; /// 3D vector structure. typedef struct { real x, y, z; /// Three 32-bit floating point numbers. } vector_3; /// 4D vector structure. typedef struct { real x, y, z, w; /// Why the hell did they choose to start from 'x', and end with 'z', it's so retarded. } vector_4; /// Assign values to 2D, 3D or 4D vector and return address of that vector. static vector_2 * vector_2_assign (vector_2 * destination, real x, real y) { destination->x = x; destination->y = y; return (destination); } static vector_3 * vector_3_assign (vector_3 * destination, real x, real y, real z) { destination->x = x; destination->y = y; destination->z = z; return (destination); } static vector_4 * vector_4_assign (vector_4 * destination, real x, real y, real z, real w) { destination->x = x; destination->y = y; destination->z = z; destination->w = w; return (destination); } /// Nullify values of 2D, 3D or 4D vector and return address of that vector. static vector_2 * vector_2_nullify (vector_2 * destination) { destination->x = destination->y = 0.0f; return (destination); } static vector_3 * vector_3_nullify (vector_3 * destination) { destination->x = destination->y = destination->z = 0.0f; return (destination); } static vector_4 * vector_4_nullify (vector_4 * destination) { destination->x = destination->y = destination->z = destination->w = 0.0f; return (destination); } /// Return length of 2D, 3D or 4D vector. static real vector_2_length (vector_2 * vector) { real x = vector->x; real y = vector->y; return (square_root (x * x + y * y)); } static real vector_3_length (vector_3 * vector) { real x = vector->x; real y = vector->y; real z = vector->z; return (square_root (x * x + y * y + z * z)); } static real vector_4_length (vector_4 * vector) { real x = vector->x; real y = vector->y; real z = vector->z; real w = vector->w; return (square_root (x * x + y * y + z * z + w * w)); } /// Normalize 2D, 3D or 4D vector and return address of that vector. static vector_2 * vector_2_normalize (vector_2 * destination) { real length = vector_2_length (destination); destination->x /= length; destination->y /= length; return (destination); } static vector_3 * vector_3_normalize (vector_3 * destination) { real length = vector_3_length (destination); destination->x /= length; destination->y /= length; destination->z /= length; return (destination); } static vector_4 * vector_4_normalize (vector_4 * destination) { real length = vector_4_length (destination); destination->x /= length; destination->y /= length; destination->z /= length; destination->w /= length; return (destination); } /// Normalize 2D, 3D or 4D source vector into destination vector and return its address. static vector_2 * vector_2_normalize_to (vector_2 * destination, vector_2 * source) { real length = vector_2_length (source); destination->x = source->x / length; destination->y = source->y / length; return (destination); } static vector_3 * vector_3_normalize_to (vector_3 * destination, vector_3 * source) { real length = vector_3_length (source); destination->x = source->x / length; destination->y = source->y / length; destination->z = source->z / length; return (destination); } static vector_4 * vector_4_normalize_to (vector_4 * destination, vector_4 * source) { real length = vector_4_length (source); destination->x = source->x / length; destination->y = source->y / length; destination->z = source->z / length; destination->w = source->w / length; return (destination); } /// Copy 2D, 3D or 4D source vector into destination vector. static vector_2 * vector_2_copy (vector_2 * destination, vector_2 * source) { destination->x = source->x; destination->y = source->y; return (destination); } static vector_3 * vector_3_copy (vector_3 * destination, vector_3 * source) { destination->x = source->x; destination->y = source->y; destination->z = source->z; return (destination); } static vector_4 * vector_4_copy (vector_4 * destination, vector_4 * source) { destination->x = source->x; destination->y = source->y; destination->z = source->z; destination->w = source->w; return (destination); } /// Exchange values of two 2D, 3D or 4D vectors. static procedure vector_2_exchange (vector_2 * vector_a, vector_2 * vector_b) { exchange_real (& vector_a->x, & vector_b->x); exchange_real (& vector_a->y, & vector_b->y); } static procedure vector_3_exchange (vector_3 * vector_a, vector_3 * vector_b) { exchange_real (& vector_a->x, & vector_b->x); exchange_real (& vector_a->y, & vector_b->y); exchange_real (& vector_a->z, & vector_b->z); } static procedure vector_4_exchange (vector_4 * vector_a, vector_4 * vector_b) { exchange_real (& vector_a->x, & vector_b->x); exchange_real (& vector_a->y, & vector_b->y); exchange_real (& vector_a->z, & vector_b->z); exchange_real (& vector_a->w, & vector_b->w); } /// Scale 2D, 3D or 4D vector by scalar value and return address of that vector. static vector_2 * vector_2_scale (vector_2 * destination, real scale) { destination->x *= scale; destination->y *= scale; return (destination); } static vector_3 * vector_3_scale (vector_3 * destination, real scale) { destination->x *= scale; destination->y *= scale; destination->z *= scale; return (destination); } static vector_4 * vector_4_scale (vector_4 * destination, real scale) { destination->x *= scale; destination->y *= scale; destination->z *= scale; destination->w *= scale; return (destination); } /// Scale 2D, 3D or 4D source vector by scalar value into destination vector and return its address. static vector_2 * vector_2_scale_to (vector_2 * destination, vector_2 * source, real scale) { destination->x = source->x * scale; destination->y = source->y * scale; return (destination); } static vector_3 * vector_3_scale_to (vector_3 * destination, vector_3 * source, real scale) { destination->x = source->x * scale; destination->y = source->y * scale; destination->z = source->z * scale; return (destination); } static vector_4 * vector_4_scale_to (vector_4 * destination, vector_4 * source, real scale) { destination->x = source->x * scale; destination->y = source->y * scale; destination->z = source->z * scale; destination->w = source->w * scale; return (destination); } /// Add 2D, 3D or 4D source vector onto destination vector and return address of destination vector. static vector_2 * vector_2_add (vector_2 * destination, vector_2 * source) { destination->x += source->x; destination->y += source->y; return (destination); } static vector_3 * vector_3_add (vector_3 * destination, vector_3 * source) { destination->x += source->x; destination->y += source->y; destination->z += source->z; return (destination); } static vector_4 * vector_4_add (vector_4 * destination, vector_4 * source) { destination->x += source->x; destination->y += source->y; destination->z += source->z; destination->w += source->w; return (destination); } /// Add two 2D, 3D or 4D vectors into destination vector and return address of destination vector. static vector_2 * vector_2_add_to (vector_2 * destination, vector_2 * vector_a, vector_2 * vector_b) { destination->x = vector_a->x + vector_b->x; destination->y = vector_a->y + vector_b->y; return (destination); } static vector_3 * vector_3_add_to (vector_3 * destination, vector_3 * vector_a, vector_3 * vector_b) { destination->x = vector_a->x + vector_b->x; destination->y = vector_a->y + vector_b->y; destination->z = vector_a->z + vector_b->z; return (destination); } static vector_4 * vector_4_add_to (vector_4 * destination, vector_4 * vector_a, vector_4 * vector_b) { destination->x = vector_a->x + vector_b->x; destination->y = vector_a->y + vector_b->y; destination->z = vector_a->z + vector_b->z; destination->w = vector_a->w + vector_b->w; return (destination); } /// Subtract 2D, 3D or 4D source vector from destination vector and return address of destination vector. static vector_2 * vector_2_subtract (vector_2 * destination, vector_2 * source) { destination->x -= source->x; destination->y -= source->y; return (destination); } static vector_3 * vector_3_subtract (vector_3 * destination, vector_3 * source) { destination->x -= source->x; destination->y -= source->y; destination->z -= source->z; return (destination); } static vector_4 * vector_4_subtract (vector_4 * destination, vector_4 * source) { destination->x -= source->x; destination->y -= source->y; destination->z -= source->z; destination->w -= source->w; return (destination); } /// Subtract two 2D, 3D or 4D vectors, save values into destination vector and return address of destination vector. static vector_2 * vector_2_subtract_to (vector_2 * destination, vector_2 * vector_a, vector_2 * vector_b) { destination->x = vector_a->x - vector_b->x; destination->y = vector_a->y - vector_b->y; return (destination); } static vector_3 * vector_3_subtract_to (vector_3 * destination, vector_3 * vector_a, vector_3 * vector_b) { destination->x = vector_a->x - vector_b->x; destination->y = vector_a->y - vector_b->y; destination->z = vector_a->z - vector_b->z; return (destination); } static vector_4 * vector_4_subtract_to (vector_4 * destination, vector_4 * vector_a, vector_4 * vector_b) { destination->x = vector_a->x - vector_b->x; destination->y = vector_a->y - vector_b->y; destination->z = vector_a->z - vector_b->z; destination->w = vector_a->w - vector_b->w; return (destination); } /// Compare if two 2D, 3D or 4D vectors are identical and return boolean value of it. static boolean vector_2_compare (vector_2 * vector_a, vector_2 * vector_b) { if ((vector_a->x == vector_b->x) && (vector_a->y == vector_b->y)) { return (true); } else { return (false); } } static boolean vector_3_compare (vector_3 * vector_a, vector_3 * vector_b) { if ((vector_a->x == vector_b->x) && (vector_a->y == vector_b->y) && (vector_a->z == vector_b->z)) { return (true); } else { return (false); } } static boolean vector_4_compare (vector_4 * vector_a, vector_4 * vector_b) { if ((vector_a->x == vector_b->x) && (vector_a->y == vector_b->y) && (vector_a->z == vector_b->z) && (vector_a->w == vector_b->w)) { return (true); } else { return (false); } } /// Return dot product of two 2D, 3D or 4D vectors. static real vector_2_dot_product (vector_2 * vector_a, vector_2 * vector_b) { return (vector_a->x * vector_b->x + vector_a->y * vector_b->y); } static real vector_3_dot_product (vector_3 * vector_a, vector_3 * vector_b) { return (vector_a->x * vector_b->x + vector_a->y * vector_b->y + vector_a->z * vector_b->z); } static real vector_4_dot_product (vector_4 * vector_a, vector_4 * vector_b) { return (vector_a->x * vector_b->x + vector_a->y * vector_b->y + vector_a->z * vector_b->z + vector_a->w * vector_b->w); } /// Return cross product of two 2D vectors. static real vector_2_cross_product (vector_2 * vector_a, vector_2 * vector_b) { return (vector_a->x * vector_b->y - vector_a->y * vector_b->x); } /// Return cross product of two 3D vectors. static vector_3 * vector_3_cross_product (vector_3 * destination, vector_3 * source) { destination->x = destination->y * source->z - destination->z * source->y; destination->y = destination->z * source->x - destination->x * source->z; destination->z = destination->x * source->y - destination->y * source->x; return (destination); }