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