00001 /*
00002 File: Vec.h
00003
00004 Function: Defines a generic resizeable vector.
00005
00006 Author(s): Andrew Willmott
00007
00008 Copyright: (c) 1995-2000, Andrew Willmott
00009 */
00010
00011 #ifndef __Vec__
00012 #define __Vec__
00013
00014 #include "vl/VL.h"
00015 // Defines the actual type for TVec etc.
00016
00017 #include "vl/Vec2.h"
00018 #include "vl/Vec3.h"
00019 #include "vl/Vec4.h"
00020 #ifndef __SVL__
00021 #include "vl/SubVec.h"
00022 #endif
00023 #include <iostream.h>
00024
00025
00026 // --- Vec Class --------------------------------------------------------------
00027
00028
00029 class TVec
00030 {
00031 public:
00032
00033 // Constructors
00034
00035 inline TVec(); // Null vector: space allocated later
00036 inline TVec(Int n);
00037 TVec(Int n, double elt0, ...); // Vec(3, 1.1, 2.0, 3.4)
00038 inline TVec(Int n, TVReal *data); // Vector pointer...
00039 TVec(const TVec &v); // Copy constructor
00040 #ifndef __SVL1__
00041 TVec(const TSubVec &v);
00042 #endif
00043 TVec(const TVec2 &v);
00044 TVec(const TVec3 &v);
00045 TVec(const TVec4 &v);
00046 TVec(Int n, ZeroOrOne); // Zero or all-ones vector
00047 TVec(Int n, Axis a); // Unit vector
00048
00049 ~TVec(); // Destructor
00050
00051 // Accessor functions
00052
00053 inline Int Elts() const;
00054
00055 inline TVReal &operator [] (Int i);
00056 inline TVReal operator [] (Int i) const;
00057
00058 inline TVReal *Ref() const; // Return pointer to data
00059
00060 // Assignment operators
00061
00062 TVec &operator = (const TVec &v); // v = a etc.
00063 #ifndef __SVL__
00064 TVec &operator = (const TSubVec &v);
00065 #endif
00066 TVec &operator = (ZeroOrOne k);
00067 TVec &operator = (Axis a);
00068 TVec &operator = (const TVec2 &v);
00069 TVec &operator = (const TVec3 &v);
00070 TVec &operator = (const TVec4 &v);
00071
00072 Void SetSize(Int n); // resize the vector
00073
00074 // Vector initialisers
00075
00076 TVec &MakeZero();
00077 TVec &MakeUnit(Int i, TVReal k = vl_one);
00078 TVec &MakeBlock(TVReal k = vl_one);
00079
00080 inline TVec &Normalise(); // normalise vector
00081 TVec &Clamp(Real fuzz);
00082 TVec &Clamp();
00083
00084 Bool IsRef() const { return(elts & VL_REF_FLAG); };
00085
00086 protected:
00087 TVReal *data;
00088 UInt32 elts;
00089 };
00090
00091
00092 // --- Vec In-Place operators -------------------------------------------------
00093
00094 TVec &operator += (TVec &a, const TVec &b);
00095 TVec &operator -= (TVec &a, const TVec &b);
00096 TVec &operator *= (TVec &a, const TVec &b);
00097 TVec &operator *= (TVec &v, TVReal s);
00098 TVec &operator /= (TVec &a, const TVec &b);
00099 TVec &operator /= (TVec &v, TVReal s);
00100
00101 // --- Vec Comparison Operators -----------------------------------------------
00102
00103 Bool operator == (const TVec &a, const TVec &b);
00104 Bool operator != (const TVec &a, const TVec &b);
00105
00106 // --- Vec Arithmetic Operators -----------------------------------------------
00107
00108 TVec operator + (const TVec &a, const TVec &b);
00109 TVec operator - (const TVec &a, const TVec &b);
00110 TVec operator - (const TVec &v);
00111 TVec operator * (const TVec &a, const TVec &b);
00112 TVec operator * (const TVec &v, TVReal s);
00113 TVec operator / (const TVec &a, const TVec &b);
00114 TVec operator / (const TVec &v, TVReal s);
00115 TVec operator * (TVReal s, const TVec &v);
00116
00117 TVReal dot(const TVec &a, const TVec &b); // v . a
00118 inline TVReal len(const TVec &v); // || v ||
00119 inline TVReal sqrlen(const TVec &v); // v . v
00120 inline TVec norm(const TVec &v); // v / || v ||
00121 inline Void normalise(TVec &v); // v = norm(v)
00122 TVec clamped(const TVec &v, Real fuzz);
00123 TVec clamped(const TVec &v);
00124
00125 // --- Vec Input & Output -----------------------------------------------------
00126
00127 ostream &operator << (ostream &s, const TVec &v);
00128 istream &operator >> (istream &s, TVec &v);
00129
00130 // --- Sub-vector functions ---------------------------------------------------
00131
00132 inline TVec sub(const TVec &v, Int start, Int length);
00133 inline TVec first(const TVec &v, Int length);
00134 inline TVec last(const TVec &v, Int length);
00135
00136
00137 // --- Vec inlines ------------------------------------------------------------
00138
00139
00140 inline TVec::TVec() : data(0), elts(0)
00141 {
00142 }
00143
00144 inline TVec::TVec(Int n) : elts(n)
00145 {
00146 Assert(n > 0,"(Vec) illegal vector size");
00147
00148 data = new TVReal[n];
00149 Assert(data != 0, "(Vec) Out of memory");
00150 }
00151
00152 inline TVec::TVec(Int n, TVReal *data) : data(data), elts(n | VL_REF_FLAG)
00153 {
00154 }
00155
00156 inline Int TVec::Elts() const
00157 {
00158 return(elts & VL_REF_MASK);
00159 }
00160
00161 inline TVReal &TVec::operator [] (Int i)
00162 {
00163 CheckRange(i, 0, Elts(), "Vec::[i]");
00164
00165 return(data[i]);
00166 }
00167
00168 inline TVReal TVec::operator [] (Int i) const
00169 {
00170 CheckRange(i, 0, Elts(), "Vec::[i]");
00171
00172 return(data[i]);
00173 }
00174
00175 inline TVReal *TVec::Ref() const
00176 {
00177 return(data);
00178 }
00179
00180 inline TVec &TVec::operator = (ZeroOrOne k)
00181 {
00182 MakeBlock(k);
00183
00184 return(SELF);
00185 }
00186
00187 inline TVec &TVec::operator = (Axis a)
00188 {
00189 MakeUnit(a);
00190
00191 return(SELF);
00192 }
00193
00194 inline TVReal len(const TVec &v)
00195 {
00196 return(sqrt(dot(v, v)));
00197 }
00198
00199 inline TVReal sqrlen(const TVec &v)
00200 {
00201 return(dot(v, v));
00202 }
00203
00204 inline TVec norm(const TVec &v)
00205 {
00206 Assert(sqrlen(v) > 0.0, "normalising length-zero vector");
00207 return(v / len(v));
00208 }
00209
00210 inline Void normalise(TVec &v)
00211 {
00212 v /= len(v);
00213 }
00214
00215 inline TVec sub(const TVec &v, Int start, Int length)
00216 {
00217 Assert(start >= 0 && length > 0 && start + length <= v.Elts(),
00218 "(sub(Vec)) illegal subset of vector");
00219
00220 return(TVec(length, v.Ref() + start));
00221 }
00222
00223 inline TVec first(const TVec &v, Int length)
00224 {
00225 Assert(length > 0 && length <= v.Elts(),
00226 "(first(Vec)) illegal subset of vector");
00227
00228 return(TVec(length, v.Ref()));
00229 }
00230
00231 inline TVec last(const TVec &v, Int length)
00232 {
00233 Assert(length > 0 && length <= v.Elts(),
00234 "(last(Vec)) illegal subset of vector");
00235
00236 return(TVec(length, v.Ref() + v.Elts() - length));
00237 }
00238
00239 inline TVec &TVec::Normalise()
00240 {
00241 Assert(sqrlen(SELF) > 0.0, "normalising length-zero vector");
00242 SELF /= len(SELF);
00243 return(SELF);
00244 }
00245
00246
00247 #endif
00248