12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027 |
- /*
- *
- * Mathematics Subpackage (VrMath)
- *
- *
- * Author: Samuel R. Buss, [email protected].
- * Web page: http://math.ucsd.edu/~sbuss/MathCG
- *
- *
- This software is provided 'as-is', without any express or implied warranty.
- In no event will the authors be held liable for any damages arising from the use of this software.
- Permission is granted to anyone to use this software for any purpose,
- including commercial applications, and to alter it and redistribute it freely,
- subject to the following restrictions:
- 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
- 3. This notice may not be removed or altered from any source distribution.
- *
- *
- */
- //
- // Linear Algebra Classes over R3
- //
- //
- // A. Vector and Position classes
- //
- // A.1. VectorR3: a real column vector of length 3.
- //
- // A.2. VectorHgR3: a column vector of length 4 which is
- // the homogenous representation of a vector in 3-space
- //
- // B. Matrix Classes
- //
- // B.1 LinearMapR3 - arbitrary linear map; 3x3 real matrix
- //
- // B.2 AffineMapR3 - arbitrary affine map; a 3x4 real matrix
- //
- // B.3 RotationMapR3 - orthonormal 3x3 matrix
- //
- // B.4 RigidMapR3 - RotationMapR3 plus displacement
- //
- #ifndef LINEAR_R3_H
- #define LINEAR_R3_H
- #include <math.h>
- #include <assert.h>
- #include <iostream>
- #include "MathMisc.h"
- using namespace std;
- class VectorR3; // Space Vector (length 3)
- class VectorHgR3; // Homogenous Space Vector
- class VectorR4; // Space Vector (length 4)
- class LinearMapR3; // Linear Map (3x3 Matrix)
- class AffineMapR3; // Affine Map (3x4 Matrix)
- class RotationMapR3; // Rotation (3x3 orthonormal matrix)
- class RigidMapR3; // 3x4 matrix, first 3 columns orthonormal
- // Most for internal use:
- class Matrix3x3;
- class Matrix3x4;
- class Quaternion;
- // **************************************
- // VectorR3 class *
- // * * * * * * * * * * * * * * * * * * **
- class VectorR3 {
- public:
- double x, y, z; // The x & y & z coordinates.
- static const VectorR3 Zero;
- static const VectorR3 UnitX;
- static const VectorR3 UnitY;
- static const VectorR3 UnitZ;
- static const VectorR3 NegUnitX;
- static const VectorR3 NegUnitY;
- static const VectorR3 NegUnitZ;
- public:
- VectorR3( ) : x(0.0), y(0.0), z(0.0) {}
- VectorR3( double xVal, double yVal, double zVal )
- : x(xVal), y(yVal), z(zVal) {}
- VectorR3( const VectorHgR3& uH );
- VectorR3& Set( const Quaternion& ); // Convert quat to rotation vector
- VectorR3& Set( double xx, double yy, double zz )
- { x=xx; y=yy; z=zz; return *this; }
- VectorR3& SetFromHg( const VectorR4& ); // Convert homogeneous VectorR4 to VectorR3
- VectorR3& SetZero() { x=0.0; y=0.0; z=0.0; return *this;}
- VectorR3& Load( const double* v );
- VectorR3& Load( const float* v );
- void Dump( double* v ) const;
- void Dump( float* v ) const;
- inline double operator[]( int i );
- VectorR3& operator= ( const VectorR3& v )
- { x=v.x; y=v.y; z=v.z; return(*this);}
- VectorR3& operator+= ( const VectorR3& v )
- { x+=v.x; y+=v.y; z+=v.z; return(*this); }
- VectorR3& operator-= ( const VectorR3& v )
- { x-=v.x; y-=v.y; z-=v.z; return(*this); }
- VectorR3& operator*= ( double m )
- { x*=m; y*=m; z*=m; return(*this); }
- VectorR3& operator/= ( double m )
- { register double mInv = 1.0/m;
- x*=mInv; y*=mInv; z*=mInv;
- return(*this); }
- VectorR3 operator- () const { return ( VectorR3(-x, -y, -z) ); }
- VectorR3& operator*= (const VectorR3& v); // Cross Product
- VectorR3& ArrayProd(const VectorR3&); // Component-wise product
- VectorR3& AddScaled( const VectorR3& u, double s );
- bool IsZero() const { return ( x==0.0 && y==0.0 && z==0.0 ); }
- double Norm() const { return ( (double)sqrt( x*x + y*y + z*z ) ); }
- double NormSq() const { return ( x*x + y*y + z*z ); }
- double MaxAbs() const;
- double Dist( const VectorR3& u ) const; // Distance from u
- double DistSq( const VectorR3& u ) const; // Distance from u squared
- VectorR3& Negate() { x = -x; y = -y; z = -z; return *this;}
- VectorR3& Normalize () { *this /= Norm(); return *this;} // No error checking
- inline VectorR3& MakeUnit(); // Normalize() with error checking
- inline VectorR3& ReNormalize();
- bool IsUnit( ) const
- { register double norm = Norm();
- return ( 1.000001>=norm && norm>=0.999999 ); }
- bool IsUnit( double tolerance ) const
- { register double norm = Norm();
- return ( 1.0+tolerance>=norm && norm>=1.0-tolerance ); }
- bool NearZero(double tolerance) const { return( MaxAbs()<=tolerance );}
- // tolerance should be non-negative
- double YaxisDistSq() const { return (x*x+z*z); }
- double YaxisDist() const { return sqrt(x*x+z*z); }
- VectorR3& Rotate( double theta, const VectorR3& u); // rotate around u.
- VectorR3& RotateUnitInDirection ( const VectorR3& dir); // rotate in direction dir
- VectorR3& Rotate( const Quaternion& ); // Rotate according to quaternion
- friend ostream& operator<< ( ostream& os, const VectorR3& u );
- };
- inline VectorR3 operator+( const VectorR3& u, const VectorR3& v );
- inline VectorR3 operator-( const VectorR3& u, const VectorR3& v );
- inline VectorR3 operator*( const VectorR3& u, double m);
- inline VectorR3 operator*( double m, const VectorR3& u);
- inline VectorR3 operator/( const VectorR3& u, double m);
- inline int operator==( const VectorR3& u, const VectorR3& v );
- inline double operator^ (const VectorR3& u, const VectorR3& v ); // Dot Product
- inline VectorR3 operator* (const VectorR3& u, const VectorR3& v); // Cross Product
- inline VectorR3 ArrayProd ( const VectorR3& u, const VectorR3& v );
- inline double Mag(const VectorR3& u) { return u.Norm(); }
- inline double Dist(const VectorR3& u, const VectorR3& v) { return u.Dist(v); }
- inline double DistSq(const VectorR3& u, const VectorR3& v) { return u.DistSq(v); }
- inline double NormalizeError (const VectorR3& u);
-
- extern const VectorR3 UnitVecIR3;
- extern const VectorR3 UnitVecJR3;
- extern const VectorR3 UnitVecKR3;
- inline VectorR3 ToVectorR3( const Quaternion& q )
- {return VectorR3().Set(q);}
- // ****************************************
- // VectorHgR3 class *
- // * * * * * * * * * * * * * * * * * * * **
- class VectorHgR3 {
- public:
- double x, y, z, w; // The x & y & z & w coordinates.
- public:
- VectorHgR3( ) : x(0.0), y(0.0), z(0.0), w(1.0) {}
- VectorHgR3( double xVal, double yVal, double zVal )
- : x(xVal), y(yVal), z(zVal), w(1.0) {}
- VectorHgR3( double xVal, double yVal, double zVal, double wVal )
- : x(xVal), y(yVal), z(zVal), w(wVal) {}
- VectorHgR3 ( const VectorR3& u ) : x(u.x), y(u.y), z(u.z), w(1.0) {}
- };
- //
- // Advanced vector and position functions (prototypes)
- //
- VectorR3 Interpolate( const VectorR3& start, const VectorR3& end, double a);
- // *****************************************
- // Matrix3x3 class *
- // * * * * * * * * * * * * * * * * * * * * *
- class Matrix3x3 {
- public:
- double m11, m12, m13, m21, m22, m23, m31, m32, m33;
-
- // Implements a 3x3 matrix: m_i_j - row-i and column-j entry
- static const Matrix3x3 Identity;
- public:
- inline Matrix3x3();
- inline Matrix3x3(const VectorR3&, const VectorR3&, const VectorR3&); // Sets by columns!
- inline Matrix3x3(double, double, double, double, double, double,
- double, double, double ); // Sets by columns
- inline void SetIdentity (); // Set to the identity map
- inline void Set ( const Matrix3x3& ); // Set to the matrix.
- inline void Set3x3 ( const Matrix3x4& ); // Set to the 3x3 part of the matrix.
- inline void Set( const VectorR3&, const VectorR3&, const VectorR3& );
- inline void Set( double, double, double,
- double, double, double,
- double, double, double );
- inline void SetByRows( double, double, double, double, double, double,
- double, double, double );
- inline void SetByRows( const VectorR3&, const VectorR3&, const VectorR3& );
-
- inline void SetColumn1 ( double, double, double );
- inline void SetColumn2 ( double, double, double );
- inline void SetColumn3 ( double, double, double );
- inline void SetColumn1 ( const VectorR3& );
- inline void SetColumn2 ( const VectorR3& );
- inline void SetColumn3 ( const VectorR3& );
- inline VectorR3 Column1() const;
- inline VectorR3 Column2() const;
- inline VectorR3 Column3() const;
- inline void SetRow1 ( double, double, double );
- inline void SetRow2 ( double, double, double );
- inline void SetRow3 ( double, double, double );
- inline void SetRow1 ( const VectorR3& );
- inline void SetRow2 ( const VectorR3& );
- inline void SetRow3 ( const VectorR3& );
- inline VectorR3 Row1() const;
- inline VectorR3 Row2() const;
- inline VectorR3 Row3() const;
- inline void SetDiagonal( double, double, double );
- inline void SetDiagonal( const VectorR3& );
- inline double Diagonal( int );
- inline void MakeTranspose(); // Transposes it.
- Matrix3x3& ReNormalize();
- VectorR3 Solve(const VectorR3&) const; // Returns solution
- inline void Transform( VectorR3* ) const;
- inline void Transform( const VectorR3& src, VectorR3* dest) const;
- protected:
- void OperatorTimesEquals( const Matrix3x3& ); // Internal use only
- void SetZero (); // Set to the zero map
- };
- inline VectorR3 operator* ( const Matrix3x3&, const VectorR3& );
- ostream& operator<< ( ostream& os, const Matrix3x3& A );
- // *****************************************
- // Matrix3x4 class *
- // * * * * * * * * * * * * * * * * * * * * *
- class Matrix3x4
- {
- public:
- double m11, m12, m13, m21, m22, m23, m31, m32, m33;
- double m14;
- double m24;
- double m34;
- static const Matrix3x4 Identity;
- public:
- // Constructors set by columns!
- Matrix3x4() {}
- Matrix3x4(const VectorR3&, const VectorR3&, const VectorR3&, const VectorR3& );
- Matrix3x4(double, double, double, double, double, double,
- double, double, double, double, double, double ); // Sets by columns
- Matrix3x4( const Matrix3x3&, const VectorR3& );
- void SetIdentity (); // Set to the identity map
- void Set ( const Matrix3x4& ); // Set to the matrix.
- void Set3x3 ( const Matrix3x3& ); // Set linear part to the matrix.
- void Set ( const Matrix3x3&, const VectorR3& ); // Set to the matrix plus 4th column
- void Set( const VectorR3&, const VectorR3&, const VectorR3&, const VectorR3& );
- void Set( double, double, double,
- double, double, double,
- double, double, double,
- double, double, double ); // Sets by columns
- void Set3x3( double, double, double,
- double, double, double,
- double, double, double ); // Sets by columns
- void SetByRows( double, double, double, double, double, double,
- double, double, double, double, double, double );
- void SetColumn1 ( double, double, double );
- void SetColumn2 ( double, double, double );
- void SetColumn3 ( double, double, double );
- void SetColumn4 ( double, double, double );
- void SetColumn1 ( const VectorR3& );
- void SetColumn2 ( const VectorR3& );
- void SetColumn3 ( const VectorR3& );
- void SetColumn4 ( const VectorR3& );
- VectorR3 Column1() const;
- VectorR3 Column2() const;
- VectorR3 Column3() const;
- VectorR3 Column4() const;
- void SetRow1 ( double x, double y, double z, double w );
- void SetRow2 ( double x, double y, double z, double w );
- void SetRow3 ( double x, double y, double z, double w );
- void SetRow4 ( double x, double y, double z, double w );
- Matrix3x4& ApplyTranslationLeft( const VectorR3& u );
- Matrix3x4& ApplyTranslationRight( const VectorR3& u );
- Matrix3x4& ApplyYRotationLeft( double theta );
- Matrix3x4& ApplyYRotationLeft( double costheta, double sintheta );
- Matrix3x4& ReNormalize();
- VectorR3 Solve(const VectorR3&) const; // Returns solution
- inline void Transform( VectorR3* ) const;
- inline void Transform3x3( VectorR3* ) const;
- inline void Transform( const VectorR3& src, VectorR3* dest ) const;
- inline void Transform3x3( const VectorR3& src, VectorR3* dest ) const;
- inline void Transform3x3Transpose( VectorR3* dest ) const;
- inline void Transform3x3Transpose( const VectorR3& src, VectorR3* dest ) const;
- protected:
- void SetZero (); // Set to the zero map
- void OperatorTimesEquals( const Matrix3x3& ); // Internal use only
- void OperatorTimesEquals( const Matrix3x4& ); // Internal use only
- };
- inline VectorR3 operator* ( const Matrix3x4&, const VectorR3& );
- ostream& operator<< ( ostream& os, const Matrix3x4& A );
- // *****************************************
- // LinearMapR3 class *
- // * * * * * * * * * * * * * * * * * * * * *
- class LinearMapR3 : public Matrix3x3 {
- public:
- LinearMapR3();
- LinearMapR3( const VectorR3&, const VectorR3&, const VectorR3& );
- LinearMapR3( double, double, double, double, double, double,
- double, double, double ); // Sets by columns
- LinearMapR3 ( const Matrix3x3& );
- void SetZero (); // Set to the zero map
- inline void Negate();
- inline LinearMapR3& operator+= (const Matrix3x3& );
- inline LinearMapR3& operator-= (const Matrix3x3& );
- inline LinearMapR3& operator*= (double);
- inline LinearMapR3& operator/= (double);
- LinearMapR3& operator*= (const Matrix3x3& ); // Matrix product
- inline LinearMapR3 Transpose() const; // Returns the transpose
- double Determinant () const; // Returns the determinant
- LinearMapR3 Inverse() const; // Returns inverse
- LinearMapR3& Invert(); // Converts into inverse.
- VectorR3 Solve(const VectorR3&) const; // Returns solution
- LinearMapR3 PseudoInverse() const; // Returns pseudo-inverse TO DO
- VectorR3 PseudoSolve(const VectorR3&); // Finds least squares solution TO DO
- };
-
- inline LinearMapR3 operator+ (const LinearMapR3&, const Matrix3x3&);
- inline LinearMapR3 operator+ (const Matrix3x3&, const LinearMapR3&);
- inline LinearMapR3 operator- (const LinearMapR3&);
- inline LinearMapR3 operator- (const LinearMapR3&, const Matrix3x3&);
- inline LinearMapR3 operator- (const Matrix3x3&, const LinearMapR3&);
- inline LinearMapR3 operator* ( const LinearMapR3&, double);
- inline LinearMapR3 operator* ( double, const LinearMapR3& );
- inline LinearMapR3 operator/ ( const LinearMapR3&, double );
- LinearMapR3 operator* ( const LinearMapR3&, const LinearMapR3& );
- // Matrix product (composition)
- // *****************************************************
- // * AffineMapR3 class *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * *
- class AffineMapR3 : public Matrix3x4 {
- public:
- AffineMapR3();
- AffineMapR3( double, double, double, double, double, double,
- double, double, double, double, double, double ); // Sets by columns
- AffineMapR3 ( const VectorR3&, const VectorR3&, const VectorR3&, const VectorR3&);
- AffineMapR3 ( const LinearMapR3&, const VectorR3& );
- void SetIdentity (); // Set to the identity map
- void SetZero (); // Set to the zero map
- AffineMapR3& operator+= (const Matrix3x4& );
- AffineMapR3& operator-= (const Matrix3x4& );
- AffineMapR3& operator*= (double);
- AffineMapR3& operator/= (double);
- AffineMapR3& operator*= (const Matrix3x3& ); // Composition
- AffineMapR3& operator*= (const Matrix3x4& ); // Composition
- AffineMapR3& ApplyTranslationLeft( const VectorR3& u )
- { Matrix3x4::ApplyTranslationLeft( u ); return *this; }
- AffineMapR3& ApplyTranslationRight( const VectorR3& u )
- { Matrix3x4::ApplyTranslationRight( u ); return *this; }
- AffineMapR3& ApplyYRotationLeft( double theta )
- { Matrix3x4::ApplyYRotationLeft( theta ); return *this; }
- AffineMapR3& ApplyYRotationLeft( double costheta, double sintheta )
- { Matrix3x4::ApplyYRotationLeft( costheta, sintheta ); return *this; }
- AffineMapR3 Inverse() const; // Returns inverse
- AffineMapR3& Invert(); // Converts into inverse.
- VectorR3 Solve(const VectorR3&) const; // Returns solution
- AffineMapR3 PseudoInverse() const; // Returns pseudo-inverse // TO DO
- VectorR3 PseudoSolve(const VectorR3&); // Least squares solution // TO DO
- };
- inline AffineMapR3 operator+ (const AffineMapR3&, const Matrix3x4&);
- inline AffineMapR3 operator+ (const Matrix3x4&, const AffineMapR3&);
- inline AffineMapR3 operator+ (const AffineMapR3&, const Matrix3x3&);
- inline AffineMapR3 operator+ (const Matrix3x3&, const AffineMapR3&);
- inline AffineMapR3 operator- (const AffineMapR3&, const Matrix3x4&);
- inline AffineMapR3 operator- (const Matrix3x4&, const AffineMapR3&);
- inline AffineMapR3 operator- (const AffineMapR3&, const Matrix3x3&);
- inline AffineMapR3 operator- (const Matrix3x3&, const AffineMapR3&);
- inline AffineMapR3 operator* (const AffineMapR3&, double);
- inline AffineMapR3 operator* (double, const AffineMapR3& );
- inline AffineMapR3 operator/ (const AffineMapR3&, double );
- // Composition operators
- AffineMapR3 operator* ( const AffineMapR3&, const AffineMapR3& );
- AffineMapR3 operator* ( const LinearMapR3&, const AffineMapR3& );
- AffineMapR3 operator* ( const AffineMapR3&, const LinearMapR3& );
- // *******************************************
- // RotationMapR3 class *
- // * * * * * * * * * * * * * * * * * * * * * *
- class RotationMapR3 : public Matrix3x3 {
- public:
- RotationMapR3();
- RotationMapR3( const VectorR3&, const VectorR3&, const VectorR3& );
- RotationMapR3( double, double, double, double, double, double,
- double, double, double );
- RotationMapR3& Set( const Quaternion& );
- RotationMapR3& Set( const VectorR3&, double theta ); // Set rotation axis and angle
- RotationMapR3& Set( const VectorR3&, double sintheta, double costheta );
- RotationMapR3& operator*= (const RotationMapR3& ); // Matrix product
- RotationMapR3 Transpose() const { return Inverse(); }; // Returns the transpose
- RotationMapR3 Inverse() const; // Returns inverse
- RotationMapR3& Invert(); // Converts into inverse.
- VectorR3 Solve(const VectorR3&) const; // Returns solution // Was named Invert
- bool ToAxisAndAngle( VectorR3* u, double* theta ) const; // returns unit vector u and angle
- };
-
- RotationMapR3 operator* ( const RotationMapR3&, const RotationMapR3& );
- // Matrix product (composition)
- inline RotationMapR3 ToRotationMapR3( const Quaternion& q )
- { return( RotationMapR3().Set(q) ); }
- ostream& operator<< ( ostream& os, const RotationMapR3& A );
- // ***************************************************************
- // * RigidMapR3 class - prototypes. * *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- class RigidMapR3 : public Matrix3x4
- {
- public:
- RigidMapR3();
- RigidMapR3( const VectorR3&, const VectorR3&, const VectorR3&, const VectorR3& );
- RigidMapR3( double, double, double, double, double, double,
- double, double, double, double, double, double );
- RigidMapR3( const Matrix3x3&, const VectorR3& );
- RigidMapR3& Set( const Matrix3x3&, const VectorR3& ); // Set to RotationMap & Vector
- RigidMapR3& SetTranslationPart( const VectorR3& ); // Set the translation part
- RigidMapR3& SetTranslationPart( double, double, double ); // Set the translation part
- RigidMapR3& SetRotationPart( const Matrix3x3& ); // Set the rotation part
- RigidMapR3& SetRotationPart( const Quaternion& );
- RigidMapR3& SetRotationPart( const VectorR3&, double theta ); // Set rotation axis and angle
- RigidMapR3& SetRotationPart( const VectorR3&, double sintheta, double costheta );
- RigidMapR3& ApplyTranslationLeft( const VectorR3& u )
- {Matrix3x4::ApplyTranslationLeft( u ); return *this;}
- RigidMapR3& ApplyTranslationRight( const VectorR3& u )
- {Matrix3x4::ApplyTranslationRight( u ); return *this;}
- RigidMapR3& ApplyYRotationLeft( double theta )
- { Matrix3x4::ApplyYRotationLeft( theta ); return *this; }
- RigidMapR3& ApplyYRotationLeft( double costheta, double sintheta )
- { Matrix3x4::ApplyYRotationLeft( costheta, sintheta ); return *this; }
- RigidMapR3& operator*=(const RotationMapR3& ); // Composition
- RigidMapR3& operator*=(const RigidMapR3& ); // Composition
- RigidMapR3 Inverse() const; // Returns inverse
- RigidMapR3& Invert(); // Converts into inverse.
- bool CalcGlideRotation( VectorR3* u, VectorR3* v,
- double *glideDist, double *rotation ) const;
- void Transform3x3Inverse( VectorR3* dest ) const
- { Matrix3x4::Transform3x3Transpose( dest ); }
- void Transform3x3Inverse( const VectorR3& src, VectorR3* dest ) const
- { Matrix3x4::Transform3x3Transpose( src, dest ); }
- };
- // ***************************************************************
- // * 3-space vector and matrix utilities (prototypes) *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Returns the solid angle between vectors v and w.
- inline double SolidAngle( const VectorR3& v, const VectorR3& w);
- // Returns a righthanded orthonormal basis to complement unit vector x
- void GetOrtho( const VectorR3& x, VectorR3& y, VectorR3& z);
- // Returns a vector v orthonormal to unit vector x
- void GetOrtho( const VectorR3& x, VectorR3& y );
- // Projections
- // The next three functions are templated below.
- //inline VectorR3 ProjectToUnit ( const VectorR3& u, const VectorR3& v); // Project u onto v
- //inline VectorR3 ProjectPerpUnit ( const VectorR3& u, const VectorR3 & v); // Project perp to v
- //inline VectorR3 ProjectPerpUnitDiff ( const VectorR3& u, const VectorR3& v)
- // v must be a unit vector.
- // Projection maps (LinearMapR3s)
- inline LinearMapR3 VectorProjectMap( const VectorR3& u );
- inline LinearMapR3 PlaneProjectMap ( const VectorR3& w );
- inline LinearMapR3 PlaneProjectMap ( const VectorR3& u, const VectorR3 &v );
- // u,v,w - must be unit vector. u and v must be orthonormal and
- // specify the plane they are parallel to. w specifies the plane
- // it is orthogonal to.
- // VrRotate is similar to glRotate. Returns a matrix (RotationMapR3)
- // that will perform the rotation. u should be a unit vector.
- RotationMapR3 VrRotate( double theta, const VectorR3& u );
- RotationMapR3 VrRotate( double costheta, double sintheta, const VectorR3& u );
- RotationMapR3 VrRotateAlign( const VectorR3& fromVec, const VectorR3& toVec);
- RotationMapR3 RotateToMap( const VectorR3& fromVec, const VectorR3& toVec);
- // fromVec and toVec should be unit vectors for RotateToMap
- // ***************************************************************
- // * Stream Output Routines (Prototypes) *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- ostream& operator<< ( ostream& os, const VectorR3& u );
- // *****************************************************
- // * VectorR3 class - inlined functions *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * *
- inline VectorR3& VectorR3::Load( const double* v )
- {
- x = *v;
- y = *(v+1);
- z = *(v+2);
- return *this;
- }
- inline VectorR3& VectorR3::Load( const float* v )
- {
- x = *v;
- y = *(v+1);
- z = *(v+2);
- return *this;
- }
- inline void VectorR3::Dump( double* v ) const
- {
- *v = x;
- *(v+1) = y;
- *(v+2) = z;
- }
- inline void VectorR3::Dump( float* v ) const
- {
- *v = (float)x;
- *(v+1) = (float)y;
- *(v+2) = (float)z;
- }
- inline double VectorR3::operator[]( int i )
- {
- switch (i) {
- case 0:
- return x;
- case 1:
- return y;
- case 2:
- return z;
- default:
- assert(0);
- return 0.0;
- }
- }
- inline VectorR3& VectorR3::MakeUnit () // Convert to unit vector (or leave zero).
- {
- double nSq = NormSq();
- if (nSq != 0.0) {
- *this /= sqrt(nSq);
- }
- return *this;
- }
- inline VectorR3 operator+( const VectorR3& u, const VectorR3& v )
- {
- return VectorR3(u.x+v.x, u.y+v.y, u.z+v.z);
- }
- inline VectorR3 operator-( const VectorR3& u, const VectorR3& v )
- {
- return VectorR3(u.x-v.x, u.y-v.y, u.z-v.z);
- }
- inline VectorR3 operator*( const VectorR3& u, register double m)
- {
- return VectorR3( u.x*m, u.y*m, u.z*m);
- }
- inline VectorR3 operator*( register double m, const VectorR3& u)
- {
- return VectorR3( u.x*m, u.y*m, u.z*m);
- }
- inline VectorR3 operator/( const VectorR3& u, double m)
- {
- register double mInv = 1.0/m;
- return VectorR3( u.x*mInv, u.y*mInv, u.z*mInv);
- }
- inline int operator==( const VectorR3& u, const VectorR3& v )
- {
- return ( u.x==v.x && u.y==v.y && u.z==v.z );
- }
- inline double operator^ ( const VectorR3& u, const VectorR3& v ) // Dot Product
- {
- return ( u.x*v.x + u.y*v.y + u.z*v.z );
- }
- inline VectorR3 operator* (const VectorR3& u, const VectorR3& v) // Cross Product
- {
- return (VectorR3( u.y*v.z - u.z*v.y,
- u.z*v.x - u.x*v.z,
- u.x*v.y - u.y*v.x ) );
- }
- inline VectorR3 ArrayProd ( const VectorR3& u, const VectorR3& v )
- {
- return ( VectorR3( u.x*v.x, u.y*v.y, u.z*v.z ) );
- }
- inline VectorR3& VectorR3::operator*= (const VectorR3& v) // Cross Product
- {
- double tx=x, ty=y;
- x = y*v.z - z*v.y;
- y = z*v.x - tx*v.z;
- z = tx*v.y - ty*v.x;
- return ( *this );
- }
- inline VectorR3& VectorR3::ArrayProd (const VectorR3& v) // Component-wise Product
- {
- x *= v.x;
- y *= v.y;
- z *= v.z;
- return ( *this );
- }
- inline VectorR3& VectorR3::AddScaled( const VectorR3& u, double s )
- {
- x += s*u.x;
- y += s*u.y;
- z += s*u.z;
- return(*this);
- }
- inline VectorR3::VectorR3( const VectorHgR3& uH )
- : x(uH.x), y(uH.y), z(uH.z)
- {
- *this /= uH.w;
- }
- inline VectorR3& VectorR3::ReNormalize() // Convert near unit back to unit
- {
- double nSq = NormSq();
- register double mFact = 1.0-0.5*(nSq-1.0); // Multiplicative factor
- *this *= mFact;
- return *this;
- }
- inline double NormalizeError (const VectorR3& u)
- {
- register double discrepancy;
- discrepancy = u.x*u.x + u.y*u.y + u.z*u.z - 1.0;
- if ( discrepancy < 0.0 ) {
- discrepancy = -discrepancy;
- }
- return discrepancy;
- }
- inline double VectorR3::Dist( const VectorR3& u ) const // Distance from u
- {
- return sqrt( DistSq(u) );
- }
- inline double VectorR3::DistSq( const VectorR3& u ) const // Distance from u
- {
- return ( (x-u.x)*(x-u.x) + (y-u.y)*(y-u.y) + (z-u.z)*(z-u.z) );
- }
- //
- // Interpolation routines (not just Spherical Interpolation)
- //
- // Interpolate(start,end,frac) - linear interpolation
- // - allows overshooting the end points
- inline VectorR3 Interpolate( const VectorR3& start, const VectorR3& end, double a)
- {
- VectorR3 ret;
- Lerp( start, end, a, ret );
- return ret;
- }
- // ******************************************************
- // * Matrix3x3 class - inlined functions *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * **
- inline Matrix3x3::Matrix3x3() {}
- inline Matrix3x3::Matrix3x3( const VectorR3& u, const VectorR3& v,
- const VectorR3& s )
- {
- m11 = u.x; // Column 1
- m21 = u.y;
- m31 = u.z;
- m12 = v.x; // Column 2
- m22 = v.y;
- m32 = v.z;
- m13 = s.x; // Column 3
- m23 = s.y;
- m33 = s.z;
- }
- inline Matrix3x3::Matrix3x3( double a11, double a21, double a31,
- double a12, double a22, double a32,
- double a13, double a23, double a33)
- // Values specified in column order!!!
- {
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- }
-
- inline void Matrix3x3::SetIdentity ( )
- {
- m11 = m22 = m33 = 1.0;
- m12 = m13 = m21 = m23 = m31 = m32 = 0.0;
- }
- inline void Matrix3x3::SetZero( )
- {
- m11 = m12 = m13 = m21 = m22 = m23 = m31 = m32 = m33 = 0.0;
- }
- inline void Matrix3x3::Set ( const Matrix3x3& A ) // Set to the matrix.
- {
- m11 = A.m11;
- m21 = A.m21;
- m31 = A.m31;
- m12 = A.m12;
- m22 = A.m22;
- m32 = A.m32;
- m13 = A.m13;
- m23 = A.m23;
- m33 = A.m33;
- }
- inline void Matrix3x3::Set3x3 ( const Matrix3x4& A ) // Set to the 3x3 part of the matrix.
- {
- m11 = A.m11;
- m21 = A.m21;
- m31 = A.m31;
- m12 = A.m12;
- m22 = A.m22;
- m32 = A.m32;
- m13 = A.m13;
- m23 = A.m23;
- m33 = A.m33;
- }
- inline void Matrix3x3::Set( const VectorR3& u, const VectorR3& v,
- const VectorR3& w)
- {
- m11 = u.x; // Column 1
- m21 = u.y;
- m31 = u.z;
- m12 = v.x; // Column 2
- m22 = v.y;
- m32 = v.z;
- m13 = w.x; // Column 3
- m23 = w.y;
- m33 = w.z;
- }
- inline void Matrix3x3::Set( double a11, double a21, double a31,
- double a12, double a22, double a32,
- double a13, double a23, double a33)
- // Values specified in column order!!!
- {
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- }
- inline void Matrix3x3::SetByRows( double a11, double a12, double a13,
- double a21, double a22, double a23,
- double a31, double a32, double a33)
- // Values specified in row order!!!
- {
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- }
- inline void Matrix3x3::SetByRows( const VectorR3& u, const VectorR3& v,
- const VectorR3& s )
- {
- m11 = u.x; // Row 1
- m12 = u.y;
- m13 = u.z;
- m21 = v.x; // Row 2
- m22 = v.y;
- m23 = v.z;
- m31 = s.x; // Row 3
- m32 = s.y;
- m33 = s.z;
- }
- inline void Matrix3x3::SetColumn1 ( double x, double y, double z)
- {
- m11 = x; m21 = y; m31= z;
- }
- inline void Matrix3x3::SetColumn2 ( double x, double y, double z)
- {
- m12 = x; m22 = y; m32= z;
- }
- inline void Matrix3x3::SetColumn3 ( double x, double y, double z)
- {
- m13 = x; m23 = y; m33= z;
- }
- inline void Matrix3x3::SetColumn1 ( const VectorR3& u )
- {
- m11 = u.x; m21 = u.y; m31 = u.z;
- }
- inline void Matrix3x3::SetColumn2 ( const VectorR3& u )
- {
- m12 = u.x; m22 = u.y; m32 = u.z;
- }
- inline void Matrix3x3::SetColumn3 ( const VectorR3& u )
- {
- m13 = u.x; m23 = u.y; m33 = u.z;
- }
- inline void Matrix3x3::SetRow1 ( double x, double y, double z )
- {
- m11 = x;
- m12 = y;
- m13 = z;
- }
- inline void Matrix3x3::SetRow2 ( double x, double y, double z )
- {
- m21 = x;
- m22 = y;
- m23 = z;
- }
- inline void Matrix3x3::SetRow3 ( double x, double y, double z )
- {
- m31 = x;
- m32 = y;
- m33 = z;
- }
- inline VectorR3 Matrix3x3::Column1() const
- {
- return ( VectorR3(m11, m21, m31) );
- }
- inline VectorR3 Matrix3x3::Column2() const
- {
- return ( VectorR3(m12, m22, m32) );
- }
- inline VectorR3 Matrix3x3::Column3() const
- {
- return ( VectorR3(m13, m23, m33) );
- }
- inline VectorR3 Matrix3x3::Row1() const
- {
- return ( VectorR3(m11, m12, m13) );
- }
- inline VectorR3 Matrix3x3::Row2() const
- {
- return ( VectorR3(m21, m22, m23) );
- }
- inline VectorR3 Matrix3x3::Row3() const
- {
- return ( VectorR3(m31, m32, m33) );
- }
- inline void Matrix3x3::SetDiagonal( double x, double y, double z )
- {
- m11 = x;
- m22 = y;
- m33 = z;
- }
- inline void Matrix3x3::SetDiagonal( const VectorR3& u )
- {
- SetDiagonal ( u.x, u.y, u.z );
- }
- inline double Matrix3x3::Diagonal( int i )
- {
- switch (i) {
- case 0:
- return m11;
- case 1:
- return m22;
- case 2:
- return m33;
- default:
- assert(0);
- return 0.0;
- }
- }
- inline void Matrix3x3::MakeTranspose() // Transposes it.
- {
- register double temp;
- temp = m12;
- m12 = m21;
- m21=temp;
- temp = m13;
- m13 = m31;
- m31 = temp;
- temp = m23;
- m23 = m32;
- m32 = temp;
- }
- inline VectorR3 operator* ( const Matrix3x3& A, const VectorR3& u)
- {
- return( VectorR3( A.m11*u.x + A.m12*u.y + A.m13*u.z,
- A.m21*u.x + A.m22*u.y + A.m23*u.z,
- A.m31*u.x + A.m32*u.y + A.m33*u.z ) );
- }
- inline void Matrix3x3::Transform( VectorR3* u ) const {
- double newX, newY;
- newX = m11*u->x + m12*u->y + m13*u->z;
- newY = m21*u->x + m22*u->y + m23*u->z;
- u->z = m31*u->x + m32*u->y + m33*u->z;
- u->x = newX;
- u->y = newY;
- }
- inline void Matrix3x3::Transform( const VectorR3& src, VectorR3* dest ) const {
- dest->x = m11*src.x + m12*src.y + m13*src.z;
- dest->y = m21*src.x + m22*src.y + m23*src.z;
- dest->z = m31*src.x + m32*src.y + m33*src.z;
- }
- // ******************************************************
- // * Matrix3x4 class - inlined functions *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * **
- inline Matrix3x4::Matrix3x4(const VectorR3& u, const VectorR3& v,
- const VectorR3& s, const VectorR3& t)
- {
- m11 = u.x; // Column 1
- m21 = u.y;
- m31 = u.z;
- m12 = v.x; // Column 2
- m22 = v.y;
- m32 = v.z;
- m13 = s.x; // Column 3
- m23 = s.y;
- m33 = s.z;
- m14 = t.x;
- m24 = t.y;
- m34 = t.z;
- }
- inline Matrix3x4::Matrix3x4(double a11, double a21, double a31,
- double a12, double a22, double a32,
- double a13, double a23, double a33,
- double a14, double a24, double a34)
- { // Values in COLUMN order!
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m14 = a14;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m24 = a24;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- m34 = a34;
- }
- inline Matrix3x4::Matrix3x4( const Matrix3x3& A, const VectorR3& u )
- {
- Set(A, u);
- }
- inline void Matrix3x4::SetIdentity () // Set to the identity map
- {
- m11 = m22 = m33 = 1.0;
- m12 = m13 = m21 = m23 = m31 = m32 = 0.0;
- m14 = m24 = m34 = 0.0;
- }
- inline void Matrix3x4::SetZero () // Set to the zero map
- {
- m11 = m22 = m33 = 0.0;
- m12 = m13 = m21 = m23 = m31 = m32 = 0.0;
- m14 = m24 = m34 = 0.0;
- }
- inline void Matrix3x4::Set ( const Matrix3x4& A ) // Set to the matrix.
- {
- m11 = A.m11;
- m21 = A.m21;
- m31 = A.m31;
- m12 = A.m12;
- m22 = A.m22;
- m32 = A.m32;
- m13 = A.m13;
- m23 = A.m23;
- m33 = A.m33;
- m14 = A.m14;
- m24 = A.m24;
- m34 = A.m34;
- }
- inline void Matrix3x4::Set ( const Matrix3x3& A, const VectorR3& t ) // Set to the matrix plus 4th column
- {
- m11 = A.m11;
- m21 = A.m21;
- m31 = A.m31;
- m12 = A.m12;
- m22 = A.m22;
- m32 = A.m32;
- m13 = A.m13;
- m23 = A.m23;
- m33 = A.m33;
- m14 = t.x; // Column 4
- m24 = t.y;
- m34 = t.z;
- }
- // Set linear part to the matrix
- inline void Matrix3x4::Set3x3 ( const Matrix3x3& A )
- {
- m11 = A.m11;
- m21 = A.m21;
- m31 = A.m31;
- m12 = A.m12;
- m22 = A.m22;
- m32 = A.m32;
- m13 = A.m13;
- m23 = A.m23;
- m33 = A.m33;
- }
- inline void Matrix3x4::Set( const VectorR3& u, const VectorR3& v,
- const VectorR3& w, const VectorR3& t )
- {
- m11 = u.x; // Column 1
- m21 = u.y;
- m31 = u.z;
- m12 = v.x; // Column 2
- m22 = v.y;
- m32 = v.z;
- m13 = w.x; // Column 3
- m23 = w.y;
- m33 = w.z;
- m14 = t.x; // Column 4
- m24 = t.y;
- m34 = t.z;
- }
- inline void Matrix3x4::Set( double a11, double a21, double a31,
- double a12, double a22, double a32,
- double a13, double a23, double a33,
- double a14, double a24, double a34 )
- // Values specified in column order!!!
- {
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m14 = a14;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m24 = a24;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- m34 = a34;
- }
- inline void Matrix3x4::Set3x3( double a11, double a21, double a31,
- double a12, double a22, double a32,
- double a13, double a23, double a33 )
- // Values specified in column order!!!
- {
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- }
- inline void Matrix3x4::SetByRows( double a11, double a12, double a13, double a14,
- double a21, double a22, double a23, double a24,
- double a31, double a32, double a33, double a34 )
- // Values specified in row order!!!
- {
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m14 = a14;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m24 = a24;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- m34 = a34;
- }
- inline void Matrix3x4::SetColumn1 ( double x, double y, double z)
- {
- m11 = x; m21 = y; m31= z;
- }
- inline void Matrix3x4::SetColumn2 ( double x, double y, double z)
- {
- m12 = x; m22 = y; m32= z;
- }
- inline void Matrix3x4::SetColumn3 ( double x, double y, double z)
- {
- m13 = x; m23 = y; m33= z;
- }
- inline void Matrix3x4::SetColumn4 ( double x, double y, double z )
- {
- m14 = x; m24 = y; m34= z;
- }
- inline void Matrix3x4::SetColumn1 ( const VectorR3& u )
- {
- m11 = u.x; m21 = u.y; m31 = u.z;
- }
- inline void Matrix3x4::SetColumn2 ( const VectorR3& u )
- {
- m12 = u.x; m22 = u.y; m32 = u.z;
- }
- inline void Matrix3x4::SetColumn3 ( const VectorR3& u )
- {
- m13 = u.x; m23 = u.y; m33 = u.z;
- }
- inline void Matrix3x4::SetColumn4 ( const VectorR3& u )
- {
- m14 = u.x; m24 = u.y; m34 = u.z;
- }
- inline VectorR3 Matrix3x4::Column1() const
- {
- return ( VectorR3(m11, m21, m31) );
- }
- inline VectorR3 Matrix3x4::Column2() const
- {
- return ( VectorR3(m12, m22, m32) );
- }
- inline VectorR3 Matrix3x4::Column3() const
- {
- return ( VectorR3(m13, m23, m33) );
- }
- inline VectorR3 Matrix3x4::Column4() const
- {
- return ( VectorR3(m14, m24, m34) );
- }
- inline void Matrix3x4::SetRow1 ( double x, double y, double z, double w )
- {
- m11 = x;
- m12 = y;
- m13 = z;
- m14 = w;
- }
- inline void Matrix3x4::SetRow2 ( double x, double y, double z, double w )
- {
- m21 = x;
- m22 = y;
- m23 = z;
- m24 = w;
- }
- inline void Matrix3x4::SetRow3 ( double x, double y, double z, double w )
- {
- m31 = x;
- m32 = y;
- m33 = z;
- m34 = w;
- }
- // Left multiply with a translation (so the translation is applied afterwards).
- inline Matrix3x4& Matrix3x4::ApplyTranslationLeft( const VectorR3& u )
- {
- m14 += u.x;
- m24 += u.y;
- m34 += u.z;
- return *this;
- }
- // Right multiply with a translation (so the translation is applied first).
- inline Matrix3x4& Matrix3x4::ApplyTranslationRight( const VectorR3& u )
- {
- double new14 = m14 + m11*u.x + m12*u.y + m13*u.z;
- double new24 = m24 + m21*u.x + m22*u.y + m23*u.z;
- m34 = m34 + m31*u.x + m32*u.y + m33*u.z;
- m14 = new14;
- m24 = new24;
- return *this;
- }
- // Left-multiply with a rotation around the y-axis.
- inline Matrix3x4& Matrix3x4::ApplyYRotationLeft( double theta )
- {
- double costheta = cos(theta);
- double sintheta = sin(theta);
- return ApplyYRotationLeft( costheta, sintheta );
- }
- inline Matrix3x4& Matrix3x4::ApplyYRotationLeft( double costheta, double sintheta )
- {
- double tmp;
- tmp = costheta*m11+sintheta*m31;
- m31 = costheta*m31-sintheta*m11;
- m11 = tmp;
- tmp = costheta*m12+sintheta*m32;
- m32 = costheta*m32-sintheta*m12;
- m12 = tmp;
- tmp = costheta*m13+sintheta*m33;
- m33 = costheta*m33-sintheta*m13;
- m13 = tmp;
- tmp = costheta*m14+sintheta*m34;
- m34 = costheta*m34-sintheta*m14;
- m14 = tmp;
- return *this;
- }
- inline VectorR3 Matrix3x4::Solve(const VectorR3& u) const // Returns solution
- {
- Matrix3x3 A;
- A.Set3x3(*this);
- return ( A.Solve( VectorR3(m14-u.x, m24-u.y, m34-u.z) ) );
- }
- inline void Matrix3x4::Transform( VectorR3* u ) const {
- double newX, newY;
- newX = m11*u->x + m12*u->y + m13*u->z + m14;
- newY = m21*u->x + m22*u->y + m23*u->z + m24;
- u->z = m31*u->x + m32*u->y + m33*u->z + m34;
- u->x = newX;
- u->y = newY;
- }
- inline void Matrix3x4::Transform3x3( VectorR3* u ) const {
- double newX, newY;
- newX = m11*u->x + m12*u->y + m13*u->z;
- newY = m21*u->x + m22*u->y + m23*u->z;
- u->z = m31*u->x + m32*u->y + m33*u->z;
- u->x = newX;
- u->y = newY;
- }
- inline void Matrix3x4::Transform( const VectorR3& src, VectorR3* dest ) const {
- dest->x = m11*src.x + m12*src.y + m13*src.z + m14;
- dest->y = m21*src.x + m22*src.y + m23*src.z + m24;
- dest->z = m31*src.x + m32*src.y + m33*src.z + m34;
- }
- inline void Matrix3x4::Transform3x3( const VectorR3& src, VectorR3* dest ) const {
- dest->x = m11*src.x + m12*src.y + m13*src.z;
- dest->y = m21*src.x + m22*src.y + m23*src.z;
- dest->z = m31*src.x + m32*src.y + m33*src.z;
- }
- inline void Matrix3x4::Transform3x3Transpose( VectorR3* u ) const {
- double newX, newY;
- newX = m11*u->x + m21*u->y + m31*u->z;
- newY = m12*u->x + m22*u->y + m32*u->z;
- u->z = m13*u->x + m23*u->y + m33*u->z;
- u->x = newX;
- u->y = newY;
- }
- inline void Matrix3x4::Transform3x3Transpose( const VectorR3& src, VectorR3* dest ) const {
- dest->x = m11*src.x + m21*src.y + m31*src.z;
- dest->y = m12*src.x + m22*src.y + m32*src.z;
- dest->z = m13*src.x + m23*src.y + m33*src.z;
- }
- inline VectorR3 operator* ( const Matrix3x4& A, const VectorR3& u )
- {
- return( VectorR3( A.m11*u.x + A.m12*u.y + A.m13*u.z + A.m14,
- A.m21*u.x + A.m22*u.y + A.m23*u.z + A.m24,
- A.m31*u.x + A.m32*u.y + A.m33*u.z + A.m34) );
- }
- // ******************************************************
- // * LinearMapR3 class - inlined functions *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * **
- inline LinearMapR3::LinearMapR3()
- {
- SetZero();
- return;
- }
- inline LinearMapR3::LinearMapR3( const VectorR3& u, const VectorR3& v,
- const VectorR3& s )
- :Matrix3x3 ( u, v, s )
- { }
- inline LinearMapR3::LinearMapR3(
- double a11, double a21, double a31,
- double a12, double a22, double a32,
- double a13, double a23, double a33)
- // Values specified in column order!!!
- :Matrix3x3 ( a11, a21, a31, a12, a22, a32, a13, a23, a33)
- { }
- inline LinearMapR3::LinearMapR3 ( const Matrix3x3& A )
- : Matrix3x3 (A)
- {}
- inline void LinearMapR3::SetZero( )
- {
- Matrix3x3::SetZero();
- }
- inline void LinearMapR3::Negate()
- {
- m11 = -m11; // Row 1
- m12 = -m12;
- m13 = -m13;
- m21 = -m21; // Row 2
- m22 = -m22;
- m23 = -m23;
- m31 = -m31; // Row 3
- m32 = -m32;
- m33 = -m33;
- }
-
- inline LinearMapR3& LinearMapR3::operator+= (const Matrix3x3& B)
- {
- m11 += B.m11;
- m12 += B.m12;
- m13 += B.m13;
- m21 += B.m21;
- m22 += B.m22;
- m23 += B.m23;
- m31 += B.m31;
- m32 += B.m32;
- m33 += B.m33;
- return ( *this );
- }
- inline LinearMapR3& LinearMapR3::operator-= (const Matrix3x3& B)
- {
- m11 -= B.m11;
- m12 -= B.m12;
- m13 -= B.m13;
- m21 -= B.m21;
- m22 -= B.m22;
- m23 -= B.m23;
- m31 -= B.m31;
- m32 -= B.m32;
- m33 -= B.m33;
- return( *this );
- }
- inline LinearMapR3 operator+ (const LinearMapR3& A, const Matrix3x3& B)
- {
- return (LinearMapR3( A.m11+B.m11, A.m21+B.m21, A.m31+B.m31,
- A.m12+B.m12, A.m22+B.m22, A.m32+B.m32,
- A.m13+B.m13, A.m23+B.m23, A.m33+B.m33 ) );
- }
- inline LinearMapR3 operator+ (const Matrix3x3& A, const LinearMapR3& B)
- {
- return (LinearMapR3( A.m11+B.m11, A.m21+B.m21, A.m31+B.m31,
- A.m12+B.m12, A.m22+B.m22, A.m32+B.m32,
- A.m13+B.m13, A.m23+B.m23, A.m33+B.m33 ) );
- }
- inline LinearMapR3 operator- (const LinearMapR3& A)
- {
- return( LinearMapR3( -A.m11, -A.m21, -A.m31,
- -A.m12, -A.m22, -A.m32,
- -A.m13, -A.m23, -A.m33 ) );
- }
- inline LinearMapR3 operator- (const Matrix3x3& A, const LinearMapR3& B)
- {
- return( LinearMapR3( A.m11-B.m11, A.m21-B.m21, A.m31-B.m31,
- A.m12-B.m12, A.m22-B.m22, A.m32-B.m32,
- A.m13-B.m13, A.m23-B.m23, A.m33-B.m33 ) );
- }
- inline LinearMapR3 operator- (const LinearMapR3& A, const Matrix3x3& B)
- {
- return( LinearMapR3( A.m11-B.m11, A.m21-B.m21, A.m31-B.m31,
- A.m12-B.m12, A.m22-B.m22, A.m32-B.m32,
- A.m13-B.m13, A.m23-B.m23, A.m33-B.m33 ) );
- }
- inline LinearMapR3& LinearMapR3::operator*= (register double b)
- {
- m11 *= b;
- m12 *= b;
- m13 *= b;
- m21 *= b;
- m22 *= b;
- m23 *= b;
- m31 *= b;
- m32 *= b;
- m33 *= b;
- return ( *this);
- }
- inline LinearMapR3 operator* ( const LinearMapR3& A, register double b)
- {
- return( LinearMapR3( A.m11*b, A.m21*b, A.m31*b,
- A.m12*b, A.m22*b, A.m32*b,
- A.m13*b, A.m23*b, A.m33*b ) );
- }
- inline LinearMapR3 operator* ( register double b, const LinearMapR3& A)
- {
- return( LinearMapR3( A.m11*b, A.m21*b, A.m31*b,
- A.m12*b, A.m22*b, A.m32*b,
- A.m13*b, A.m23*b, A.m33*b ) );
- }
- inline LinearMapR3 operator/ ( const LinearMapR3& A, double b)
- {
- register double bInv = 1.0/b;
- return( LinearMapR3( A.m11*bInv, A.m21*bInv, A.m31*bInv,
- A.m12*bInv, A.m22*bInv, A.m32*bInv,
- A.m13*bInv, A.m23*bInv, A.m33*bInv ) );
- }
- inline LinearMapR3& LinearMapR3::operator/= (register double b)
- {
- register double bInv = 1.0/b;
- return ( *this *= bInv );
- }
- inline LinearMapR3& LinearMapR3::operator*= (const Matrix3x3& B) // Matrix product
- {
- OperatorTimesEquals( B );
- return( *this );
- }
- inline VectorR3 LinearMapR3::Solve(const VectorR3& u) const // Returns solution
- {
- return ( Matrix3x3::Solve( u ) );
- }
-
- inline LinearMapR3 LinearMapR3::Transpose() const // Returns the transpose
- {
- return ( LinearMapR3 ( m11, m12, m13, m21, m22, m23, m31, m32, m33) );
- }
- // ******************************************************
- // * AffineMapR3 class - inlined functions *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * **
- inline AffineMapR3::AffineMapR3( double a11, double a21, double a31,
- double a12, double a22, double a32,
- double a13, double a23, double a33,
- double a14, double a24, double a34)
- { // Values in COLUMN order!
- m11 = a11; // Row 1
- m12 = a12;
- m13 = a13;
- m14 = a14;
- m21 = a21; // Row 2
- m22 = a22;
- m23 = a23;
- m24 = a24;
- m31 = a31; // Row 3
- m32 = a32;
- m33 = a33;
- m34 = a34;
- }
- inline AffineMapR3::AffineMapR3 (const VectorR3& u, const VectorR3& v,
- const VectorR3& w, const VectorR3& t)
- {
- m11 = u.x; // Column 1
- m21 = u.y;
- m31 = u.z;
- m12 = v.x; // Column 2
- m22 = v.y;
- m32 = v.z;
- m13 = w.x; // Column 3
- m23 = w.y;
- m33 = w.z;
- m14 = t.x; // Column 4
- m24 = t.y;
- m34 = t.z;
- }
- inline AffineMapR3::AffineMapR3 (const LinearMapR3& A, const VectorR3& t)
- {
- m11 = A.m11;
- m12 = A.m12;
- m13 = A.m13;
- m14 = t.x;
- m21 = A.m21;
- m22 = A.m22;
- m23 = A.m23;
- m24 = t.y;
- m31 = A.m31;
- m32 = A.m32;
- m33 = A.m33;
- m34 = t.z;
- }
- inline void AffineMapR3::SetIdentity ( )
- {
- Matrix3x4::SetIdentity();
- }
- inline void AffineMapR3::SetZero( )
- {
- Matrix3x4::SetZero();
- }
- inline VectorR3 AffineMapR3::Solve(const VectorR3& u) const // Returns solution
- {
- return ( Matrix3x4::Solve( u ) );
- }
- inline AffineMapR3& AffineMapR3::operator+= (const Matrix3x4& B)
- {
- m11 += B.m11;
- m21 += B.m21;
- m31 += B.m31;
- m12 += B.m12;
- m22 += B.m22;
- m32 += B.m32;
- m13 += B.m13;
- m23 += B.m23;
- m33 += B.m33;
- m14 += B.m14;
- m24 += B.m24;
- m34 += B.m34;
- return (*this);
- }
- inline AffineMapR3& AffineMapR3::operator-= (const Matrix3x4& B)
- {
- m11 -= B.m11;
- m21 -= B.m21;
- m31 -= B.m31;
- m12 -= B.m12;
- m22 -= B.m22;
- m32 -= B.m32;
- m13 -= B.m13;
- m23 -= B.m23;
- m33 -= B.m33;
- m14 -= B.m14;
- m24 -= B.m24;
- m34 -= B.m34;
- return (*this);
- }
- inline AffineMapR3 operator+ (const AffineMapR3& A, const AffineMapR3& B)
- {
- return( AffineMapR3( A.m11+B.m11, A.m21+B.m21, A.m31+B.m31,
- A.m12+B.m12, A.m22+B.m22, A.m32+B.m32,
- A.m13+B.m13, A.m23+B.m23, A.m33+B.m33,
- A.m14+B.m14, A.m23+B.m24, A.m34+B.m34) );
- }
- inline AffineMapR3 operator+ (const AffineMapR3& A, const Matrix3x3& B)
- {
- return( AffineMapR3( A.m11+B.m11, A.m21+B.m21, A.m31+B.m31,
- A.m12+B.m12, A.m22+B.m22, A.m32+B.m32,
- A.m13+B.m13, A.m23+B.m23, A.m33+B.m33,
- A.m14, A.m23, A.m34 ) );
- }
- inline AffineMapR3 operator+ (const Matrix3x3& B, const AffineMapR3& A)
- {
- return( AffineMapR3( A.m11+B.m11, A.m21+B.m21, A.m31+B.m31,
- A.m12+B.m12, A.m22+B.m22, A.m32+B.m32,
- A.m13+B.m13, A.m23+B.m23, A.m33+B.m33,
- A.m14, A.m23, A.m34 ) );
- }
- inline AffineMapR3 operator- (const AffineMapR3& A, const AffineMapR3& B)
- {
- return( AffineMapR3( A.m11-B.m11, A.m21-B.m21, A.m31-B.m31,
- A.m12-B.m12, A.m22-B.m22, A.m32-B.m32,
- A.m13-B.m13, A.m23-B.m23, A.m33-B.m33,
- A.m14-B.m14, A.m23-B.m24, A.m34-B.m34) );
- }
- inline AffineMapR3 operator- (const AffineMapR3& A, const LinearMapR3& B)
- {
- return ( AffineMapR3( A.m11-B.m11, A.m21-B.m21, A.m31-B.m31,
- A.m12-B.m12, A.m22-B.m22, A.m32-B.m32,
- A.m13-B.m13, A.m23-B.m23, A.m33-B.m33,
- A.m14, A.m23, A.m34 ) );
- }
- inline AffineMapR3 operator- (const LinearMapR3& B, const AffineMapR3& A)
- {
- return( AffineMapR3( A.m11-B.m11, A.m21-B.m21, A.m31-B.m31,
- A.m12-B.m12, A.m22-B.m22, A.m32-B.m32,
- A.m13-B.m13, A.m23-B.m23, A.m33-B.m33,
- A.m14, A.m23, A.m34 ) );
- }
- inline AffineMapR3& AffineMapR3::operator*= (register double b)
- {
- m11 *= b;
- m12 *= b;
- m13 *= b;
- m21 *= b;
- m22 *= b;
- m23 *= b;
- m31 *= b;
- m32 *= b;
- m33 *= b;
- m14 *= b;
- m24 *= b;
- m34 *= b;
- return (*this);
- }
- inline AffineMapR3 operator* (const AffineMapR3& A, register double b)
- {
- return(AffineMapR3( A.m11*b, A.m21*b, A.m31*b,
- A.m12*b, A.m22*b, A.m32*b,
- A.m13*b, A.m23*b, A.m33*b,
- A.m14*b, A.m24*b, A.m34*b ) );
- }
- inline AffineMapR3 operator* (register double b, const AffineMapR3& A)
- {
- return(AffineMapR3( A.m11*b, A.m21*b, A.m31*b,
- A.m12*b, A.m22*b, A.m32*b,
- A.m13*b, A.m23*b, A.m33*b,
- A.m14*b, A.m24*b, A.m34*b ) );
- }
- inline AffineMapR3& AffineMapR3::operator/= (double b)
- {
- register double bInv = 1.0/b;
- *this *= bInv;
- return( *this );
- }
- inline AffineMapR3 operator/ (const AffineMapR3& A, double b)
- {
- register double bInv = 1.0/b;
- return(AffineMapR3( A.m11*bInv, A.m21*bInv, A.m31*bInv,
- A.m12*bInv, A.m22*bInv, A.m32*bInv,
- A.m13*bInv, A.m23*bInv, A.m33*bInv,
- A.m14*bInv, A.m24*bInv, A.m34*bInv ) );
- }
- inline AffineMapR3& AffineMapR3::operator*= (const Matrix3x3& B) // Composition
- {
- OperatorTimesEquals( B );
- return( *this );
- }
- inline AffineMapR3& AffineMapR3::operator*= (const Matrix3x4& B) // Composition
- {
- OperatorTimesEquals( B );
- return( *this );
- }
- // **************************************************************
- // RotationMapR3 class (inlined functions) *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **
- inline RotationMapR3::RotationMapR3()
- {
- SetIdentity();
- return;
- }
- inline RotationMapR3::RotationMapR3( const VectorR3& u, const VectorR3& v,
- const VectorR3& s )
- :Matrix3x3 ( u, v, s )
- { }
- inline RotationMapR3::RotationMapR3(
- double a11, double a21, double a31,
- double a12, double a22, double a32,
- double a13, double a23, double a33)
- // Values specified in column order!!!
- :Matrix3x3 ( a11, a21, a31, a12, a22, a32, a13, a23, a33)
- { }
- inline RotationMapR3 RotationMapR3::Inverse() const // Returns inverse
- {
- return ( RotationMapR3 ( m11, m12, m13, // In column order!
- m21, m22, m23,
- m31, m32, m33 ) );
- }
- inline RotationMapR3& RotationMapR3::Invert() // Converts into inverse.
- {
- register double temp;
- temp = m12;
- m12 = m21;
- m21 = temp;
- temp = m13;
- m13 = m31;
- m31 = temp;
- temp = m23;
- m23 = m32;
- m32 = temp;
- return ( *this );
- }
- inline VectorR3 RotationMapR3::Solve(const VectorR3& u) const // Returns solution
- {
- return( VectorR3( m11*u.x + m21*u.y + m31*u.z,
- m12*u.x + m22*u.y + m32*u.z,
- m13*u.x + m23*u.y + m33*u.z ) );
- }
- inline RotationMapR3& RotationMapR3::operator*= (const RotationMapR3& B) // Matrix product
- {
- OperatorTimesEquals( B );
- return( *this );
- }
- // **************************************************************
- // RigidMapR3 class (inlined functions) *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * **
- inline RigidMapR3::RigidMapR3()
- {
- SetIdentity();
- return;
- }
- inline RigidMapR3::RigidMapR3( const VectorR3& u, const VectorR3& v,
- const VectorR3& s, const VectorR3& t )
- :Matrix3x4 ( u, v, s, t )
- {}
- inline RigidMapR3::RigidMapR3(
- double a11, double a21, double a31,
- double a12, double a22, double a32,
- double a13, double a23, double a33,
- double a14, double a24, double a34)
- // Values specified in column order!!!
- :Matrix3x4 ( a11, a21, a31, a12, a22, a32, a13, a23, a33, a14, a24, a34 )
- {}
- inline RigidMapR3::RigidMapR3( const Matrix3x3& A, const VectorR3& u ) // Set to RotationMap & Vector
- : Matrix3x4( A, u )
- {}
-
- inline RigidMapR3& RigidMapR3::Set( const Matrix3x3& A, const VectorR3& u ) // Set to RotationMap & Vector
- {
- Matrix3x4::Set( A, u );
- return *this;
- }
- inline RigidMapR3& RigidMapR3::SetTranslationPart( const VectorR3& u) // Set the translation part
- {
- SetColumn4( u );
- return *this;
- }
- inline RigidMapR3& RigidMapR3::SetTranslationPart( double x, double y, double z) // Set the translation part
- {
- SetColumn4( x, y, z );
- return *this;
- }
- inline RigidMapR3& RigidMapR3::SetRotationPart( const Matrix3x3& A) // Set the rotation part
- {
- Matrix3x4::Set3x3( A );
- return *this;
- }
-
- inline RigidMapR3& RigidMapR3::operator*= (const RotationMapR3& B) // Composition
- {
- OperatorTimesEquals( B );
- return( *this );
- }
- inline RigidMapR3& RigidMapR3::operator*= (const RigidMapR3& B) // Composition
- {
- OperatorTimesEquals( B );
- return( *this );
- }
- inline RigidMapR3 RigidMapR3::Inverse() const // Returns inverse
- {
- double new14 = -(m11*m14 + m21*m24 + m31*m34);
- double new24 = -(m12*m14 + m22*m24 + m32*m34);
- double new34 = -(m13*m14 + m23*m24 + m33*m34);
- return ( RigidMapR3 ( m11, m12, m13, // In column order!
- m21, m22, m23,
- m31, m32, m33,
- new14, new24, new34 ) );
- }
- inline RigidMapR3& RigidMapR3::Invert() // Converts into inverse.
- {
- double new14 = -(m11*m14 + m21*m24 + m31*m34);
- double new24 = -(m12*m14 + m22*m24 + m32*m34);
- m34 = -(m13*m14 + m23*m24 + m33*m34);
- m14 = new14;
- m24 = new24;
- register double temp;
- temp = m12;
- m12 = m21;
- m21 = temp;
- temp = m13;
- m13 = m31;
- m31 = temp;
- temp = m23;
- m23 = m32;
- m32 = temp;
- return ( *this );
- }
- // ***************************************************************
- // * 3-space vector and matrix utilities (inlined functions) *
- // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
- // Returns the projection of u onto unit v
- inline VectorR3 ProjectToUnit ( const VectorR3& u, const VectorR3& v)
- {
- return (u^v)*v;
- }
- // Returns the projection of u onto the plane perpindicular to the unit vector v
- inline VectorR3 ProjectPerpUnit ( const VectorR3& u, const VectorR3& v)
- {
- return ( u - ((u^v)*v) );
- }
- // Returns the projection of u onto the plane perpindicular to the unit vector v
- // This one is more stable when u and v are nearly equal.
- inline VectorR3 ProjectPerpUnitDiff ( const VectorR3& u, const VectorR3& v)
- {
- VectorR3 ans = u;
- ans -= v;
- ans -= ((ans^v)*v);
- return ans; // ans = (u-v) - ((u-v)^v)*v
- }
- // VectorProjectMap returns map projecting onto a given vector u.
- // u should be a unit vector (otherwise the returned map is
- // scaled according to the magnitude of u.
- inline LinearMapR3 VectorProjectMap( const VectorR3& u )
- {
- double a = u.x*u.y;
- double b = u.x*u.z;
- double c = u.y*u.z;
- return( LinearMapR3( u.x*u.x, a, b,
- a, u.y*u.y, c,
- b, c, u.z*u.z ) );
- }
- // PlaneProjectMap returns map projecting onto a given plane.
- // The plane is the plane orthognal to w.
- // w must be a unit vector (otherwise the returned map is
- // garbage).
- inline LinearMapR3 PlaneProjectMap ( const VectorR3& w )
- {
- double a = -w.x*w.y;
- double b = -w.x*w.z;
- double c = -w.y*w.z;
- return( LinearMapR3( 1.0-w.x*w.x, a, b,
- a, 1.0-w.y*w.y, c,
- b, c, 1.0-w.z*w.z ) );
- }
- // PlaneProjectMap returns map projecting onto a given plane.
- // The plane is the plane containing the two orthonormal vectors u,v.
- // If u, v are orthonormal, this is a projection with scaling.
- // If they are not orthonormal, the results are more difficult
- // to interpret.
- inline LinearMapR3 PlaneProjectMap ( const VectorR3& u, const VectorR3 &v )
- {
- double a = u.x*u.y + v.x*v.y;
- double b = u.x*u.z + v.x*v.z;
- double c = u.y*u.z + v.y*v.z;
- return( LinearMapR3( u.x*u.x+v.x*v.x, a, b,
- a, u.y*u.y+u.y*u.y, c,
- b, c, u.z*u.z+v.z*v.z ) );
- }
- // Returns the solid angle between unit vectors v and w.
- inline double SolidAngle( const VectorR3& v, const VectorR3& w)
- {
- return atan2 ( (v*w).Norm(), v^w );
- }
- #endif
- // ******************* End of header material ********************
|