00001 /* 00002 File: Vec.cc 00003 00004 Function: Implements Vec.h 00005 00006 Author(s): Andrew Willmott 00007 00008 Copyright: (c) 1995-2000, Andrew Willmott 00009 00010 Notes: 00011 00012 */ 00013 00014 00015 #include "vl/Vec.h" 00016 #ifndef __SVL__ 00017 #include "cl/Array.h" 00018 #endif 00019 00020 #include <iomanip.h> 00021 #include <string.h> 00022 #include <stdarg.h> 00023 00024 00025 // --- Vec Constructors ------------------------------------------------------- 00026 00027 00028 TVec::TVec(Int n, ZeroOrOne k) : elts(n) 00029 { 00030 Assert(n > 0,"(Vec) illegal vector size"); 00031 00032 data = new TVReal[n]; 00033 Assert(data != 0, "(Vec) Out of memory"); 00034 00035 MakeBlock(k); 00036 } 00037 00038 TVec::TVec(Int n, Axis a) : elts(n) 00039 { 00040 Assert(n > 0,"(Vec) illegal vector size"); 00041 00042 data = new TVReal[n]; 00043 Assert(data != 0, "(Vec) Out of memory"); 00044 00045 MakeUnit(a); 00046 } 00047 00048 TVec::TVec(const TVec &v) 00049 { 00050 Assert(v.data != 0, "(Vec) Can't construct from a null vector"); 00051 00052 elts = v.Elts(); 00053 data = new TVReal[elts]; 00054 Assert(data != 0, "(Vec) Out of memory"); 00055 // You might wonder why I don't use memcpy here and elsewhere. 00056 // Timing tests on an R4400 show memcpy only becomes faster for 00057 // n > 30 or so, and on an R10000, memcpy is never faster. Hence 00058 // I'm sticking with loop copies for now. 00059 for (Int i = 0; i < Elts(); i++) 00060 data[i] = v[i]; 00061 } 00062 00063 #ifndef __SVL1__ 00064 TVec::TVec(const TSubVec &v) : elts(v.Elts()) 00065 { 00066 data = new TVReal[elts]; 00067 Assert(data != 0, "(Vec) Out of memory"); 00068 00069 for (Int i = 0; i < Elts(); i++) 00070 data[i] = v[i]; 00071 } 00072 #endif 00073 00074 TVec::TVec(const TVec2 &v) : elts(v.Elts() | VL_REF_FLAG), data(v.Ref()) 00075 { 00076 } 00077 00078 TVec::TVec(const TVec3 &v) : elts(v.Elts() | VL_REF_FLAG), data(v.Ref()) 00079 { 00080 } 00081 00082 TVec::TVec(const TVec4 &v) : elts(v.Elts() | VL_REF_FLAG), data(v.Ref()) 00083 { 00084 } 00085 00086 TVec::TVec(Int n, double elt0, ...) : elts(n) 00087 { 00088 Assert(n > 0,"(Vec) illegal vector size"); 00089 00090 va_list ap; 00091 Int i = 1; 00092 00093 data = new TVReal[n]; 00094 00095 va_start(ap, elt0); 00096 00097 SetReal(data[0], elt0); 00098 00099 while (--n) 00100 SetReal(data[i++], va_arg(ap, double)); 00101 00102 va_end(ap); 00103 } 00104 00105 TVec::~TVec() 00106 { 00107 if (!IsRef()) 00108 delete[] data; 00109 } 00110 00111 00112 // --- Vec Assignment Operators ----------------------------------------------- 00113 00114 00115 TVec &TVec::operator = (const TVec &v) 00116 { 00117 if (!IsRef()) 00118 SetSize(v.Elts()); 00119 else 00120 Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match"); 00121 00122 for (Int i = 0; i < Elts(); i++) 00123 data[i] = v[i]; 00124 00125 return(SELF); 00126 } 00127 00128 #ifndef __SVL__ 00129 TVec &TVec::operator = (const TSubVec &v) 00130 { 00131 if (!IsRef()) 00132 SetSize(v.Elts()); 00133 else 00134 Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match"); 00135 00136 for (Int i = 0; i < Elts(); i++) 00137 data[i] = v[i]; 00138 00139 return(SELF); 00140 } 00141 #endif 00142 00143 TVec &TVec::operator = (const TVec2 &v) 00144 { 00145 if (!IsRef()) 00146 SetSize(v.Elts()); 00147 else 00148 Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match"); 00149 00150 data[0] = v[0]; 00151 data[1] = v[1]; 00152 00153 return(SELF); 00154 } 00155 00156 TVec &TVec::operator = (const TVec3 &v) 00157 { 00158 if (!IsRef()) 00159 SetSize(v.Elts()); 00160 else 00161 Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match"); 00162 00163 data[0] = v[0]; 00164 data[1] = v[1]; 00165 data[2] = v[2]; 00166 00167 return(SELF); 00168 } 00169 00170 TVec &TVec::operator = (const TVec4 &v) 00171 { 00172 if (!IsRef()) 00173 SetSize(v.Elts()); 00174 else 00175 Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match"); 00176 00177 data[0] = v[0]; 00178 data[1] = v[1]; 00179 data[2] = v[2]; 00180 data[3] = v[3]; 00181 00182 return(SELF); 00183 } 00184 00185 Void TVec::SetSize(Int n) 00186 { 00187 if (!IsRef()) 00188 { 00189 // Don't reallocate if we already have enough storage 00190 00191 if (n <= elts) 00192 { 00193 elts = n; 00194 return; 00195 } 00196 00197 // Otherwise, delete old storage 00198 00199 delete[] data; 00200 } 00201 00202 elts = n; 00203 data = new TVReal[elts]; 00204 Assert(data != 0, "(Vec::SetSize) Out of memory"); 00205 } 00206 00207 TVec &TVec::MakeZero() 00208 { 00209 Int j; 00210 00211 for (j = 0; j < Elts(); j++) 00212 data[j] = vl_zero; 00213 00214 return(SELF); 00215 } 00216 00217 TVec &TVec::MakeUnit(Int i, TVReal k) 00218 { 00219 Int j; 00220 00221 for (j = 0; j < Elts(); j++) 00222 data[j] = vl_zero; 00223 00224 data[i] = k; 00225 00226 return(SELF); 00227 } 00228 00229 TVec &TVec::MakeBlock(TVReal k) 00230 { 00231 Int i; 00232 00233 for (i = 0; i < Elts(); i++) 00234 data[i] = k; 00235 00236 return(SELF); 00237 } 00238 00239 00240 // --- Vec In-Place operators ------------------------------------------------- 00241 00242 00243 TVec &operator += (TVec &a, const TVec &b) 00244 { 00245 Assert(a.Elts() == b.Elts(), "(Vec::+=) vector sizes don't match"); 00246 00247 Int i; 00248 00249 for (i = 0; i < a.Elts(); i++) 00250 a[i] += b[i]; 00251 00252 return(a); 00253 } 00254 00255 TVec &operator -= (TVec &a, const TVec &b) 00256 { 00257 Assert(a.Elts() == b.Elts(), "(Vec::-=) vector sizes don't match"); 00258 00259 Int i; 00260 00261 for (i = 0; i < a.Elts(); i++) 00262 a[i] -= b[i]; 00263 00264 return(a); 00265 } 00266 00267 TVec &operator *= (TVec &a, const TVec &b) 00268 { 00269 Assert(a.Elts() == b.Elts(), "(Vec::*=) Vec sizes don't match"); 00270 00271 Int i; 00272 00273 for (i = 0; i < a.Elts(); i++) 00274 a[i] *= b[i]; 00275 00276 return(a); 00277 } 00278 00279 TVec &operator *= (TVec &v, TVReal s) 00280 { 00281 Int i; 00282 00283 for (i = 0; i < v.Elts(); i++) 00284 v[i] *= s; 00285 00286 return(v); 00287 } 00288 00289 TVec &operator /= (TVec &a, const TVec &b) 00290 { 00291 Assert(a.Elts() == b.Elts(), "(Vec::/=) Vec sizes don't match"); 00292 00293 Int i; 00294 00295 for (i = 0; i < a.Elts(); i++) 00296 a[i] /= b[i]; 00297 00298 return(a); 00299 } 00300 00301 TVec &operator /= (TVec &v, TVReal s) 00302 { 00303 Int i; 00304 00305 for (i = 0; i < v.Elts(); i++) 00306 v[i] /= s; 00307 00308 return(v); 00309 } 00310 00311 00312 // --- Vec Comparison Operators ----------------------------------------------- 00313 00314 00315 Bool operator == (const TVec &a, const TVec &b) 00316 { 00317 Int i; 00318 00319 for (i = 0; i < a.Elts(); i++) 00320 if (a[i] != b[i]) 00321 return(0); 00322 00323 return(1); 00324 } 00325 00326 Bool operator != (const TVec &a, const TVec &b) 00327 { 00328 Int i; 00329 00330 for (i = 0; i < a.Elts(); i++) 00331 if (a[i] != b[i]) 00332 return(1); 00333 00334 return(0); 00335 } 00336 00337 00338 // --- Vec Arithmetic Operators ----------------------------------------------- 00339 00340 00341 TVec operator + (const TVec &a, const TVec &b) 00342 { 00343 Assert(a.Elts() == b.Elts(), "(Vec::+) Vec sizes don't match"); 00344 00345 TVec result(a.Elts()); 00346 Int i; 00347 00348 for (i = 0; i < a.Elts(); i++) 00349 result[i] = a[i] + b[i]; 00350 00351 return(result); 00352 } 00353 00354 TVec operator - (const TVec &a, const TVec &b) 00355 { 00356 Assert(a.Elts() == b.Elts(), "(Vec::-) Vec sizes don't match"); 00357 00358 TVec result(a.Elts()); 00359 Int i; 00360 00361 for (i = 0; i < a.Elts(); i++) 00362 result[i] = a[i] - b[i]; 00363 00364 return(result); 00365 } 00366 00367 TVec operator - (const TVec &v) 00368 { 00369 TVec result(v.Elts()); 00370 Int i; 00371 00372 for (i = 0; i < v.Elts(); i++) 00373 result[i] = - v[i]; 00374 00375 return(result); 00376 } 00377 00378 TVec operator * (const TVec &a, const TVec &b) 00379 { 00380 Assert(a.Elts() == b.Elts(), "(Vec::*) Vec sizes don't match"); 00381 00382 TVec result(a.Elts()); 00383 Int i; 00384 00385 for (i = 0; i < a.Elts(); i++) 00386 result[i] = a[i] * b[i]; 00387 00388 return(result); 00389 } 00390 00391 TVec operator * (const TVec &v, TVReal s) 00392 { 00393 TVec result(v.Elts()); 00394 Int i; 00395 00396 for (i = 0; i < v.Elts(); i++) 00397 result[i] = v[i] * s; 00398 00399 return(result); 00400 } 00401 00402 TVec operator / (const TVec &a, const TVec &b) 00403 { 00404 Assert(a.Elts() == b.Elts(), "(Vec::/) Vec sizes don't match"); 00405 00406 TVec result(a.Elts()); 00407 Int i; 00408 00409 for (i = 0; i < a.Elts(); i++) 00410 result[i] = a[i] / b[i]; 00411 00412 return(result); 00413 } 00414 00415 TVec operator / (const TVec &v, TVReal s) 00416 { 00417 TVec result(v.Elts()); 00418 Int i; 00419 00420 for (i = 0; i < v.Elts(); i++) 00421 result[i] = v[i] / s; 00422 00423 return(result); 00424 } 00425 00426 TVReal dot(const TVec &a, const TVec &b) 00427 { 00428 Assert(a.Elts() == b.Elts(), "(Vec::dot) Vec sizes don't match"); 00429 00430 TMReal sum = vl_zero; 00431 Int i; 00432 00433 for (i = 0; i < a.Elts(); i++) 00434 sum += a[i] * b[i]; 00435 00436 return(sum); 00437 } 00438 00439 TVec operator * (TVReal s, const TVec &v) 00440 { 00441 TVec result(v.Elts()); 00442 Int i; 00443 00444 for (i = 0; i < v.Elts(); i++) 00445 result[i] = v[i] * s; 00446 00447 return(result); 00448 } 00449 00450 TVec &TVec::Clamp(Real fuzz) 00451 // clamps all values of the matrix with a magnitude 00452 // smaller than fuzz to zero. 00453 { 00454 Int i; 00455 00456 for (i = 0; i < Elts(); i++) 00457 if (len(SELF[i]) < fuzz) 00458 SELF[i] = vl_zero; 00459 00460 return(SELF); 00461 } 00462 00463 TVec &TVec::Clamp() 00464 { 00465 return(Clamp(1e-7)); 00466 } 00467 00468 TVec clamped(const TVec &v, Real fuzz) 00469 // clamps all values of the matrix with a magnitude 00470 // smaller than fuzz to zero. 00471 { 00472 TVec result(v); 00473 00474 return(result.Clamp(fuzz)); 00475 } 00476 00477 TVec clamped(const TVec &v) 00478 { 00479 return(clamped(v, 1e-7)); 00480 } 00481 00482 00483 // --- Vec Input & Output ----------------------------------------------------- 00484 00485 00486 ostream &operator << (ostream &s, const TVec &v) 00487 { 00488 Int i, w; 00489 00490 s << '['; 00491 00492 if (v.Elts() > 0) 00493 { 00494 w = s.width(); 00495 s << v[0]; 00496 00497 for (i = 1; i < v.Elts(); i++) 00498 s << ' ' << setw(w) << v[i]; 00499 } 00500 00501 s << ']'; 00502 00503 return(s); 00504 } 00505 00506 #ifndef __SVL__ 00507 istream &operator >> (istream &s, TVec &v) 00508 { 00509 Array<TVReal> array; 00510 00511 // Expected format: [1 2 3 4 ...] 00512 00513 s >> array; // Read input into variable-sized array 00514 00515 v = TVec(array.NumItems(), array.Ref()); // Copy input into vector 00516 00517 return(s); 00518 } 00519 #endif