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