Bart Janssens / SVL
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Vec.cpp Source File

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 */