diff --git a/examples/cpp/lib/svl/Basics.h b/examples/cpp/lib/svl/Basics.h new file mode 100644 index 0000000000000000000000000000000000000000..c59852c4e3502300c84ecb97470ab7488d0c6cff --- /dev/null +++ b/examples/cpp/lib/svl/Basics.h @@ -0,0 +1,162 @@ +/* + File: Basics.h + + Function: Basic definitions for all files. Contains type + definitions, assertion and debugging facilities, and + miscellaneous useful template functions. + + This is a cut-down version for SVL. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott + + Notes: This header is affected by the following defines: + + VL_CHECKING - Include code for assertions, + range errors and warnings. + VL_FLOAT - Use floats for real numbers. (Doubles + are the default.) + VL_NO_BOOL - There is no bool type. + VL_NO_TF - true and false are not predefined. +*/ + +#ifndef __Basics__ +#define __Basics__ + +#include "SVLConfig.h" +#include <iostream> +#include <cmath> + + +// --- Basic types ------------------------------------------------------------- + +typedef void Void; +typedef float Float; +typedef double Double; +typedef char Char; +typedef int Short; +typedef int Int; +typedef long Long; +typedef unsigned char Byte; +typedef unsigned int UInt; + +#ifndef VL_FLOAT +typedef Double Real; +#else +typedef Float Real; +#endif + +#define SELF (*this) // A syntactic convenience. + + +// --- Boolean type ------------------------------------------------------------ + +// X11 #defines 'Bool' -- typical. + +#ifdef Bool +#undef Bool +#endif + +#ifndef VL_NO_BOOL +// if the compiler implements the bool type... +typedef bool Bool; +#else +// if not, make up our own. +class Bool +{ +public: + + Bool() : val(0) {}; + Bool(Int b) : val(b) {}; + + operator Int() { return val; }; + +private: + Int val; +}; +#ifdef VL_NO_TF +enum {false, true}; +#endif +#endif + + +// --- Assertions and Range checking ------------------------------------------- + +#define _Error(e) _Assert(false, e, __FILE__, __LINE__) +#define _Warning(w) _Expect(false, w, __FILE__, __LINE__) + +#if defined(VL_CHECKING) +#define Assert(b, e) _Assert(b, e, __FILE__, __LINE__) + // Assert that b is true. e is an error message to be printed if b + // is false. +#define Expect(b, w) _Expect(b, w, __FILE__, __LINE__) + // Prints warning w if b is false +#define CheckRange(i, l, u, r) _CheckRange(i, l, u, r, __FILE__, __LINE__) + // Checks whether i is in the range [lowerBound, upperBound). +#else +#define Assert(b, e) +#define Expect(b, w) +#define CheckRange(a, l, u, r) +#endif + +Void _Assert(Int condition, const Char *errorMessage, const Char *file, Int line); +Void _Expect(Int condition, const Char *warningMessage, const Char *file, Int line); +Void _CheckRange(Int i, Int lowerBound, Int upperBound, const Char *rangeMessage, + const Char *file, Int line); + + +// --- Inlines ----------------------------------------------------------------- + +template<class Value> + inline Value Min(Value x, Value y) + { + if (x <= y) + return(x); + else + return(y); + }; + +template<class Value> + inline Value Max(Value x, Value y) + { + if (x >= y) + return(x); + else + return(y); + }; + +template<class Value> + inline Void Swap(Value &x, Value &y) + { + Value t; + + t = x; + x = y; + y = t; + }; + +template<class Value> + inline Value Mix(Value x, Value y, Real s) + { + return(x + (y - x) * s); + }; + +template<class Value> + inline Value Clip(Value x, Value min, Value max) + { + if (x < min) + return(min); + else if (x > max) + return(max); + else + return(x); + }; + +template<class Value> + inline Value sqr(Value x) + { + return(x * x); + }; + +#endif diff --git a/examples/cpp/lib/svl/Constants.h b/examples/cpp/lib/svl/Constants.h new file mode 100644 index 0000000000000000000000000000000000000000..bc3a5b8875fb5a65b0946e1b6894c157159b4471 --- /dev/null +++ b/examples/cpp/lib/svl/Constants.h @@ -0,0 +1,43 @@ +/* + File: Constants.h + + Function: Contains various constants for VL. + + Author: Andrew Willmott + + Copyright: (c) 1999-2001, Andrew Willmott +*/ + +#ifndef __VLConstants__ +#define __VLConstants__ + +#include <cmath> + + +// --- Mathematical constants ------------------------------------------------- + + +#ifdef M_PI +const Real vl_pi = M_PI; +const Real vl_halfPi = M_PI_2; +#elif defined(_PI) +const Real vl_pi = _PI; +const Real vl_halfPi = vl_pi / 2.0; +#else +const Real vl_pi = 3.14159265358979323846; +const Real vl_halfPi = vl_pi / 2.0; +#endif + +#ifdef HUGE_VAL +const Double vl_inf = HUGE_VAL; +#endif + +enum ZeroOrOne { vl_zero = 0, vl_0 = 0, vl_one = 1, vl_I = 1, vl_1 = 1 }; +enum Block { vl_Z = 0, vl_B = 1, vl_block = 1 }; +enum Axis { vl_x, vl_y, vl_z, vl_w }; +typedef Axis vl_axis; + +const UInt VL_REF_FLAG = UInt(1) << (sizeof(UInt) * 8 - 1); +const UInt VL_REF_MASK = (~VL_REF_FLAG); + +#endif diff --git a/examples/cpp/lib/svl/LICENSE b/examples/cpp/lib/svl/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..7c1e717dab0c6ea10c7aa55a848865312bd6fd87 --- /dev/null +++ b/examples/cpp/lib/svl/LICENSE @@ -0,0 +1,23 @@ + +Except where otherwise noted, Copyright (c) 2002 Andrew Willmott. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form have no conditions on them. + +THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS 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. diff --git a/examples/cpp/lib/svl/Mat.h b/examples/cpp/lib/svl/Mat.h new file mode 100644 index 0000000000000000000000000000000000000000..8162ed892c3f9caa148e771ee9bc400bb54621a0 --- /dev/null +++ b/examples/cpp/lib/svl/Mat.h @@ -0,0 +1,213 @@ +/* + File: Mat.h + + Function: Defines a generic resizeable matrix. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott + */ + +#ifndef __Mat__ +#define __Mat__ + +#include "svl/Vec.h" + +class Mat2; +class Mat3; +class Mat4; + + +// --- Mat Class -------------------------------------------------------------- + +class Mat +{ +public: + + // Constructors + + Mat(); // Null matrix + Mat(Int rows, Int cols); // Uninitialised matrix + Mat(Int rows, Int cols, Double elt0 ...); // Mat(2, 2, 1.0, 2.0, 3.0, 4.0) + Mat(Int nrows, Int ncols, Real *ndata); // Create reference matrix + Mat(const Mat &m); // Copy constructor + Mat(const Mat2 &m); // reference to a Mat2 + Mat(const Mat3 &m); // reference to a Mat3 + Mat(const Mat4 &m); // reference to a Mat4 + Mat(Int rows, Int cols, ZeroOrOne k); // I * k + Mat(Int rows, Int cols, Block k); // block matrix (m[i][j] = k) + + ~Mat(); + + // Accessor methods + + Int Rows() const { return(rows & VL_REF_MASK); }; + Int Cols() const { return(cols); }; + + Vec operator [] (Int i); // Indexing by row + Vec operator [] (Int i) const; // Indexing by row + + Real &Elt(Int i, Int j); // Indexing by elt + Real Elt(Int i, Int j) const; + + Void SetSize(Int nrows, Int ncols); + Void SetSize(const Mat &m); + Bool IsSquare() const + { return((rows & VL_REF_MASK) == cols); }; + + Real *Ref() const; // Return pointer to data + + // Assignment operators + + Mat &operator = (const Mat &m); // Assignment of a matrix + Mat &operator = (ZeroOrOne k); // Set to k * I... + Mat &operator = (Block k); // Set to a block matrix... + Mat &operator = (const Mat2 &m); + Mat &operator = (const Mat3 &m); + Mat &operator = (const Mat4 &m); + + // In-Place Operators + + Mat &operator += (const Mat &m); + Mat &operator -= (const Mat &m); + Mat &operator *= (const Mat &m); + Mat &operator *= (Real s); + Mat &operator /= (Real s); + + // Matrix initialisers + + Void MakeZero(); + Void MakeDiag(Real k); + Void MakeDiag(); + Void MakeBlock(Real k); + Void MakeBlock(); + + Mat &Clamp(Real fuzz); + Mat &Clamp(); + + // Private... + +protected: + + Real *data; + UInt rows; + UInt cols; + + Bool IsRef() { return((rows & VL_REF_FLAG) != 0); }; +}; + + +// --- Mat Comparison Operators ----------------------------------------------- + +Bool operator == (const Mat &m, const Mat &n); +Bool operator != (const Mat &m, const Mat &n); + + +// --- Mat Arithmetic Operators ----------------------------------------------- + +Mat operator + (const Mat &m, const Mat &n); +Mat operator - (const Mat &m, const Mat &n); +Mat operator - (const Mat &m); +Mat operator * (const Mat &m, const Mat &n); +Mat operator * (const Mat &m, Real s); +inline Mat operator * (Real s, const Mat &m); +Mat operator / (const Mat &m, Real s); + +Vec operator * (const Mat &m, const Vec &v); +Vec operator * (const Vec &v, const Mat &m); + +Mat trans(const Mat &m); // Transpose +Real trace(const Mat &m); // Trace +Mat inv(const Mat &m, Real *determinant = 0, Real pEps = 1e-20); + // Inverse +Mat oprod(const Vec &a, const Vec &b); // Outer product + +Mat clamped(const Mat &m, Real fuzz); +Mat clamped(const Mat &m); + + +// --- Mat Input & Output ----------------------------------------------------- + +std::ostream &operator << (std::ostream &s, const Mat &m); +std::istream &operator >> (std::istream &s, Mat &m); + + +// --- Mat Inlines ------------------------------------------------------------ + +inline Mat::Mat() : data(0), rows(0), cols(0) +{ +} + +inline Mat::Mat(Int rows, Int cols) : rows(rows), cols(cols) +{ + Assert(rows > 0 && cols > 0, "(Mat) illegal matrix size"); + + data = new Real[rows * cols]; +} + +inline Mat::Mat(Int nrows, Int ncols, Real *ndata) : + data(ndata), rows(nrows | VL_REF_FLAG), cols(ncols) +{ +} + +inline Vec Mat::operator [] (Int i) +{ + CheckRange(i, 0, Rows(), "(Mat::[i]) i index out of range"); + + return(Vec(cols, data + i * cols)); +} + +inline Vec Mat::operator [] (Int i) const +{ + CheckRange(i, 0, Rows(), "(Mat::[i]) i index out of range"); + + return(Vec(cols, data + i * cols)); +} + +inline Real &Mat::Elt(Int i, Int j) +{ + CheckRange(i, 0, Rows(), "(Mat::e(i,j)) i index out of range"); + CheckRange(j, 0, Cols(), "(Mat::e(i,j)) j index out of range"); + + return(data[i * cols + j]); +} + +inline Real Mat::Elt(Int i, Int j) const +{ + CheckRange(i, 0, Rows(), "(Mat::e(i,j)) i index out of range"); + CheckRange(j, 0, Cols(), "(Mat::e(i,j)) j index out of range"); + + return(data[i * cols + j]); +} + +inline Real *Mat::Ref() const +{ + return(data); +} + +inline Mat operator * (Real s, const Mat &m) +{ + return(m * s); +} + +inline Mat &Mat::operator = (ZeroOrOne k) +{ + MakeDiag(k); + + return(SELF); +} + +inline Mat &Mat::operator = (Block k) +{ + MakeBlock((ZeroOrOne) k); + + return(SELF); +} + +inline Mat::~Mat() +{ + if (!IsRef()) + delete[] data; +} + +#endif diff --git a/examples/cpp/lib/svl/Mat2.h b/examples/cpp/lib/svl/Mat2.h new file mode 100644 index 0000000000000000000000000000000000000000..7f0a6fa6ef902bb44eecb2351cd0f1962b5cc000 --- /dev/null +++ b/examples/cpp/lib/svl/Mat2.h @@ -0,0 +1,379 @@ +/* + File: Mat2.h + + Function: Defines a 2 x 2 matrix. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott + */ + +#ifndef __Mat2__ +#define __Mat2__ + +#include "svl/Vec2.h" + + +// --- Mat2 Class ------------------------------------------------------------- + +class Mat2 +{ +public: + + // Constructors + + Mat2(); + Mat2(Real a, Real b, Real c, Real d); // Create from rows + Mat2(const Mat2 &m); // Copy constructor + Mat2(ZeroOrOne k); + Mat2(Block k); + + // Accessor functions + + Int Rows() const { return(2); }; + Int Cols() const { return(2); }; + + Vec2 &operator [] (Int i); + const Vec2 &operator [] (Int i) const; + + Real *Ref() const; // Return pointer to data + + // Assignment operators + + Mat2 &operator = (const Mat2 &m); + Mat2 &operator = (ZeroOrOne k); + Mat2 &operator = (Block k); + Mat2 &operator += (const Mat2 &m); + Mat2 &operator -= (const Mat2 &m); + Mat2 &operator *= (const Mat2 &m); + Mat2 &operator *= (Real s); + Mat2 &operator /= (Real s); + + // Comparison operators + + Bool operator == (const Mat2 &m) const; // M == N? + Bool operator != (const Mat2 &m) const; // M != N? + + // Arithmetic operators + + Mat2 operator + (const Mat2 &m) const; // M + N + Mat2 operator - (const Mat2 &m) const; // M - N + Mat2 operator - () const; // -M + Mat2 operator * (const Mat2 &m) const; // M * N + Mat2 operator * (Real s) const; // M * s + Mat2 operator / (Real s) const; // M / s + + // Initialisers + + Void MakeZero(); // Zero matrix + Void MakeDiag(Real k = vl_one); // I + Void MakeBlock(Real k = vl_one); // all elts=k + + // Vector Transformations + + Mat2& MakeRot(Real theta); + Mat2& MakeScale(const Vec2 &s); + + // Private... + +protected: + + Vec2 row[2]; // Rows of the matrix +}; + + +// --- Matrix operators ------------------------------------------------------- + +inline Vec2 &operator *= (Vec2 &v, const Mat2 &m); // v *= m +inline Vec2 operator * (const Mat2 &m, const Vec2 &v); // m * v +inline Vec2 operator * (const Vec2 &v, const Mat2 &m); // v * m +inline Mat2 operator * (Real s, const Mat2 &m); // s * m + +inline Mat2 trans(const Mat2 &m); // Transpose +inline Real trace(const Mat2 &m); // Trace +inline Mat2 adj(const Mat2 &m); // Adjoint +Real det(const Mat2 &m); // Determinant +Mat2 inv(const Mat2 &m); // Inverse +Mat2 oprod(const Vec2 &a, const Vec2 &b); + // Outer product + +// The xform functions help avoid dependence on whether row or column +// vectors are used to represent points and vectors. +inline Vec2 xform(const Mat2 &m, const Vec2 &v); // Transform of v by m +inline Mat2 xform(const Mat2 &m, const Mat2 &n); // xform v -> m(n(v)) + +std::ostream &operator << (std::ostream &s, const Mat2 &m); +std::istream &operator >> (std::istream &s, Mat2 &m); + + +// --- Inlines ---------------------------------------------------------------- + +inline Vec2 &Mat2::operator [] (Int i) +{ + CheckRange(i, 0, 2, "(Mat2::[i]) index out of range"); + return(row[i]); +} + +inline const Vec2 &Mat2::operator [] (Int i) const +{ + CheckRange(i, 0, 2, "(Mat2::[i]) index out of range"); + return(row[i]); +} + +inline Real *Mat2::Ref() const +{ + return((Real*) row); +} + +inline Mat2::Mat2() +{ +} + +inline Mat2::Mat2(Real a, Real b, Real c, Real d) +{ + row[0][0] = a; row[0][1] = b; + row[1][0] = c; row[1][1] = d; +} + +inline Mat2::Mat2(const Mat2 &m) +{ + row[0] = m[0]; + row[1] = m[1]; +} + + +inline Void Mat2::MakeZero() +{ + row[0][0] = vl_zero; row[0][1] = vl_zero; + row[1][0] = vl_zero; row[1][1] = vl_zero; +} + +inline Void Mat2::MakeDiag(Real k) +{ + row[0][0] = k; row[0][1] = vl_zero; + row[1][0] = vl_zero; row[1][1] = k; +} + +inline Void Mat2::MakeBlock(Real k) +{ + row[0][0] = k; row[0][1] = k; + row[1][0] = k; row[1][1] = k; +} + +inline Mat2::Mat2(ZeroOrOne k) +{ + MakeDiag(k); +} + +inline Mat2::Mat2(Block k) +{ + MakeBlock((ZeroOrOne) k); +} + +inline Mat2 &Mat2::operator = (ZeroOrOne k) +{ + MakeDiag(k); + + return(SELF); +} + +inline Mat2 &Mat2::operator = (Block k) +{ + MakeBlock((ZeroOrOne) k); + + return(SELF); +} + +inline Mat2 &Mat2::operator = (const Mat2 &m) +{ + row[0] = m[0]; + row[1] = m[1]; + + return(SELF); +} + +inline Mat2 &Mat2::operator += (const Mat2 &m) +{ + row[0] += m[0]; + row[1] += m[1]; + + return(SELF); +} + +inline Mat2 &Mat2::operator -= (const Mat2 &m) +{ + row[0] -= m[0]; + row[1] -= m[1]; + + return(SELF); +} + +inline Mat2 &Mat2::operator *= (const Mat2 &m) +{ + SELF = SELF * m; + + return(SELF); +} + +inline Mat2 &Mat2::operator *= (Real s) +{ + row[0] *= s; + row[1] *= s; + + return(SELF); +} + +inline Mat2 &Mat2::operator /= (Real s) +{ + row[0] /= s; + row[1] /= s; + + return(SELF); +} + + +inline Mat2 Mat2::operator + (const Mat2 &m) const +{ + Mat2 result; + + result[0] = row[0] + m[0]; + result[1] = row[1] + m[1]; + + return(result); +} + +inline Mat2 Mat2::operator - (const Mat2 &m) const +{ + Mat2 result; + + result[0] = row[0] - m[0]; + result[1] = row[1] - m[1]; + + return(result); +} + +inline Mat2 Mat2::operator - () const +{ + Mat2 result; + + result[0] = -row[0]; + result[1] = -row[1]; + + return(result); +} + +inline Mat2 Mat2::operator * (const Mat2 &m) const +{ +#define N(x,y) row[x][y] +#define M(x,y) m.row[x][y] +#define R(x,y) result[x][y] + + Mat2 result; + + R(0,0) = N(0,0) * M(0,0) + N(0,1) * M(1,0); + R(0,1) = N(0,0) * M(0,1) + N(0,1) * M(1,1); + R(1,0) = N(1,0) * M(0,0) + N(1,1) * M(1,0); + R(1,1) = N(1,0) * M(0,1) + N(1,1) * M(1,1); + + return(result); + +#undef N +#undef M +#undef R +} + +inline Mat2 Mat2::operator * (Real s) const +{ + Mat2 result; + + result[0] = row[0] * s; + result[1] = row[1] * s; + + return(result); +} + +inline Mat2 Mat2::operator / (Real s) const +{ + Mat2 result; + + result[0] = row[0] / s; + result[1] = row[1] / s; + + return(result); +} + +inline Mat2 operator * (Real s, const Mat2 &m) +{ + return(m * s); +} + +inline Vec2 operator * (const Mat2 &m, const Vec2 &v) +{ + Vec2 result; + + result[0] = m[0][0] * v[0] + m[0][1] * v[1]; + result[1] = m[1][0] * v[0] + m[1][1] * v[1]; + + return(result); +} + +inline Vec2 operator * (const Vec2 &v, const Mat2 &m) +{ + Vec2 result; + + result[0] = v[0] * m[0][0] + v[1] * m[1][0]; + result[1] = v[0] * m[0][1] + v[1] * m[1][1]; + + return(result); +} + +inline Vec2 &operator *= (Vec2 &v, const Mat2 &m) +{ + Real t; + + t = v[0] * m[0][0] + v[1] * m[1][0]; + v[1] = v[0] * m[0][1] + v[1] * m[1][1]; + v[0] = t; + + return(v); +} + + +inline Mat2 trans(const Mat2 &m) +{ + Mat2 result; + + result[0][0] = m[0][0]; result[0][1] = m[1][0]; + result[1][0] = m[0][1]; result[1][1] = m[1][1]; + + return(result); +} + +inline Real trace(const Mat2 &m) +{ + return(m[0][0] + m[1][1]); +} + +inline Mat2 adj(const Mat2 &m) +{ + Mat2 result; + + result[0] = cross(m[1]); + result[1] = -cross(m[0]); + + return(result); +} + +#ifdef VL_ROW_ORIENT +inline Vec2 xform(const Mat2 &m, const Vec2 &v) +{ return(v * m); } +inline Mat2 xform(const Mat2 &m, const Mat2 &n) +{ return(n * m); } +#else +inline Vec2 xform(const Mat2 &m, const Vec2 &v) +{ return(m * v); } +inline Mat2 xform(const Mat2 &m, const Mat2 &n) +{ return(m * n); } +#endif + +#endif diff --git a/examples/cpp/lib/svl/Mat3.h b/examples/cpp/lib/svl/Mat3.h new file mode 100644 index 0000000000000000000000000000000000000000..a528c7aa4bb300cf6c4062a3b50f06e9fc054120 --- /dev/null +++ b/examples/cpp/lib/svl/Mat3.h @@ -0,0 +1,224 @@ +/* + File: Mat3.h + + Function: Defines a 3 x 3 matrix. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott +*/ + +#ifndef __Mat3__ +#define __Mat3__ + +#include "svl/Vec3.h" + + +// --- Mat3 Class ------------------------------------------------------------- + + +class Vec4; + +class Mat3 +{ +public: + + // Constructors + + Mat3(); + Mat3(Real a, Real b, Real c, + Real d, Real e, Real f, + Real g, Real h, Real i); + Mat3(const Mat3 &m); + Mat3(ZeroOrOne k); + Mat3(Block k); + + // Accessor functions + + Int Rows() const { return(3); }; + Int Cols() const { return(3); }; + + Vec3 &operator [] (Int i); + const Vec3 &operator [] (Int i) const; + + Real *Ref() const; // Return pointer to data + + // Assignment operators + + Mat3 &operator = (const Mat3 &m); + Mat3 &operator = (ZeroOrOne k); + Mat3 &operator = (Block k); + Mat3 &operator += (const Mat3 &m); + Mat3 &operator -= (const Mat3 &m); + Mat3 &operator *= (const Mat3 &m); + Mat3 &operator *= (Real s); + Mat3 &operator /= (Real s); + + // Comparison operators + + Bool operator == (const Mat3 &m) const; // M == N? + Bool operator != (const Mat3 &m) const; // M != N? + + // Arithmetic operators + + Mat3 operator + (const Mat3 &m) const; // M + N + Mat3 operator - (const Mat3 &m) const; // M - N + Mat3 operator - () const; // -M + Mat3 operator * (const Mat3 &m) const; // M * N + Mat3 operator * (Real s) const; // M * s + Mat3 operator / (Real s) const; // M / s + + // Initialisers + + Void MakeZero(); // Zero matrix + Void MakeDiag(Real k = vl_one); // I + Void MakeBlock(Real k = vl_one); // all elts = k + + // Vector Transforms + + Mat3& MakeRot(const Vec3 &axis, Real theta); + Mat3& MakeRot(const Vec4 &q); // Rotate by quaternion + Mat3& MakeScale(const Vec3 &s); + + // Homogeneous Transforms + + Mat3& MakeHRot(Real theta); // Rotate by theta rads + Mat3& MakeHScale(const Vec2 &s); // Scale by s + Mat3& MakeHTrans(const Vec2 &t); // Translation by t + + // Private... + +protected: + + Vec3 row[3]; +}; + + +// --- Matrix operators ------------------------------------------------------- + +inline Vec3 &operator *= (Vec3 &v, const Mat3 &m); // v *= m +inline Vec3 operator * (const Mat3 &m, const Vec3 &v); // m * v +inline Vec3 operator * (const Vec3 &v, const Mat3 &m); // v * m +inline Mat3 operator * (const Real s, const Mat3 &m); // s * m + +Mat3 trans(const Mat3 &m); // Transpose +Real trace(const Mat3 &m); // Trace +Mat3 adj(const Mat3 &m); // Adjoint +Real det(const Mat3 &m); // Determinant +Mat3 inv(const Mat3 &m); // Inverse +Mat3 oprod(const Vec3 &a, const Vec3 &b); // Outer product + +// The xform functions help avoid dependence on whether row or column +// vectors are used to represent points and vectors. +inline Vec3 xform(const Mat3 &m, const Vec3 &v); // Transform of v by m +inline Vec2 xform(const Mat3 &m, const Vec2 &v); // Hom. xform of v by m +inline Mat3 xform(const Mat3 &m, const Mat3 &n); // Xform v -> m(n(v)) + +std::ostream &operator << (std::ostream &s, const Mat3 &m); +std::istream &operator >> (std::istream &s, Mat3 &m); + + +// --- Inlines ---------------------------------------------------------------- + +inline Mat3::Mat3() +{ +} + +inline Vec3 &Mat3::operator [] (Int i) +{ + CheckRange(i, 0, 3, "(Mat3::[i]) index out of range"); + return(row[i]); +} + +inline const Vec3 &Mat3::operator [] (Int i) const +{ + CheckRange(i, 0, 3, "(Mat3::[i]) index out of range"); + return(row[i]); +} + +inline Real *Mat3::Ref() const +{ + return((Real *) row); +} + +inline Mat3::Mat3(ZeroOrOne k) +{ + MakeDiag(k); +} + +inline Mat3::Mat3(Block k) +{ + MakeBlock((ZeroOrOne) k); +} + +inline Mat3 &Mat3::operator = (ZeroOrOne k) +{ + MakeDiag(k); + + return(SELF); +} + +inline Mat3 &Mat3::operator = (Block k) +{ + MakeBlock((ZeroOrOne) k); + + return(SELF); +} + +inline Mat3 operator * (const Real s, const Mat3 &m) +{ + return(m * s); +} + +inline Vec3 operator * (const Mat3 &m, const Vec3 &v) +{ + Vec3 result; + + result[0] = v[0] * m[0][0] + v[1] * m[0][1] + v[2] * m[0][2]; + result[1] = v[0] * m[1][0] + v[1] * m[1][1] + v[2] * m[1][2]; + result[2] = v[0] * m[2][0] + v[1] * m[2][1] + v[2] * m[2][2]; + + return(result); +} + +inline Vec3 operator * (const Vec3 &v, const Mat3 &m) +{ + Vec3 result; + + result[0] = v[0] * m[0][0] + v[1] * m[1][0] + v[2] * m[2][0]; + result[1] = v[0] * m[0][1] + v[1] * m[1][1] + v[2] * m[2][1]; + result[2] = v[0] * m[0][2] + v[1] * m[1][2] + v[2] * m[2][2]; + + return(result); +} + +inline Vec3 &operator *= (Vec3 &v, const Mat3 &m) +{ + Real t0, t1; + + t0 = v[0] * m[0][0] + v[1] * m[1][0] + v[2] * m[2][0]; + t1 = v[0] * m[0][1] + v[1] * m[1][1] + v[2] * m[2][1]; + v[2] = v[0] * m[0][2] + v[1] * m[1][2] + v[2] * m[2][2]; + v[0] = t0; + v[1] = t1; + + return(v); +} + +#ifdef VL_ROW_ORIENT +inline Vec2 xform(const Mat3 &m, const Vec2 &v) +{ return(proj(Vec3(v, 1.0) * m)); } +inline Vec3 xform(const Mat3 &m, const Vec3 &v) +{ return(v * m); } +inline Mat3 xform(const Mat3 &m, const Mat3 &n) +{ return(n * m); } +#else +inline Vec2 xform(const Mat3 &m, const Vec2 &v) +{ return(proj(m * Vec3(v, 1.0))); } +inline Vec3 xform(const Mat3 &m, const Vec3 &v) +{ return(m * v); } +inline Mat3 xform(const Mat3 &m, const Mat3 &n) +{ return(m * n); } +#endif + +#endif diff --git a/examples/cpp/lib/svl/Mat4.h b/examples/cpp/lib/svl/Mat4.h new file mode 100644 index 0000000000000000000000000000000000000000..d4d1dd6d7b7f1ef5ca3f2fbadf96ab54c8c96995 --- /dev/null +++ b/examples/cpp/lib/svl/Mat4.h @@ -0,0 +1,189 @@ +/* + File: Mat4.h + + Function: Defines a 4 x 4 matrix. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott + */ + +#ifndef __Mat4__ +#define __Mat4__ + +#include "svl/Vec3.h" +#include "svl/Vec4.h" + + +// --- Mat4 Class ------------------------------------------------------------- + +class Mat4 +{ +public: + + // Constructors + + Mat4(); + Mat4(Real a, Real b, Real c, Real d, + Real e, Real f, Real g, Real h, + Real i, Real j, Real k, Real l, + Real m, Real n, Real o, Real p); + Mat4(const Mat4 &m); + Mat4(ZeroOrOne k); + Mat4(Block k); + + // Accessor functions + + Int Rows() const { return(4); }; + Int Cols() const { return(4); }; + + Vec4 &operator [] (Int i); + const Vec4 &operator [] (Int i) const; + + Real *Ref() const; + + // Assignment operators + + Mat4 &operator = (const Mat4 &m); + Mat4 &operator = (ZeroOrOne k); + Mat4 &operator = (Block k); + Mat4 &operator += (const Mat4 &m); + Mat4 &operator -= (const Mat4 &m); + Mat4 &operator *= (const Mat4 &m); + Mat4 &operator *= (Real s); + Mat4 &operator /= (Real s); + + // Comparison operators + + Bool operator == (const Mat4 &m) const; // M == N? + Bool operator != (const Mat4 &m) const; // M != N? + + // Arithmetic operators + + Mat4 operator + (const Mat4 &m) const; // M + N + Mat4 operator - (const Mat4 &m) const; // M - N + Mat4 operator - () const; // -M + Mat4 operator * (const Mat4 &m) const; // M * N + Mat4 operator * (Real s) const; // M * s + Mat4 operator / (Real s) const; // M / s + + // Initialisers + + Void MakeZero(); // Zero matrix + Void MakeDiag(Real k = vl_one); // I + Void MakeBlock(Real k = vl_one); // all elts = k + + // Homogeneous Transforms + + Mat4& MakeHRot(const Vec3 &axis, Real theta); + // Rotate by theta radians about axis + Mat4& MakeHRot(const Vec4 &q); // Rotate by quaternion + Mat4& MakeHScale(const Vec3 &s); // Scale by components of s + + Mat4& MakeHTrans(const Vec3 &t); // Translation by t + + Mat4& Transpose(); // transpose in place + Mat4& AddShift(const Vec3 &t); // Concatenate shift + + // Private... + +protected: + + Vec4 row[4]; +}; + + +// --- Matrix operators ------------------------------------------------------- + +Vec4 operator * (const Mat4 &m, const Vec4 &v); // m * v +Vec4 operator * (const Vec4 &v, const Mat4 &m); // v * m +Vec4 &operator *= (Vec4 &a, const Mat4 &m); // v *= m +inline Mat4 operator * (Real s, const Mat4 &m); // s * m + +Mat4 trans(const Mat4 &m); // Transpose +Real trace(const Mat4 &m); // Trace +Mat4 adj(const Mat4 &m); // Adjoint +Real det(const Mat4 &m); // Determinant +Mat4 inv(const Mat4 &m); // Inverse +Mat4 oprod(const Vec4 &a, const Vec4 &b); + // Outer product + +// The xform functions help avoid dependence on whether row or column +// vectors are used to represent points and vectors. +inline Vec4 xform(const Mat4 &m, const Vec4 &v); // Transform of v by m +inline Vec3 xform(const Mat4 &m, const Vec3 &v); // Hom. xform of v by m +inline Mat4 xform(const Mat4 &m, const Mat4 &n); // Xform v -> m(n(v)) + +std::ostream &operator << (std::ostream &s, const Mat4 &m); +std::istream &operator >> (std::istream &s, Mat4 &m); + + +// --- Inlines ---------------------------------------------------------------- + +inline Mat4::Mat4() +{ +} + +inline Vec4 &Mat4::operator [] (Int i) +{ + CheckRange(i, 0, 4, "(Mat4::[i]) index out of range"); + return(row[i]); +} + +inline const Vec4 &Mat4::operator [] (Int i) const +{ + CheckRange(i, 0, 4, "(Mat4::[i]) index out of range"); + return(row[i]); +} + +inline Real *Mat4::Ref() const +{ + return((Real *) row); +} + +inline Mat4::Mat4(ZeroOrOne k) +{ + MakeDiag(k); +} + +inline Mat4::Mat4(Block k) +{ + MakeBlock((ZeroOrOne) k); +} + +inline Mat4 &Mat4::operator = (ZeroOrOne k) +{ + MakeDiag(k); + + return(SELF); +} + +inline Mat4 &Mat4::operator = (Block k) +{ + MakeBlock((ZeroOrOne) k); + + return(SELF); +} + +inline Mat4 operator * (Real s, const Mat4 &m) +{ + return(m * s); +} + +#ifdef VL_ROW_ORIENT +inline Vec3 xform(const Mat4 &m, const Vec3 &v) +{ return(proj(Vec4(v, 1.0) * m)); } +inline Vec4 xform(const Mat4 &m, const Vec4 &v) +{ return(v * m); } +inline Mat4 xform(const Mat4 &m, const Mat4 &n) +{ return(n * m); } +#else +inline Vec3 xform(const Mat4 &m, const Vec3 &v) +{ return(proj(m * Vec4(v, 1.0))); } +inline Vec4 xform(const Mat4 &m, const Vec4 &v) +{ return(m * v); } +inline Mat4 xform(const Mat4 &m, const Mat4 &n) +{ return(m * n); } +#endif + +#endif diff --git a/examples/cpp/lib/svl/README b/examples/cpp/lib/svl/README new file mode 100644 index 0000000000000000000000000000000000000000..b9435663a6065d9682a7d7da01028d97c7f79ce5 --- /dev/null +++ b/examples/cpp/lib/svl/README @@ -0,0 +1,94 @@ +Contents + + The SVL vector & matrix package, version 1.5. + + SVL provides 2-, 3- and 4-vector and matrix types, as well as + arbitrarily-sized vectors and matrices, and various useful functions + and arithmetic operators. + + SVL is free for commercial and non-commercial use; see the LICENSE file + for redistribution conditions. (These apply only to the source code. + Binaries may be freely redistributed, no strings attached.) + +Author + + Andrew Willmott, ajw+svl@cs.cmu.edu + Please send me any suggestions/comments/bug fixes you have. + +History + + Briefly: SVL, and its more complex cousin, VL, have their roots in + an attempt replace the various (inevitably heavily-macroized) + vector/matrix packages used by the members of the CMU graphics group + with a single C++ one, so that people could share code more easily. + SVL makes heavy use of inlines to achieve performance equal to that + of the C macros and functions it replaced. + +To Make + + Running 'make' with no arguments will list possible architectures to + compile for. The makefiles should work with most makes that have the + include directive, but try using gmake if something goes wrong. + + If your architecture is not listed, copy and then modify the config file + in the makefiles directory that's closest to what you need. + + To install, set the DEST variable appropriately and 'make install'. + DEST defaults to /usr/local. + + E.g., to install into /usr on a linux machine: + make DEST=/usr linux install + from this directory. + +To Use + + #include svl/SVL.h, and link with -lsvl. To use in debug mode, add the + switch "-DVL_DEBUG" to your compile line, and link with -lsvl.dbg. See + the documentation for more information. + +Documentation + + Run your favourite web browser with file:doc/svl.html + +Changes + + 1.4 Fixed problem with SVLgl.h -- had some wrappers for OpenGL calls that + don't actually exist(!) + Fixed bad memory problem with Mat::SetSize + Makefile for OSX, split sunos/solaris + + 1.3.2 Fixed minor MSVC warnings + Added windows packaging + 1.3.1 Sunday 11/03/01 + Reordered initializers, eliminated signed/unsigned comparisons + Fixed make clean problem + Irix CC is warning that 'Mat2::*' is being called before its inline + definition, but appears to be on crack as the inline '*' is + defined before the xform() that calls it. + Fixed afs-lib dependency for afs build + 1.3 Sunday 11/03/01 + Split off from VL 1.3. All VL-dependent code and type + parameterization macros removed to make code more understandable. + Fix for the C++ "standard" no longer allowing stack temporaries to + be passes as non-const refs. (Fixing this for VL requires more + significant changes, so it's proved easier to fork SVL at this + point for the sake of simplicity.) + Renamed files, general cleanups. + Added ">>" operators for Vec and Mat. + Disallowed resize of a vector reference. (This caused more bugs + than it was worth.) + Removed all asserts checking that the return value of 'new' is + not zero. The C++ "standard" has been changed so that new + instead throws an exception in this situation. + Added option to use memcpy for general vector copies: VL_USE_MEMCPY. + It seems that nowadays, on Intel processors at least, using + memcpy is faster than loops for most cases. See note in Vec.cc. + Changed the packaging to match the current vl/gcl scheme. + Updated afs-setup rule to ensure SVLConfig.h winds up in the + architecture-dependent lib directory. + 1.2 Release to match VL 1.2. + 1.1.3 Fixed some windows compile issues under VC++. + 1.1.2 Added comments about the Real, Vec, etc. types to VL.h + 1.1.1 Fixed problem with += operators and gcc under linux. + 1.1 Added oprod operator, irix n32 CC support, changed makefiles & afs + support, eliminated most g++ warnings. \ No newline at end of file diff --git a/examples/cpp/lib/svl/SVL.h b/examples/cpp/lib/svl/SVL.h new file mode 100644 index 0000000000000000000000000000000000000000..5f2f6435d3582b82eeb38ce5512b0ec270bbc228 --- /dev/null +++ b/examples/cpp/lib/svl/SVL.h @@ -0,0 +1,43 @@ +/* + File: SVL.h + + Function: Master header for a simple version of the VL library. + The various classes are named Vec2, Mat3, Vec, etc. + Link with -lsvl, or define the symbol VL_DEBUG and + link with -lsvl.dbg for the debugging version. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott + */ + + +#ifndef __SVL__ +#define __SVL__ + +#define SVL_VERSION "1.5" +#define SVL_VER_NUM 10500 + +#ifdef VL_DEBUG +#define VL_CHECKING +#endif + +#include <iostream> + +#include "svl/Basics.h" +#include "svl/Constants.h" +#include "svl/Utils.h" + +#include "svl/Vec2.h" +#include "svl/Vec3.h" +#include "svl/Vec4.h" +#include "svl/Vec.h" + +#include "svl/Mat2.h" +#include "svl/Mat3.h" +#include "svl/Mat4.h" +#include "svl/Mat.h" + +#include "svl/Transform.h" + +#endif diff --git a/examples/cpp/lib/svl/Transform.h b/examples/cpp/lib/svl/Transform.h new file mode 100644 index 0000000000000000000000000000000000000000..d40f329f12c3ef4819e8ea360eef9bd8fa776fa3 --- /dev/null +++ b/examples/cpp/lib/svl/Transform.h @@ -0,0 +1,41 @@ +/* + File: Transform.h + + Function: Provides transformation constructors. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott +*/ + +#ifndef __SVL_TRANSFORM__ +#define __SVL_TRANSFORM__ + +inline Mat2 Rot2(Real theta) + { Mat2 result; result.MakeRot(theta); return(result); } +inline Mat2 Scale2(const Vec2 &s) + { Mat2 result; result.MakeScale(s); return(result); } + +inline Mat3 Rot3(const Vec3 &axis, Real theta) + { Mat3 result; result.MakeRot(axis, theta); return(result); } +inline Mat3 Rot3(const Vec4 &q) + { Mat3 result; result.MakeRot(q); return(result); } +inline Mat3 Scale3(const Vec3 &s) + { Mat3 result; result.MakeScale(s); return(result); } +inline Mat3 HRot3(Real theta) + { Mat3 result; result.MakeHRot(theta); return(result); } +inline Mat3 HScale3(const Vec2 &s) + { Mat3 result; result.MakeHScale(s); return(result); } +inline Mat3 HTrans3(const Vec2 &t) + { Mat3 result; result.MakeHTrans(t); return(result); } + +inline Mat4 HRot4(const Vec3 &axis, Real theta) + { Mat4 result; result.MakeHRot(axis, theta); return(result); } +inline Mat4 HRot4(const Vec4 &q) + { Mat4 result; result.MakeHRot(q); return(result); } +inline Mat4 HScale4(const Vec3 &s) + { Mat4 result; result.MakeHScale(s); return(result); } +inline Mat4 HTrans4(const Vec3 &t) + { Mat4 result; result.MakeHTrans(t); return(result); } + +#endif diff --git a/examples/cpp/lib/svl/Utils.h b/examples/cpp/lib/svl/Utils.h new file mode 100644 index 0000000000000000000000000000000000000000..803332817b15e60df0227ffc22b45a10c914f944 --- /dev/null +++ b/examples/cpp/lib/svl/Utils.h @@ -0,0 +1,85 @@ +/* + File: Utils.h + + Function: Various math definitions for VL + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott + */ + +#ifndef __VL_MATH__ +#define __VL_MATH__ + +#include <cstdlib> + +// --- Inlines ---------------------------------------------------------------- + +// additions to arithmetic functions + +#ifdef VL_HAS_IEEEFP +#include <ieeefp.h> +#define vl_is_finite(X) finite(X) +#elif defined (__GNUC__) && defined(__USE_MISC) +#define vl_is_finite(X) finite(X) +#else +#define vl_is_finite(X) (1) +#endif + +#ifdef VL_HAS_DRAND +inline Double vl_rand() +{ return(drand48()); } +#else +#ifndef RAND_MAX +// we're on something totally sucky, like SunOS +#define RAND_MAX (Double(1 << 30) * 4.0 - 1.0) +#endif +inline Double vl_rand() +{ return(rand() / (RAND_MAX + 1.0)); } +#endif + +#ifndef __CMATH__ +// GNU's complex.h defines its own abs(double) +#ifdef VL_HAS_ABSF +inline Float abs(Float x) +{ return (fabsf(x)); } +#endif +inline Double abs(Double x) +{ return (fabs(x)); } +#endif +#ifdef VL_HAS_ABSF +inline Float len(Float x) +{ return (fabsf(x)); } +#endif +inline Double len(Double x) +{ return (fabs(x)); } + +inline Float sqrlen(Float r) +{ return(sqr(r)); } +inline Double sqrlen(Double r) +{ return(sqr(r)); } + +inline Float mix(Float a, Float b, Float s) +{ return((1.0f - s) * a + s * b); } +inline Double mix(Double a, Double b, Double s) +{ return((1.0 - s) * a + s * b); } + +inline Double sign(Double d) +{ + if (d < 0) + return(-1.0); + else + return(1.0); +} + +// useful routines + +inline Bool IsPowerOfTwo(Int a) +{ return((a & -a) == a); }; + +inline Void SetReal(Float &a, Double b) +{ a = Float(b); } +inline Void SetReal(Double &a, Double b) +{ a = b; } + +#endif diff --git a/examples/cpp/lib/svl/Vec.h b/examples/cpp/lib/svl/Vec.h new file mode 100644 index 0000000000000000000000000000000000000000..faef974e0fc389014e32d20a48d7d08f470411c2 --- /dev/null +++ b/examples/cpp/lib/svl/Vec.h @@ -0,0 +1,237 @@ +/* + File: Vec.h + + Function: Defines a generic resizeable vector. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott + */ + +#ifndef __Vec__ +#define __Vec__ + +class Vec2; +class Vec3; +class Vec4; + + +// --- Vec Class -------------------------------------------------------------- + +class Vec +{ +public: + + // Constructors + + Vec(); // Null vector + explicit Vec(Int n); // n-element vector + Vec(Int n, double elt0, ...); // e.g. Vec(3, 1.1, 2.0, 3.4) + Vec(Int n, Real *data); // Vector reference + Vec(const Vec &v); // Copy constructor + Vec(const Vec2 &v); // reference to a Vec2 + Vec(const Vec3 &v); // reference to a Vec3 + Vec(const Vec4 &v); // reference to a Vec4 + Vec(Int n, ZeroOrOne); // Zero or all-ones vector + Vec(Int n, Axis a); // Unit vector + ~Vec(); // Destructor + + // Accessor functions + + Int Elts() const; + + Real &operator [] (Int i); + Real operator [] (Int i) const; + + Void SetSize(Int n); // Resize the vector + Real *Ref() const; // Return pointer to data + + // Assignment operators + + Vec &operator = (const Vec &v); // v = a etc. + Vec &operator = (ZeroOrOne k); + Vec &operator = (Axis a); + Vec &operator = (const Vec2 &v); + Vec &operator = (const Vec3 &v); + Vec &operator = (const Vec4 &v); + + // In-Place operators + + Vec &operator += (const Vec &v); + Vec &operator -= (const Vec &v); + Vec &operator *= (const Vec &v); + Vec &operator *= (Real s); + Vec &operator /= (const Vec &v); + Vec &operator /= (Real s); + + // Vector initialisers + + Vec &MakeZero(); + Vec &MakeUnit(Int i, Real k = vl_one); + Vec &MakeBlock(Real k = vl_one); + + Vec &Normalise(); // Normalise vector + Vec &Clamp(Real fuzz); + Vec &Clamp(); + + Bool IsRef() const { return((elts & VL_REF_FLAG) != 0); }; + + // Private... + +protected: + + Real *data; + UInt elts; +}; + + +// --- Vec Comparison Operators ----------------------------------------------- + +Bool operator == (const Vec &a, const Vec &b); +Bool operator != (const Vec &a, const Vec &b); + + +// --- Vec Arithmetic Operators ----------------------------------------------- + +Vec operator + (const Vec &a, const Vec &b); +Vec operator - (const Vec &a, const Vec &b); +Vec operator - (const Vec &v); +Vec operator * (const Vec &a, const Vec &b); +Vec operator * (const Vec &v, Real s); +Vec operator / (const Vec &a, const Vec &b); +Vec operator / (const Vec &v, Real s); +Vec operator * (Real s, const Vec &v); + +Real dot(const Vec &a, const Vec &b);// v . a +inline Real len(const Vec &v); // || v || +inline Real sqrlen(const Vec &v); // v . v +inline Vec norm(const Vec &v); // v / || v || +inline Void normalise(Vec &v); // v = norm(v) + +Vec clamped(const Vec &v, Real fuzz); +Vec clamped(const Vec &v); + + +// --- Vec Input & Output ----------------------------------------------------- + +std::ostream &operator << (std::ostream &s, const Vec &v); +std::istream &operator >> (std::istream &s, Vec &v); + + +// --- Sub-vector functions --------------------------------------------------- + +inline Vec sub(const Vec &v, Int start, Int length); +inline Vec first(const Vec &v, Int length); +inline Vec last(const Vec &v, Int length); + + +// --- Vec inlines ------------------------------------------------------------ + +inline Vec::Vec() : data(0), elts(0) +{ +} + +inline Vec::Vec(Int n) : elts(n) +{ + Assert(n > 0,"(Vec) illegal vector size"); + + data = new Real[n]; +} + +inline Vec::Vec(Int n, Real *data) : data(data), elts(n | VL_REF_FLAG) +{ +} + +inline Int Vec::Elts() const +{ + return(elts & VL_REF_MASK); +} + +inline Real &Vec::operator [] (Int i) +{ + CheckRange(i, 0, Elts(), "Vec::[i]"); + + return(data[i]); +} + +inline Real Vec::operator [] (Int i) const +{ + CheckRange(i, 0, Elts(), "Vec::[i]"); + + return(data[i]); +} + +inline Real *Vec::Ref() const +{ + return(data); +} + +inline Vec &Vec::operator = (ZeroOrOne k) +{ + MakeBlock(k); + + return(SELF); +} + +inline Vec &Vec::operator = (Axis a) +{ + MakeUnit(a); + + return(SELF); +} + +inline Real len(const Vec &v) +{ + return(sqrt(dot(v, v))); +} + +inline Real sqrlen(const Vec &v) +{ + return(dot(v, v)); +} + +inline Vec norm(const Vec &v) +{ + Assert(sqrlen(v) > 0.0, "normalising length-zero vector"); + return(v / len(v)); +} + +inline Void normalise(Vec &v) +{ + v /= len(v); +} + +inline Vec sub(const Vec &v, Int start, Int length) +{ + Assert(start >= 0 && length > 0 && start + length <= v.Elts(), + "(sub(Vec)) illegal subset of vector"); + + return(Vec(length, v.Ref() + start)); +} + +inline Vec first(const Vec &v, Int length) +{ + Assert(length > 0 && length <= v.Elts(), + "(first(Vec)) illegal subset of vector"); + + return(Vec(length, v.Ref())); +} + +inline Vec last(const Vec &v, Int length) +{ + Assert(length > 0 && length <= v.Elts(), + "(last(Vec)) illegal subset of vector"); + + return(Vec(length, v.Ref() + v.Elts() - length)); +} + +inline Vec &Vec::Normalise() +{ + Assert(sqrlen(SELF) > 0.0, "normalising length-zero vector"); + SELF /= len(SELF); + return(SELF); +} + + +#endif + diff --git a/examples/cpp/lib/svl/Vec2.h b/examples/cpp/lib/svl/Vec2.h new file mode 100644 index 0000000000000000000000000000000000000000..10eac08a3f150cab612e031526e12e6df8205a6d --- /dev/null +++ b/examples/cpp/lib/svl/Vec2.h @@ -0,0 +1,364 @@ +/* + File: Vec2.h + + Function: Defines a length-2 vector. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott + */ + +#ifndef __Vec2__ +#define __Vec2__ + + +// --- Vec2 Class ------------------------------------------------------------- + + +class Vec2 +{ +public: + + // Constructors + + Vec2(); + Vec2(Real x, Real y); // (x, y) + Vec2(const Vec2 &v); // Copy constructor + Vec2(ZeroOrOne k); // v[i] = vl_zero + Vec2(Axis k); // v[k] = 1 + + // Accessor functions + + Real &operator [] (Int i); + const Real &operator [] (Int i) const; + + Int Elts() const { return(2); }; + Real *Ref() const; // Return ptr to data + + // Assignment operators + + Vec2 &operator = (const Vec2 &a); + Vec2 &operator = (ZeroOrOne k); + Vec2 &operator = (Axis k); + + Vec2 &operator += (const Vec2 &a); + Vec2 &operator -= (const Vec2 &a); + Vec2 &operator *= (const Vec2 &a); + Vec2 &operator *= (Real s); + Vec2 &operator /= (const Vec2 &a); + Vec2 &operator /= (Real s); + + // Comparison operators + + Bool operator == (const Vec2 &a) const; // v == a? + Bool operator != (const Vec2 &a) const; // v != a? + + // Arithmetic operators + + Vec2 operator + (const Vec2 &a) const; // v + a + Vec2 operator - (const Vec2 &a) const; // v - a + Vec2 operator - () const; // -v + Vec2 operator * (const Vec2 &a) const; // v * a (vx * ax, ...) + Vec2 operator * (Real s) const; // v * s + Vec2 operator / (const Vec2 &a) const; // v / a (vx / ax, ...) + Vec2 operator / (Real s) const; // v / s + + // Initialisers + + Vec2 &MakeZero(); // Zero vector + Vec2 &MakeUnit(Int i, Real k = vl_one); // I[i] + Vec2 &MakeBlock(Real k = vl_one); // All-k vector + + Vec2 &Normalise(); // normalise vector + + // Private... + +protected: + + Real elt[2]; +}; + + +// --- Vec operators ---------------------------------------------------------- + +inline Vec2 operator * (Real s, const Vec2 &v); // s * v +inline Real dot(const Vec2 &a, const Vec2 &b); // v . a +inline Real len(const Vec2 &v); // || v || +inline Real sqrlen(const Vec2 &v); // v . v +inline Vec2 norm(const Vec2 &v); // v / || v || +inline Void normalise(Vec2 &v); // v = norm(v) +inline Vec2 cross(const Vec2 &v); // cross prod. + +std::ostream &operator << (std::ostream &s, const Vec2 &v); +std::istream &operator >> (std::istream &s, Vec2 &v); + + +// --- Inlines ---------------------------------------------------------------- + +inline Real &Vec2::operator [] (Int i) +{ + CheckRange(i, 0, 2, "(Vec2::[i]) index out of range"); + return(elt[i]); +} + +inline const Real &Vec2::operator [] (Int i) const +{ + CheckRange(i, 0, 2, "(Vec2::[i]) index out of range"); + return(elt[i]); +} + +inline Vec2::Vec2() +{ +} + +inline Vec2::Vec2(Real x, Real y) +{ + elt[0] = x; + elt[1] = y; +} + +inline Vec2::Vec2(const Vec2 &v) +{ + elt[0] = v[0]; + elt[1] = v[1]; +} + +inline Real *Vec2::Ref() const +{ + return((Real *) elt); +} + +inline Vec2 &Vec2::operator = (const Vec2 &v) +{ + elt[0] = v[0]; + elt[1] = v[1]; + + return(SELF); +} + +inline Vec2 &Vec2::operator += (const Vec2 &v) +{ + elt[0] += v[0]; + elt[1] += v[1]; + + return(SELF); +} + +inline Vec2 &Vec2::operator -= (const Vec2 &v) +{ + elt[0] -= v[0]; + elt[1] -= v[1]; + + return(SELF); +} + +inline Vec2 &Vec2::operator *= (const Vec2 &v) +{ + elt[0] *= v[0]; + elt[1] *= v[1]; + + return(SELF); +} + +inline Vec2 &Vec2::operator *= (Real s) +{ + elt[0] *= s; + elt[1] *= s; + + return(SELF); +} + +inline Vec2 &Vec2::operator /= (const Vec2 &v) +{ + elt[0] /= v[0]; + elt[1] /= v[1]; + + return(SELF); +} + +inline Vec2 &Vec2::operator /= (Real s) +{ + elt[0] /= s; + elt[1] /= s; + + return(SELF); +} + +inline Vec2 Vec2::operator + (const Vec2 &a) const +{ + Vec2 result; + + result[0] = elt[0] + a[0]; + result[1] = elt[1] + a[1]; + + return(result); +} + +inline Vec2 Vec2::operator - (const Vec2 &a) const +{ + Vec2 result; + + result[0] = elt[0] - a[0]; + result[1] = elt[1] - a[1]; + + return(result); +} + +inline Vec2 Vec2::operator - () const +{ + Vec2 result; + + result[0] = -elt[0]; + result[1] = -elt[1]; + + return(result); +} + +inline Vec2 Vec2::operator * (const Vec2 &a) const +{ + Vec2 result; + + result[0] = elt[0] * a[0]; + result[1] = elt[1] * a[1]; + + return(result); +} + +inline Vec2 Vec2::operator * (Real s) const +{ + Vec2 result; + + result[0] = elt[0] * s; + result[1] = elt[1] * s; + + return(result); +} + +inline Vec2 operator * (Real s, const Vec2 &v) +{ + return(v * s); +} + +inline Vec2 Vec2::operator / (const Vec2 &a) const +{ + Vec2 result; + + result[0] = elt[0] / a[0]; + result[1] = elt[1] / a[1]; + + return(result); +} + +inline Vec2 Vec2::operator / (Real s) const +{ + Vec2 result; + + result[0] = elt[0] / s; + result[1] = elt[1] / s; + + return(result); +} + +inline Real dot(const Vec2 &a, const Vec2 &b) +{ + return(a[0] * b[0] + a[1] * b[1]); +} + +inline Vec2 cross(const Vec2 &a) +{ + Vec2 result; + + result[0] = a[1]; + result[1] = -a[0]; + + return(result); +} + +inline Real len(const Vec2 &v) +{ + return(sqrt(dot(v, v))); +} + +inline Real sqrlen(const Vec2 &v) +{ + return(dot(v, v)); +} + +inline Vec2 norm(const Vec2 &v) +{ + Assert(sqrlen(v) > 0.0, "normalising length-zero vector"); + return(v / len(v)); +} + +inline Void normalise(Vec2 &v) +{ + v /= len(v); +} + +inline Vec2 &Vec2::MakeUnit(Int i, Real k) +{ + if (i == 0) + { elt[0] = k; elt[1] = vl_zero; } + else if (i == 1) + { elt[0] = vl_zero; elt[1] = k; } + else + _Error("(Vec2::Unit) illegal unit vector"); + return(SELF); +} + +inline Vec2 &Vec2::MakeZero() +{ + elt[0] = vl_zero; elt[1] = vl_zero; + return(SELF); +} + +inline Vec2 &Vec2::MakeBlock(Real k) +{ + elt[0] = k; elt[1] = k; + return(SELF); +} + +inline Vec2 &Vec2::Normalise() +{ + Assert(sqrlen(SELF) > 0.0, "normalising length-zero vector"); + SELF /= len(SELF); + return(SELF); +} + + +inline Vec2::Vec2(ZeroOrOne k) +{ + elt[0] = k; + elt[1] = k; +} + +inline Vec2::Vec2(Axis k) +{ + MakeUnit(k, vl_one); +} + +inline Vec2 &Vec2::operator = (ZeroOrOne k) +{ + elt[0] = k; elt[1] = k; + + return(SELF); +} + +inline Vec2 &Vec2::operator = (Axis k) +{ + MakeUnit(k, vl_1); + + return(SELF); +} + +inline Bool Vec2::operator == (const Vec2 &a) const +{ + return(elt[0] == a[0] && elt[1] == a[1]); +} + +inline Bool Vec2::operator != (const Vec2 &a) const +{ + return(elt[0] != a[0] || elt[1] != a[1]); +} + +#endif diff --git a/examples/cpp/lib/svl/Vec3.h b/examples/cpp/lib/svl/Vec3.h new file mode 100644 index 0000000000000000000000000000000000000000..7a9b64f0477c272b952c2ee21752292bb52f2778 --- /dev/null +++ b/examples/cpp/lib/svl/Vec3.h @@ -0,0 +1,414 @@ +/* + File: Vec3.h + + Function: Defines a length-3 vector. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott + */ + +#ifndef __Vec3__ +#define __Vec3__ + +#include "svl/Vec2.h" + + +// --- Vec3 Class ------------------------------------------------------------- + +class Vec3 +{ +public: + + // Constructors + + Vec3(); + Vec3(Real x, Real y, Real z); // [x, y, z] + Vec3(const Vec3 &v); // Copy constructor + Vec3(const Vec2 &v, Real w); // Hom. 2D vector + Vec3(ZeroOrOne k); + Vec3(Axis a); + + // Accessor functions + + Int Elts() const { return(3); }; + + Real &operator [] (Int i); + const Real &operator [] (Int i) const; + + Real *Ref() const; // Return pointer to data + + // Assignment operators + + Vec3 &operator = (const Vec3 &a); + Vec3 &operator = (ZeroOrOne k); + Vec3 &operator += (const Vec3 &a); + Vec3 &operator -= (const Vec3 &a); + Vec3 &operator *= (const Vec3 &a); + Vec3 &operator *= (Real s); + Vec3 &operator /= (const Vec3 &a); + Vec3 &operator /= (Real s); + + // Comparison operators + + Bool operator == (const Vec3 &a) const; // v == a? + Bool operator != (const Vec3 &a) const; // v != a? + Bool operator < (const Vec3 &a) const; // v < a? + Bool operator >= (const Vec3 &a) const; // v >= a? + + // Arithmetic operators + + Vec3 operator + (const Vec3 &a) const; // v + a + Vec3 operator - (const Vec3 &a) const; // v - a + Vec3 operator - () const; // -v + Vec3 operator * (const Vec3 &a) const; // v * a (vx * ax, ...) + Vec3 operator * (Real s) const; // v * s + Vec3 operator / (const Vec3 &a) const; // v / a (vx / ax, ...) + Vec3 operator / (Real s) const; // v / s + + // Initialisers + + Vec3 &MakeZero(); // Zero vector + Vec3 &MakeUnit(Int i, Real k = vl_one); // I[i] + Vec3 &MakeBlock(Real k = vl_one); // All-k vector + + Vec3 &Normalise(); // normalise vector + + // Private... + +protected: + + Real elt[3]; +}; + + +// --- Vec operators ---------------------------------------------------------- + +inline Vec3 operator * (Real s, const Vec3 &v); // s * v +inline Real dot(const Vec3 &a, const Vec3 &b); // v . a +inline Real len(const Vec3 &v); // || v || +inline Real sqrlen(const Vec3 &v); // v . v +inline Vec3 norm(const Vec3 &v); // v / || v || +inline Void normalise(Vec3 &v); // v = norm(v) +inline Vec3 cross(const Vec3 &a, const Vec3 &b);// a x b +inline Vec2 proj(const Vec3 &v); // hom. projection + +std::ostream &operator << (std::ostream &s, const Vec3 &v); +std::istream &operator >> (std::istream &s, Vec3 &v); + + +// --- Inlines ---------------------------------------------------------------- + +inline Real &Vec3::operator [] (Int i) +{ + CheckRange(i, 0, 3, "(Vec3::[i]) index out of range"); + return(elt[i]); +} + +inline const Real &Vec3::operator [] (Int i) const +{ + CheckRange(i, 0, 3, "(Vec3::[i]) index out of range"); + return(elt[i]); +} + +inline Vec3::Vec3() +{ +} + +inline Vec3::Vec3(Real x, Real y, Real z) +{ + elt[0] = x; + elt[1] = y; + elt[2] = z; +} + +inline Vec3::Vec3(const Vec3 &v) +{ + elt[0] = v[0]; + elt[1] = v[1]; + elt[2] = v[2]; +} + +inline Vec3::Vec3(const Vec2 &v, Real w) +{ + elt[0] = v[0]; + elt[1] = v[1]; + elt[2] = w; +} + +inline Real *Vec3::Ref() const +{ + return((Real *) elt); +} + +inline Vec3 &Vec3::operator = (const Vec3 &v) +{ + elt[0] = v[0]; + elt[1] = v[1]; + elt[2] = v[2]; + + return(SELF); +} + +inline Vec3 &Vec3::operator += (const Vec3 &v) +{ + elt[0] += v[0]; + elt[1] += v[1]; + elt[2] += v[2]; + + return(SELF); +} + +inline Vec3 &Vec3::operator -= (const Vec3 &v) +{ + elt[0] -= v[0]; + elt[1] -= v[1]; + elt[2] -= v[2]; + + return(SELF); +} + +inline Vec3 &Vec3::operator *= (const Vec3 &a) +{ + elt[0] *= a[0]; + elt[1] *= a[1]; + elt[2] *= a[2]; + + return(SELF); +} + +inline Vec3 &Vec3::operator *= (Real s) +{ + elt[0] *= s; + elt[1] *= s; + elt[2] *= s; + + return(SELF); +} + +inline Vec3 &Vec3::operator /= (const Vec3 &a) +{ + elt[0] /= a[0]; + elt[1] /= a[1]; + elt[2] /= a[2]; + + return(SELF); +} + +inline Vec3 &Vec3::operator /= (Real s) +{ + elt[0] /= s; + elt[1] /= s; + elt[2] /= s; + + return(SELF); +} + +inline Vec3 Vec3::operator + (const Vec3 &a) const +{ + Vec3 result; + + result[0] = elt[0] + a[0]; + result[1] = elt[1] + a[1]; + result[2] = elt[2] + a[2]; + + return(result); +} + +inline Vec3 Vec3::operator - (const Vec3 &a) const +{ + Vec3 result; + + result[0] = elt[0] - a[0]; + result[1] = elt[1] - a[1]; + result[2] = elt[2] - a[2]; + + return(result); +} + +inline Vec3 Vec3::operator - () const +{ + Vec3 result; + + result[0] = -elt[0]; + result[1] = -elt[1]; + result[2] = -elt[2]; + + return(result); +} + +inline Vec3 Vec3::operator * (const Vec3 &a) const +{ + Vec3 result; + + result[0] = elt[0] * a[0]; + result[1] = elt[1] * a[1]; + result[2] = elt[2] * a[2]; + + return(result); +} + +inline Vec3 Vec3::operator * (Real s) const +{ + Vec3 result; + + result[0] = elt[0] * s; + result[1] = elt[1] * s; + result[2] = elt[2] * s; + + return(result); +} + +inline Vec3 Vec3::operator / (const Vec3 &a) const +{ + Vec3 result; + + result[0] = elt[0] / a[0]; + result[1] = elt[1] / a[1]; + result[2] = elt[2] / a[2]; + + return(result); +} + +inline Vec3 Vec3::operator / (Real s) const +{ + Vec3 result; + + result[0] = elt[0] / s; + result[1] = elt[1] / s; + result[2] = elt[2] / s; + + return(result); +} + +inline Vec3 operator * (Real s, const Vec3 &v) +{ + return(v * s); +} + +inline Vec3 &Vec3::MakeUnit(Int n, Real k) +{ + if (n == 0) + { elt[0] = k; elt[1] = vl_zero; elt[2] = vl_zero; } + else if (n == 1) + { elt[0] = vl_zero; elt[1] = k; elt[2] = vl_zero; } + else if (n == 2) + { elt[0] = vl_zero; elt[1] = vl_zero; elt[2] = k; } + else + _Error("(Vec3::Unit) illegal unit vector"); + + return(SELF); +} + +inline Vec3 &Vec3::MakeZero() +{ + elt[0] = vl_zero; elt[1] = vl_zero; elt[2] = vl_zero; + + return(SELF); +} + +inline Vec3 &Vec3::MakeBlock(Real k) +{ + elt[0] = k; elt[1] = k; elt[2] = k; + + return(SELF); +} + +inline Vec3 &Vec3::Normalise() +{ + Assert(sqrlen(SELF) > 0.0, "normalising length-zero vector"); + SELF /= len(SELF); + + return(SELF); +} + + +inline Vec3::Vec3(ZeroOrOne k) +{ + elt[0] = k; elt[1] = k; elt[2] = k; +} + +inline Vec3 &Vec3::operator = (ZeroOrOne k) +{ + elt[0] = k; elt[1] = k; elt[2] = k; + + return(SELF); +} + +inline Vec3::Vec3(Axis a) +{ + MakeUnit(a, vl_one); +} + + +inline Bool Vec3::operator == (const Vec3 &a) const +{ + return(elt[0] == a[0] && elt[1] == a[1] && elt[2] == a[2]); +} + +inline Bool Vec3::operator != (const Vec3 &a) const +{ + return(elt[0] != a[0] || elt[1] != a[1] || elt[2] != a[2]); +} + +inline Bool Vec3::operator < (const Vec3 &a) const +{ + return(elt[0] < a[0] && elt[1] < a[1] && elt[2] < a[2]); +} + +inline Bool Vec3::operator >= (const Vec3 &a) const +{ + return(elt[0] >= a[0] && elt[1] >= a[1] && elt[2] >= a[2]); +} + + +inline Real dot(const Vec3 &a, const Vec3 &b) +{ + return(a[0] * b[0] + a[1] * b[1] + a[2] * b[2]); +} + +inline Real len(const Vec3 &v) +{ + return(sqrt(dot(v, v))); +} + +inline Real sqrlen(const Vec3 &v) +{ + return(dot(v, v)); +} + +inline Vec3 norm(const Vec3 &v) +{ + Assert(sqrlen(v) > 0.0, "normalising length-zero vector"); + return(v / len(v)); +} + +inline Void normalise(Vec3 &v) +{ + v /= len(v); +} + +inline Vec3 cross(const Vec3 &a, const Vec3 &b) +{ + Vec3 result; + + result[0] = a[1] * b[2] - a[2] * b[1]; + result[1] = a[2] * b[0] - a[0] * b[2]; + result[2] = a[0] * b[1] - a[1] * b[0]; + + return(result); +} + +inline Vec2 proj(const Vec3 &v) +{ + Vec2 result; + + Assert(v[2] != 0, "(Vec3/proj) last elt. is zero"); + + result[0] = v[0] / v[2]; + result[1] = v[1] / v[2]; + + return(result); +} + +#endif diff --git a/examples/cpp/lib/svl/Vec4.h b/examples/cpp/lib/svl/Vec4.h new file mode 100644 index 0000000000000000000000000000000000000000..7586d675e543aeae2e6c663063d2efc3d08350f5 --- /dev/null +++ b/examples/cpp/lib/svl/Vec4.h @@ -0,0 +1,379 @@ +/* + File: Vec4.h + + Function: Defines a length-4 vector. + + Author(s): Andrew Willmott + + Copyright: (c) 1995-2001, Andrew Willmott + */ + +#ifndef __Vec4__ +#define __Vec4__ + +#include "svl/Vec3.h" + + +// --- Vec4 Class ------------------------------------------------------------- + +class Vec4 +{ +public: + + // Constructors + + Vec4(); + Vec4(Real x, Real y, Real z, Real w); // [x, y, z, w] + Vec4(const Vec4 &v); // Copy constructor + Vec4(const Vec3 &v, Real w); // Hom. 3D vector + Vec4(ZeroOrOne k); + Vec4(Axis k); + + // Accessor functions + + Int Elts() const { return(4); }; + + Real &operator [] (Int i); + const Real &operator [] (Int i) const; + + Real *Ref() const; // Return pointer to data + + // Assignment operators + + Vec4 &operator = (const Vec4 &a); + Vec4 &operator = (ZeroOrOne k); + Vec4 &operator = (Axis k); + Vec4 &operator += (const Vec4 &a); + Vec4 &operator -= (const Vec4 &a); + Vec4 &operator *= (const Vec4 &a); + Vec4 &operator *= (Real s); + Vec4 &operator /= (const Vec4 &a); + Vec4 &operator /= (Real s); + + // Comparison operators + + Bool operator == (const Vec4 &a) const; // v == a ? + Bool operator != (const Vec4 &a) const; // v != a ? + + // Arithmetic operators + + Vec4 operator + (const Vec4 &a) const; // v + a + Vec4 operator - (const Vec4 &a) const; // v - a + Vec4 operator - () const; // -v + Vec4 operator * (const Vec4 &a) const; // v * a (vx * ax, ...) + Vec4 operator * (Real s) const; // v * s + Vec4 operator / (const Vec4 &a) const; // v / a (vx / ax, ...) + Vec4 operator / (Real s) const; // v / s + + + // Initialisers + + Vec4 &MakeZero(); // Zero vector + Vec4 &MakeUnit(Int i, Real k = vl_one); // kI[i] + Vec4 &MakeBlock(Real k = vl_one); // All-k vector + + Vec4 &Normalise(); // normalise vector + + // Private... + +protected: + + Real elt[4]; +}; + + +// --- Vec operators ---------------------------------------------------------- + +inline Vec4 operator * (Real s, const Vec4 &v); // Left mult. by s +inline Real dot(const Vec4 &a, const Vec4 &b); // v . a +inline Real len(const Vec4 &v); // || v || +inline Real sqrlen(const Vec4 &v); // v . v +inline Vec4 norm(const Vec4 &v); // v / || v || +inline Void normalise(Vec4 &v); // v = norm(v) +Vec4 cross(const Vec4 &a, const Vec4 &b, const Vec4 &c); + // 4D cross prod. +Vec3 proj(const Vec4 &v); // hom. projection + +std::ostream &operator << (std::ostream &s, const Vec4 &v); +std::istream &operator >> (std::istream &s, Vec4 &v); + + +// --- Inlines ---------------------------------------------------------------- + +inline Real &Vec4::operator [] (Int i) +{ + CheckRange(i, 0, 4, "(Vec4::[i]) index out of range"); + return(elt[i]); +} + +inline const Real &Vec4::operator [] (Int i) const +{ + CheckRange(i, 0, 4, "(Vec4::[i]) index out of range"); + return(elt[i]); +} + + +inline Vec4::Vec4() +{ +} + +inline Vec4::Vec4(Real x, Real y, Real z, Real w) +{ + elt[0] = x; + elt[1] = y; + elt[2] = z; + elt[3] = w; +} + +inline Vec4::Vec4(const Vec4 &v) +{ + elt[0] = v[0]; + elt[1] = v[1]; + elt[2] = v[2]; + elt[3] = v[3]; +} + +inline Vec4::Vec4(const Vec3 &v, Real w) +{ + elt[0] = v[0]; + elt[1] = v[1]; + elt[2] = v[2]; + elt[3] = w; +} + +inline Real *Vec4::Ref() const +{ + return((Real *) elt); +} + +inline Vec4 &Vec4::operator = (const Vec4 &v) +{ + elt[0] = v[0]; + elt[1] = v[1]; + elt[2] = v[2]; + elt[3] = v[3]; + + return(SELF); +} + +inline Vec4 &Vec4::operator += (const Vec4 &v) +{ + elt[0] += v[0]; + elt[1] += v[1]; + elt[2] += v[2]; + elt[3] += v[3]; + + return(SELF); +} + +inline Vec4 &Vec4::operator -= (const Vec4 &v) +{ + elt[0] -= v[0]; + elt[1] -= v[1]; + elt[2] -= v[2]; + elt[3] -= v[3]; + + return(SELF); +} + +inline Vec4 &Vec4::operator *= (const Vec4 &v) +{ + elt[0] *= v[0]; + elt[1] *= v[1]; + elt[2] *= v[2]; + elt[3] *= v[3]; + + return(SELF); +} + +inline Vec4 &Vec4::operator *= (Real s) +{ + elt[0] *= s; + elt[1] *= s; + elt[2] *= s; + elt[3] *= s; + + return(SELF); +} + +inline Vec4 &Vec4::operator /= (const Vec4 &v) +{ + elt[0] /= v[0]; + elt[1] /= v[1]; + elt[2] /= v[2]; + elt[3] /= v[3]; + + return(SELF); +} + +inline Vec4 &Vec4::operator /= (Real s) +{ + elt[0] /= s; + elt[1] /= s; + elt[2] /= s; + elt[3] /= s; + + return(SELF); +} + + +inline Vec4 Vec4::operator + (const Vec4 &a) const +{ + Vec4 result; + + result[0] = elt[0] + a[0]; + result[1] = elt[1] + a[1]; + result[2] = elt[2] + a[2]; + result[3] = elt[3] + a[3]; + + return(result); +} + +inline Vec4 Vec4::operator - (const Vec4 &a) const +{ + Vec4 result; + + result[0] = elt[0] - a[0]; + result[1] = elt[1] - a[1]; + result[2] = elt[2] - a[2]; + result[3] = elt[3] - a[3]; + + return(result); +} + +inline Vec4 Vec4::operator - () const +{ + Vec4 result; + + result[0] = -elt[0]; + result[1] = -elt[1]; + result[2] = -elt[2]; + result[3] = -elt[3]; + + return(result); +} + +inline Vec4 Vec4::operator * (const Vec4 &a) const +{ + Vec4 result; + + result[0] = elt[0] * a[0]; + result[1] = elt[1] * a[1]; + result[2] = elt[2] * a[2]; + result[3] = elt[3] * a[3]; + + return(result); +} + +inline Vec4 Vec4::operator * (Real s) const +{ + Vec4 result; + + result[0] = elt[0] * s; + result[1] = elt[1] * s; + result[2] = elt[2] * s; + result[3] = elt[3] * s; + + return(result); +} + +inline Vec4 Vec4::operator / (const Vec4 &a) const +{ + Vec4 result; + + result[0] = elt[0] / a[0]; + result[1] = elt[1] / a[1]; + result[2] = elt[2] / a[2]; + result[3] = elt[3] / a[3]; + + return(result); +} + +inline Vec4 Vec4::operator / (Real s) const +{ + Vec4 result; + + result[0] = elt[0] / s; + result[1] = elt[1] / s; + result[2] = elt[2] / s; + result[3] = elt[3] / s; + + return(result); +} + +inline Vec4 operator * (Real s, const Vec4 &v) +{ + return(v * s); +} + +inline Vec4 &Vec4::MakeZero() +{ + elt[0] = vl_zero; elt[1] = vl_zero; elt[2] = vl_zero; elt[3] = vl_zero; + return(SELF); +} + +inline Vec4 &Vec4::MakeBlock(Real k) +{ + elt[0] = k; elt[1] = k; elt[2] = k; elt[3] = k; + return(SELF); +} + +inline Vec4 &Vec4::Normalise() +{ + Assert(sqrlen(SELF) > 0.0, "normalising length-zero vector"); + SELF /= len(SELF); + return(SELF); +} + +inline Vec4::Vec4(ZeroOrOne k) +{ + MakeBlock(k); +} + +inline Vec4::Vec4(Axis k) +{ + MakeUnit(k, vl_1); +} + +inline Vec4 &Vec4::operator = (ZeroOrOne k) +{ + MakeBlock(k); + + return(SELF); +} + +inline Vec4 &Vec4::operator = (Axis k) +{ + MakeUnit(k, vl_1); + + return(SELF); +} + + +inline Real dot(const Vec4 &a, const Vec4 &b) +{ + return(a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]); +} + +inline Real len(const Vec4 &v) +{ + return(sqrt(dot(v, v))); +} + +inline Real sqrlen(const Vec4 &v) +{ + return(dot(v, v)); +} + +inline Vec4 norm(const Vec4 &v) +{ + Assert(sqrlen(v) > 0.0, "normalising length-zero vector"); + return(v / len(v)); +} + +inline Void normalise(Vec4 &v) +{ + v /= len(v); +} + +#endif