00001
00002 #ifndef __H_GEOMETRY_H_
00003 #define __H_GEOMETRY_H_
00004
00005 #include "H_Standard.h"
00006
00007 #include <fstream>
00008 #include <math.h>
00009 #include <assert.h>
00010
00011 #define FOR_I(code) for(unsigned int i=dim;i--;) {code}
00012
00013
00014
00015 template <unsigned int dim, class type> class Point
00016 {
00017
00018 public:
00019 enum t_dimName {X=0,Y=1,Z=2,W=3};
00020 type p[dim];
00021 public:
00022 inline type &operator[] (unsigned int i) {return p[i];}
00023 inline const type &operator[] (unsigned int i) const {return p[i];}
00024 inline Point() {}
00025 template <class type_b> Point(const Point<dim,type_b> &A) {FOR_I(p[i]=type(A[i]);)}
00026 inline Point(type x, type y)
00027 {assert(dim==2); p[X]=x;p[Y]=y;}
00028 inline Point(type x, type y, type z)
00029 {assert(dim==3); p[X]=x;p[Y]=y;p[Z]=z;}
00030 inline Point(type x, type y, type z, type w)
00031 {assert(dim==4); p[X]=x;p[Y]=y;p[Z]=z;p[W]=w;}
00032 inline const type &x() const {return p[X];}
00033 inline const type &y() const {return p[Y];}
00034 inline const type &z() const {return p[Z];}
00035 inline const type &w() const {return p[W];}
00036 inline type &x() {return p[X];}
00037 inline type &y() {return p[Y];}
00038 inline type &z() {return p[Z];}
00039 inline type &w() {return p[W];}
00040 bool isNull() const
00041 {FOR_I(if(p[i]!=0) return false;) return true;}
00042 void reset()
00043 {FOR_I(p[i]=0;)}
00044 bool operator== (const Point &A) const
00045 {FOR_I(if(p[i]!=A.p[i]) return false;) return true;}
00046 bool operator!= (const Point &A) const
00047 {return !(*this == A);}
00048 Point operator* (type e) const
00049 {Point tmp;FOR_I(tmp.p[i]=p[i]*e;) return tmp;}
00050 Point operator- (const Point &A) const
00051 {Point tmp;FOR_I(tmp.p[i]=p[i]-A.p[i];) return tmp;}
00052 Point operator- () const
00053 {Point tmp;FOR_I(tmp.p[i]=-p[i];) return tmp;}
00054 Point operator+ (const Point &A) const
00055 {Point tmp;FOR_I(tmp.p[i]=p[i]+A.p[i];) return tmp;}
00056 type operator* (const Point &A) const
00057 {type sum=0;FOR_I(sum+=p[i]*A.p[i];) return sum;}
00058 Point operator/ (type e) const
00059 {Point tmp;FOR_I(tmp.p[i]=p[i]/e;) return tmp;}
00060 Point &operator/= (type e)
00061 {FOR_I(p[i]/=e;) return *this;}
00062 Point &operator+= (const Point &A)
00063 {FOR_I(p[i]+=A.p[i];) return *this;}
00064 Point &operator-= (const Point &A)
00065 {FOR_I(p[i]-=A.p[i];) return *this;}
00066
00067 type norm() const {type sum=0; FOR_I(sum+=p[i]*p[i];) return type(sqrt(double(sum)));}
00068 type normalize() {type tmp=norm();*this=*this/tmp;return tmp;}
00069 type normalize(type length) {type tmp=norm();*this=*this*(length/tmp);return tmp;}
00070 type distance(const Point &A) const {return (*this-A).norm();}
00071
00072
00073
00074 };
00075
00076
00077 template <unsigned int dim, class type>
00078 istream & operator>> (istream &in, Point<dim,type> &A)
00079 {for(unsigned int i=0; i<dim ; i++){in>>A.p[i];} return in;}
00080
00081 template <unsigned int dim, class type>
00082 ostream & operator<< (ostream &out, const Point<dim,type> &A)
00083 {for(unsigned int i=0; i<dim ; i++){out<<A.p[i]<<" ";} return out;}
00084
00085 template <unsigned int dim, class type>
00086 Point<dim,type> operator* (type e, const Point<dim,type> &A)
00087 {
00088 Point<dim,type> tmp;
00089 FOR_I(tmp.p[i]=e*A.p[i];)
00090 return tmp;
00091 }
00092
00093 template <class type>
00094 Point<3,type> operator^ (const Point<3,type> &A, const Point<3,type> &B)
00095 {
00096 return Point<3,type>(
00097 (A.y()*B.z()-A.z()*B.y()),
00098 (A.z()*B.x()-A.x()*B.z()),
00099 (A.x()*B.y()-A.y()*B.x())
00100 );
00101 }
00102
00103 template <class type> void RotateAround(Point<3,type> &A, Point<3,type> B)
00104 {
00105 Point<3,type> tmp(A);
00106 type angle = B.normalize();
00107
00108 type s, c;
00109 type xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c;
00110
00111 s = (type)sin((double)angle);
00112 c = (type)cos((double)angle);
00113
00114 if (angle>0)
00115 {
00116 xx = B.x() * B.x();
00117 yy = B.y() * B.y();
00118 zz = B.z() * B.z();
00119 xy = B.x() * B.y();
00120 yz = B.y() * B.z();
00121 zx = B.z() * B.x();
00122 xs = B.x() * s;
00123 ys = B.y() * s;
00124 zs = B.z() * s;
00125 one_c = 1 - c;
00126
00127 A.x() = ((one_c * xx) + c)*tmp.x() + ((one_c * xy) - zs)*tmp.y() + ((one_c * zx) + ys)*tmp.z();
00128 A.y() = ((one_c * xy) + zs)*tmp.x() + ((one_c * yy) + c)*tmp.y() + ((one_c * yz) - xs)*tmp.z();
00129 A.z() = ((one_c * zx) - ys)*tmp.x() + ((one_c * yz) + xs)*tmp.y() + ((one_c * zz) + c)*tmp.z();
00130 }
00131 }
00132
00133 typedef Point<2,REAL> Point2D;
00134 typedef Point<3,REAL> Point3D;
00135
00136
00137 class HRect
00138 {
00139 public:
00140 REAL left, top, right, bottom;
00141 public:
00142 HRect();
00143 HRect(REAL l, REAL t, REAL r, REAL b );
00144 HRect(const Point2D &A, const Point2D &B);
00145 REAL GetWidth() const;
00146 REAL GetHeight() const;
00147 bool IsContained(const Point2D &APoint2D);
00148 bool IsContained(const HRect &HRect);
00149 void Scale(REAL factor);
00150 void Move(const Point2D &Vector);
00151 Point2D GetCenter() const;
00152 };
00153
00154 class Ref
00155 {
00156 public:
00157 Point3D X,Y,Z;
00158 Point3D Position;
00159 Point3D Speed,Momentum;
00160 static REAL TimeIncrement;
00161
00162 public:
00163 Ref();
00164 Ref(const Point3D &APosition, const Point3D &AY, const Point3D &AZ);
00165 void reset();
00166 Point3D GetAbsCoord(const Point3D &RelPos) const;
00167 Ref GetRef(const Point3D &RelPos) const;
00168 Ref GetRef(const Ref &ARef) const;
00169 void Straighten();
00170 void Move(const Point3D &point);
00171 void Rotate(const Point3D &Axe);
00172 Point3D GetDirection() const;
00173 Point3D GetUp() const;
00174 Point3D GetW() const;
00175 Point3D GetX() const;
00176 Point3D GetY() const;
00177 Point3D GetZ() const;
00178 };
00179 istream &operator >> (istream &infile, Ref &ARef);
00180 ostream &operator << (ostream &outfile, const Ref &ARef);
00181
00182 class FixedVector
00183 {
00184 public:
00185 FixedVector();
00186 FixedVector(const Point3D &APosition, const Point3D &AValue);
00187 void reset();
00188 public:
00189 Point3D Position;
00190 Point3D Value;
00191 };
00192
00193 class InertRef : public Ref
00194 {
00195 private:
00196 Point3D SigmaForce;
00197 Point3D SigmaForceMoment;
00198 REAL Mass, RotInertia;
00199 public:
00200 inline REAL GetMass() {return Mass;}
00201 InertRef();
00202 InertRef(REAL AMass, REAL ARotInertia);
00203 void Apply(const FixedVector &AForce);
00204 void TimeClick();
00205 };
00206
00207 class Contact
00208 {
00209 public:
00210 Contact();
00211 public:
00212 Point3D Position;
00213 Point3D Normal;
00214 int SurfaceType;
00215 bool Found;
00216 };
00217
00218 unsigned int LargestPowOf2(unsigned int x);
00219
00220
00221 #endif //__H_GEOMETRY_H_