Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Vec.cpp
00001 /* 00002 File: Vec.cpp 00003 00004 Function: Implements Vec.h 00005 00006 Author(s): Andrew Willmott 00007 00008 Copyright: (c) 1995-2001, Andrew Willmott 00009 00010 */ 00011 00012 00013 #include "Vec.h" 00014 00015 //#include <cctype> 00016 //#include <cstring> 00017 #include <cstdarg> 00018 //#include <iomanip> 00019 #include "Vec2.h" 00020 #include "Vec3.h" 00021 #include "Vec4.h" 00022 00023 // --- Vec Constructors ------------------------------------------------------- 00024 00025 00026 Vec::Vec(Int n, ZeroOrOne k) : elts(n) 00027 { 00028 Assert(n > 0,"(Vec) illegal vector size"); 00029 00030 data = new Real[n]; 00031 00032 MakeBlock(k); 00033 } 00034 00035 Vec::Vec(Int n, Axis a) : elts(n) 00036 { 00037 Assert(n > 0,"(Vec) illegal vector size"); 00038 00039 data = new Real[n]; 00040 00041 MakeUnit(a); 00042 } 00043 00044 Vec::Vec(const Vec &v) 00045 { 00046 Assert(v.data != 0, "(Vec) Can't construct from a null vector"); 00047 00048 elts = v.Elts(); 00049 data = new Real[elts]; 00050 00051 #ifdef VL_USE_MEMCPY 00052 memcpy(data, v.Ref(), sizeof(Real) * Elts()); 00053 #else 00054 for (Int i = 0; i < Elts(); i++) 00055 data[i] = v[i]; 00056 #endif 00057 } 00058 00059 Vec::Vec(const Vec2 &v) : data(v.Ref()), elts(v.Elts() | VL_REF_FLAG) 00060 { 00061 } 00062 00063 Vec::Vec(const Vec3 &v) : data(v.Ref()), elts(v.Elts() | VL_REF_FLAG) 00064 { 00065 } 00066 00067 Vec::Vec(const Vec4 &v) : data(v.Ref()), elts(v.Elts() | VL_REF_FLAG) 00068 { 00069 } 00070 00071 Vec::Vec(Int n, double elt0, ...) : elts(n) 00072 { 00073 Assert(n > 0,"(Vec) illegal vector size"); 00074 00075 va_list ap; 00076 Int i = 1; 00077 00078 data = new Real[n]; 00079 va_start(ap, elt0); 00080 00081 SetReal(data[0], elt0); 00082 00083 while (--n) 00084 SetReal(data[i++], va_arg(ap, double)); 00085 00086 va_end(ap); 00087 } 00088 00089 Vec::~Vec() 00090 { 00091 Assert(elts != 0,"(Vec) illegal vector size"); 00092 00093 if (!IsRef()) 00094 delete[] data; 00095 } 00096 00097 00098 // --- Vec Assignment Operators ----------------------------------------------- 00099 00100 00101 Vec &Vec::operator = (const Vec &v) 00102 { 00103 if (!IsRef()) 00104 SetSize(v.Elts()); 00105 else 00106 Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match"); 00107 00108 #ifdef VL_USE_MEMCPY 00109 memcpy(data, v.data, sizeof(Real) * Elts()); 00110 #else 00111 for (Int i = 0; i < Elts(); i++) 00112 data[i] = v[i]; 00113 #endif 00114 00115 return(SELF); 00116 } 00117 00118 Vec &Vec::operator = (const Vec2 &v) 00119 { 00120 if (!IsRef()) 00121 SetSize(v.Elts()); 00122 else 00123 Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match"); 00124 00125 data[0] = v[0]; 00126 data[1] = v[1]; 00127 00128 return(SELF); 00129 } 00130 00131 Vec &Vec::operator = (const Vec3 &v) 00132 { 00133 if (!IsRef()) 00134 SetSize(v.Elts()); 00135 else 00136 Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match"); 00137 00138 data[0] = v[0]; 00139 data[1] = v[1]; 00140 data[2] = v[2]; 00141 00142 return(SELF); 00143 } 00144 00145 Vec &Vec::operator = (const Vec4 &v) 00146 { 00147 if (!IsRef()) 00148 SetSize(v.Elts()); 00149 else 00150 Assert(Elts() == v.Elts(), "(Vec::=) Vector sizes don't match"); 00151 00152 data[0] = v[0]; 00153 data[1] = v[1]; 00154 data[2] = v[2]; 00155 data[3] = v[3]; 00156 00157 return(SELF); 00158 } 00159 00160 Void Vec::SetSize(Int ni) 00161 { 00162 Assert(ni > 0, "(Vec::SetSize) Illegal vector size"); 00163 UInt n = UInt(ni); 00164 00165 if (!IsRef()) 00166 { 00167 // Don't reallocate if we already have enough storage 00168 00169 if (n <= elts) 00170 { 00171 elts = n; 00172 return; 00173 } 00174 00175 // Otherwise, delete old storage 00176 00177 delete[] data; 00178 00179 elts = n; 00180 data = new Real[elts]; 00181 } 00182 else 00183 Assert(false, "(Vec::SetSize) Can't resize a vector reference"); 00184 } 00185 00186 Vec &Vec::MakeZero() 00187 { 00188 #ifdef VL_USE_MEMCPY 00189 memset(data, 0, sizeof(Real) * Elts()); 00190 #else 00191 Int j; 00192 00193 for (j = 0; j < Elts(); j++) 00194 data[j] = vl_zero; 00195 #endif 00196 00197 return(SELF); 00198 } 00199 00200 Vec &Vec::MakeUnit(Int i, Real k) 00201 { 00202 MakeZero(); 00203 data[i] = k; 00204 00205 return(SELF); 00206 } 00207 00208 Vec &Vec::MakeBlock(Real k) 00209 { 00210 Int i; 00211 00212 for (i = 0; i < Elts(); i++) 00213 data[i] = k; 00214 00215 return(SELF); 00216 } 00217 00218 00219 // --- Vec In-Place operators ------------------------------------------------- 00220 00221 00222 Vec &Vec::operator += (const Vec &b) 00223 { 00224 Assert(Elts() == b.Elts(), "(Vec::+=) vector sizes don't match"); 00225 00226 Int i; 00227 00228 for (i = 0; i < Elts(); i++) 00229 data[i] += b[i]; 00230 00231 return(SELF); 00232 } 00233 00234 Vec &Vec::operator -= (const Vec &b) 00235 { 00236 Assert(Elts() == b.Elts(), "(Vec::-=) vector sizes don't match"); 00237 00238 Int i; 00239 00240 for (i = 0; i < Elts(); i++) 00241 data[i] -= b[i]; 00242 00243 return(SELF); 00244 } 00245 00246 Vec &Vec::operator *= (const Vec &b) 00247 { 00248 Assert(Elts() == b.Elts(), "(Vec::*=) Vec sizes don't match"); 00249 00250 Int i; 00251 00252 for (i = 0; i < Elts(); i++) 00253 data[i] *= b[i]; 00254 00255 return(SELF); 00256 } 00257 00258 Vec &Vec::operator *= (Real s) 00259 { 00260 Int i; 00261 00262 for (i = 0; i < Elts(); i++) 00263 data[i] *= s; 00264 00265 return(SELF); 00266 } 00267 00268 Vec &Vec::operator /= (const Vec &b) 00269 { 00270 Assert(Elts() == b.Elts(), "(Vec::/=) Vec sizes don't match"); 00271 00272 Int i; 00273 00274 for (i = 0; i < Elts(); i++) 00275 data[i] /= b[i]; 00276 00277 return(SELF); 00278 } 00279 00280 Vec &Vec::operator /= (Real s) 00281 { 00282 Int i; 00283 00284 for (i = 0; i < Elts(); i++) 00285 data[i] /= s; 00286 00287 return(SELF); 00288 } 00289 00290 00291 // --- Vec Comparison Operators ----------------------------------------------- 00292 00293 00294 Bool operator == (const Vec &a, const Vec &b) 00295 { 00296 Int i; 00297 00298 for (i = 0; i < a.Elts(); i++) 00299 if (a[i] != b[i]) 00300 return(0); 00301 00302 return(1); 00303 } 00304 00305 Bool operator != (const Vec &a, const Vec &b) 00306 { 00307 Int i; 00308 00309 for (i = 0; i < a.Elts(); i++) 00310 if (a[i] != b[i]) 00311 return(1); 00312 00313 return(0); 00314 } 00315 00316 00317 // --- Vec Arithmetic Operators ----------------------------------------------- 00318 00319 00320 Vec operator + (const Vec &a, const Vec &b) 00321 { 00322 Assert(a.Elts() == b.Elts(), "(Vec::+) Vec sizes don't match"); 00323 00324 Vec result(a.Elts()); 00325 Int i; 00326 00327 for (i = 0; i < a.Elts(); i++) 00328 result[i] = a[i] + b[i]; 00329 00330 return(result); 00331 } 00332 00333 Vec operator - (const Vec &a, const Vec &b) 00334 { 00335 Assert(a.Elts() == b.Elts(), "(Vec::-) Vec sizes don't match"); 00336 00337 Vec result(a.Elts()); 00338 Int i; 00339 00340 for (i = 0; i < a.Elts(); i++) 00341 result[i] = a[i] - b[i]; 00342 00343 return(result); 00344 } 00345 00346 Vec operator - (const Vec &v) 00347 { 00348 Vec result(v.Elts()); 00349 Int i; 00350 00351 for (i = 0; i < v.Elts(); i++) 00352 result[i] = - v[i]; 00353 00354 return(result); 00355 } 00356 00357 Vec operator * (const Vec &a, const Vec &b) 00358 { 00359 Assert(a.Elts() == b.Elts(), "(Vec::*) Vec sizes don't match"); 00360 00361 Vec result(a.Elts()); 00362 Int i; 00363 00364 for (i = 0; i < a.Elts(); i++) 00365 result[i] = a[i] * b[i]; 00366 00367 return(result); 00368 } 00369 00370 Vec operator * (const Vec &v, Real s) 00371 { 00372 Vec result(v.Elts()); 00373 Int i; 00374 00375 for (i = 0; i < v.Elts(); i++) 00376 result[i] = v[i] * s; 00377 00378 return(result); 00379 } 00380 00381 Vec operator / (const Vec &a, const Vec &b) 00382 { 00383 Assert(a.Elts() == b.Elts(), "(Vec::/) Vec sizes don't match"); 00384 00385 Vec result(a.Elts()); 00386 Int i; 00387 00388 for (i = 0; i < a.Elts(); i++) 00389 result[i] = a[i] / b[i]; 00390 00391 return(result); 00392 } 00393 00394 Vec operator / (const Vec &v, Real s) 00395 { 00396 Vec result(v.Elts()); 00397 Int i; 00398 00399 for (i = 0; i < v.Elts(); i++) 00400 result[i] = v[i] / s; 00401 00402 return(result); 00403 } 00404 00405 Real dot(const Vec &a, const Vec &b) 00406 { 00407 Assert(a.Elts() == b.Elts(), "(Vec::dot) Vec sizes don't match"); 00408 00409 Real sum = vl_zero; 00410 Int i; 00411 00412 for (i = 0; i < a.Elts(); i++) 00413 sum += a[i] * b[i]; 00414 00415 return(sum); 00416 } 00417 00418 Vec operator * (Real s, const Vec &v) 00419 { 00420 Vec result(v.Elts()); 00421 Int i; 00422 00423 for (i = 0; i < v.Elts(); i++) 00424 result[i] = v[i] * s; 00425 00426 return(result); 00427 } 00428 00429 Vec &Vec::Clamp(Real fuzz) 00430 // clamps all values of the matrix with a magnitude 00431 // smaller than fuzz to zero. 00432 { 00433 Int i; 00434 00435 for (i = 0; i < Elts(); i++) 00436 if (len(SELF[i]) < fuzz) 00437 SELF[i] = vl_zero; 00438 00439 return(SELF); 00440 } 00441 00442 Vec &Vec::Clamp() 00443 { 00444 return(Clamp(1e-7)); 00445 } 00446 00447 Vec clamped(const Vec &v, Real fuzz) 00448 // clamps all values of the matrix with a magnitude 00449 // smaller than fuzz to zero. 00450 { 00451 Vec result(v); 00452 00453 return(result.Clamp(fuzz)); 00454 } 00455 00456 Vec clamped(const Vec &v) 00457 { 00458 return(clamped(v, 1e-7)); 00459 } 00460 00461 00462 // --- Vec Input & Output ----------------------------------------------------- 00463 00464 00465 /* 00466 ostream &operator << (ostream &s, const Vec &v) 00467 { 00468 Int i, w; 00469 00470 s << '['; 00471 00472 if (v.Elts() > 0) 00473 { 00474 w = s.width(); 00475 s << v[0]; 00476 00477 for (i = 1; i < v.Elts(); i++) 00478 s << ' ' << setw(w) << v[i]; 00479 } 00480 00481 s << ']'; 00482 00483 return(s); 00484 } 00485 */ 00486 00487 inline Void CopyPartialVec(const Vec &u, Vec &v, Int numElts) 00488 { 00489 for (Int i = 0; i < numElts; i++) 00490 v[i] = u[i]; 00491 } 00492 00493 /* 00494 istream &operator >> (istream &s, Vec &v) 00495 { 00496 Int size = 0; 00497 Vec inVec(16); 00498 Char c; 00499 00500 // Expected format: [a b c d ...] 00501 00502 while (isspace(s.peek())) // chomp white space 00503 s.get(c); 00504 00505 if (s.peek() == '[') 00506 { 00507 s.get(c); 00508 00509 00510 while (isspace(s.peek())) // chomp white space 00511 s.get(c); 00512 00513 while (s.peek() != ']') // resize if needed 00514 { 00515 if (size == inVec.Elts()) 00516 { 00517 Vec holdVec(inVec); 00518 00519 inVec.SetSize(size * 2); 00520 CopyPartialVec(holdVec, inVec, size); 00521 } 00522 00523 s >> inVec[size++]; // read an item 00524 00525 if (!s) 00526 { 00527 _Warning("Couldn't read vector element"); 00528 return(s); 00529 } 00530 00531 while (isspace(s.peek())) // chomp white space 00532 s.get(c); 00533 } 00534 s.get(c); 00535 } 00536 else 00537 { 00538 s.clear(ios::failbit); 00539 _Warning("Error: Expected '[' while reading vector"); 00540 return(s); 00541 } 00542 00543 v.SetSize(size); 00544 CopyPartialVec(inVec, v, size); 00545 00546 return(s); 00547 } 00548 */
Generated on Wed Jul 13 2022 19:31:42 by
1.7.2