]> Dogcows Code - chaz/yoink/blobdiff - src/vector.hh
new classes; yajl library
[chaz/yoink] / src / vector.hh
diff --git a/src/vector.hh b/src/vector.hh
new file mode 100644 (file)
index 0000000..f5c18ba
--- /dev/null
@@ -0,0 +1,372 @@
+
+/*******************************************************************************
+
+ Copyright (c) 2009, Charles McGarvey
+ All rights reserved.
+ Redistribution   and   use  in  source  and  binary  forms,  with  or  without
+ modification, are permitted provided that the following conditions are met:
+   * Redistributions  of  source  code  must retain the above copyright notice,
+     this list of conditions and the following disclaimer.
+   * Redistributions  in binary form must reproduce the above copyright notice,
+     this  list of conditions and the following disclaimer in the documentation
+     and/or other materials provided with the distribution.
+ THIS  SOFTWARE  IS  PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED.  IN  NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES  (INCLUDING,  BUT  NOT  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES;  LOSS  OF  USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+*******************************************************************************/
+
+#ifndef _VECTOR_HH_
+#define _VECTOR_HH_
+
+/**
+ * @file vector.hh
+ * Vector classes.
+ */
+
+#include <iostream>
+#include <cassert>
+
+#include "math.hh"
+#include "random.hh"
+
+
+// TODO: project, reflect, random, normal (of plane), orthonormal
+
+namespace dc {
+
+/**
+ * 2-dimensional vector.
+ */
+
+struct vector2
+{
+       vector2() {}
+       vector2(scalar X, scalar Y) : x(X), y(Y) {}
+       vector2(scalar v[2]) : x(v[0]), y(v[1]) {}
+
+       const scalar& operator[](int i) const
+       {
+               assert(i >= 0 && i <= 1 && "Index into vector2 out of bounds.");
+               return array[i];
+       }
+       scalar& operator[](int i)
+       {
+               assert(i >= 0 && i <= 1 && "Index into vector2 out of bounds.");
+               return array[i];
+       }
+
+       vector2 operator+(const vector2& v) const
+       {
+               return vector2(x + v.x, y + v.y);
+       }
+       vector2 operator-(const vector2& v) const
+       {
+               return vector2(x - v.x, y - v.y);
+       }
+       vector2 operator*(scalar s) const
+       {
+               return vector2(x * s, y * s);
+       }
+       vector2 operator/(scalar s) const
+       {
+               return vector2(x / s, y / s);
+       }
+
+       vector2& operator+=(const vector2& v)
+       {
+               x += v.x; y += v.y;
+               return *this;
+       }
+       vector2& operator-=(const vector2& v)
+       {
+               x -= v.x; y -= v.y;
+               return *this;
+       }
+       vector2& operator*=(scalar s)
+       {
+               x *= s; y *= s;
+               return *this;
+       }
+       vector2& operator/=(scalar s)
+       {
+               x /= s; y /= s;
+               return *this;
+       }
+
+       vector2 operator-() const
+       {
+               return vector2(-x, -y);
+       }
+
+       scalar dot(const vector2& v) const      /// dot product
+       {
+               return x * v.x + y * v.y;
+       }
+       scalar angleBetween(const vector2& v) const
+       {
+               scalar lens = length() * v.length();
+               if (lens == 0.0) { return HUGE_VAL; }
+               return std::acos(dot(v) / lens);
+       }
+
+       void normalize()                /// scale such that length is one
+       {
+               scalar len = length();
+               if (len != 0.0) { *this /= len; }
+       }
+       vector2 normalized() const
+       {
+               scalar len = length();
+               if (len != 0.0) { return *this / len; }
+               return vector2(0.0, 0.0);
+       }
+
+       scalar length2() const  /// magnitude squared
+       {
+               return dot(*this);
+       }
+       scalar length() const   /// magnitude
+       {
+               return std::sqrt(length2());
+       }
+
+       bool operator==(const vector2& v) const
+       {
+               return equals(x, v.x) && equals(y, v.y);
+       }
+       bool operator!=(const vector2& v) const
+       {
+               return !(*this == v);
+       }
+
+
+       static vector2 random()
+       {
+               vector2 v = random(-1.0, 1.0);
+               v.normalize();
+               return v;
+       }
+
+       static vector2 random(scalar lower, scalar upper)
+       {
+               return vector2(rng::get<scalar>(lower, upper),
+                                          rng::get<scalar>(lower, upper));
+       }
+
+
+       union
+       {
+               struct
+               {
+                       scalar x, y;    ///< euler coordinates
+               };
+               scalar array[2];        ///< array
+       };
+
+       static vector2 zero;    ///< zero vector
+};
+
+inline vector2 operator*(scalar s, const vector2& v)
+{
+       return v * s;
+}
+inline vector2 operator/(scalar s, const vector2& v)
+{
+       return vector2(s / v.x, s / v.y);
+}
+
+inline std::ostream& operator<<(std::ostream& output, const vector2& v)
+{
+       output << "(" << v.x << "," << v.y << ")";
+    return output;
+}
+
+
+typedef vector2 point;
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+/**
+ * 3-dimensional vector.
+ */
+
+struct vector3
+{
+       vector3() {}
+       vector3(scalar X, scalar Y, scalar Z) : x(X), y(Y), z(Z) {}
+       vector3(scalar v[3]) : x(v[0]), y(v[1]), z(v[2]) {}
+
+       const scalar& operator[](int i) const
+       {
+               assert(i >= 0 && i <= 2 && "Index into vector3 out of bounds.");
+               return array[i];
+       }
+       scalar& operator[](int i)
+       {
+               assert(i >= 0 && i <= 2 && "Index into vector3 out of bounds.");
+               return array[i];
+       }
+
+       vector3 operator+(const vector3& v) const
+       {
+               return vector3(x + v.x, y + v.y, z + v.z);
+       }
+       vector3 operator-(const vector3& v) const
+       {
+               return vector3(x - v.x, y - v.y, z - v.z);
+       }
+       vector3 operator*(scalar s) const
+       {
+               return vector3(x * s, y * s, z * s);
+       }
+       vector3 operator/(scalar s) const
+       {
+               return vector3(x / s, y / s, z / s);
+       }
+
+       vector3& operator+=(const vector3& v)
+       {
+               x += v.x; y += v.y; z += v.z;
+               return *this;
+       }
+       vector3& operator-=(const vector3& v)
+       {
+               x -= v.x; y -= v.y; z -= v.z;
+               return *this;
+       }
+       vector3& operator*=(scalar s)
+       {
+               x *= s; y *= s; z *= s;
+               return *this;
+       }
+       vector3& operator/=(scalar s)
+       {
+               x /= s; y /= s; z /= s;
+               return *this;
+       }
+
+       vector3 operator-() const
+       {
+               return vector3(-x, -y, -z);
+       }
+
+       scalar dot(const vector3& v) const              /// dot product
+       {
+               return x * v.x + y * v.y + z * v.z;
+       }
+       vector3 cross(const vector3& v) const   /// cross product
+       {
+               return vector3(y * v.z - z * v.y,
+                                          z * v.x - x * v.z,
+                                          x * v.y - y * v.x);
+       }
+
+       scalar angleBetween(const vector3& v) const
+       {
+               scalar lens = length() * v.length();
+               if (lens == 0.0) { return HUGE_VAL; }
+               return std::acos(dot(v) / lens);
+       }
+
+       void normalize()                /// scale such that length is one
+       {
+               scalar len = length();
+               if (len != 0.0) { *this /= len; }
+       }
+       vector3 normalized() const
+       {
+               scalar len = length();
+               if (len != 0.0) { return *this / len; }
+               return vector3(0.0, 0.0, 0.0);
+       }
+
+       scalar length2() const  /// magnitude squared
+       {
+               return dot(*this);
+       }
+       scalar length() const   /// magnitude
+       {
+               return std::sqrt(length2());
+       }
+
+       bool operator==(const vector3& v) const
+       {
+               return equals(x, v.x) && equals(y, v.y) && equals(z, v.z);
+       }
+       bool operator!=(const vector3& v) const
+       {
+               return !(*this == v);
+       }
+
+
+       static vector3 random()
+       {
+               vector3 v = random(-1.0, 1.0);
+               v.normalize();
+               return v;
+       }
+
+       static vector3 random(scalar lower, scalar upper)
+       {
+               return vector3(rng::get<scalar>(lower, upper),
+                                          rng::get<scalar>(lower, upper),
+                                          rng::get<scalar>(lower, upper));
+       }
+
+
+       union
+       {
+               struct
+               {
+                       scalar x, y, z;         ///< euler coordinates
+               };
+               struct
+               {
+                       scalar u, v, w;         ///< texture coordinates
+               };
+               struct
+               {
+                       scalar r, g, b;         ///< color intensities
+               };
+               scalar array[3];                ///< array
+       };
+
+       static vector3 zero;            ///< zero vector
+};
+
+inline vector3 operator*(scalar s, const vector3& v)
+{
+       return v * s;
+}
+inline vector3 operator/(scalar s, const vector3& v)
+{
+       return vector3(s / v.x, s / v.y, s / v.z);
+}
+
+inline std::ostream& operator<<(std::ostream& output, const vector3& v)
+{
+       output << "(" << v.x << "," << v.y << "," << v.z << ")";
+    return output;
+}
+
+
+typedef vector3 color;
+
+
+} // namespace dc
+
+
+#endif // _VECTOR_HH_
+
This page took 0.032463 seconds and 4 git commands to generate.