+++ /dev/null
-
-/*******************************************************************************
-
- 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_
-