Path: blob/devel/ElmerGUI/netgen/libsrc/gprim/geomobjects.hpp
3206 views
#ifndef FILE_OBJECTS1#define FILE_OBJECTS23/* *************************************************************************/4/* File: geomobjects.hpp */5/* Author: Joachim Schoeberl */6/* Date: 20. Jul. 02 */7/* *************************************************************************/891011template <int D> class Vec;12template <int D> class Point;131415template <int D>16class Point17{1819protected:20double x[D];2122public:23Point () { ; }24Point (double ax) { x[0] = ax; }25Point (double ax, double ay) { x[0] = ax; x[1] = ay; }26Point (double ax, double ay, double az)27{ x[0] = ax; x[1] = ay; x[2] = az; }28Point (double ax, double ay, double az, double au)29{ x[0] = ax; x[1] = ay; x[2] = az; x[3] = au;}3031Point (const Point<D> & p2)32{ for (int i = 0; i < D; i++) x[i] = p2.x[i]; }3334explicit Point (const Vec<D> & v)35{ for (int i = 0; i < D; i++) x[i] = v(i); }363738Point & operator= (const Point<D> & p2)39{40for (int i = 0; i < D; i++) x[i] = p2.x[i];41return *this;42}4344Point & operator= (double val)45{46for (int i = 0; i < D; i++) x[i] = val;47return *this;48}4950double & operator() (int i) { return x[i]; }51const double & operator() (int i) const { return x[i]; }5253operator const double* () const { return x; }54};555657585960template <int D>61class Vec62{6364protected:65double x[D];6667public:68Vec () { ; } // for (int i = 0; i < D; i++) x[i] = 0; }69Vec (double ax) { for (int i = 0; i < D; i++) x[i] = ax; }70Vec (double ax, double ay) { x[0] = ax; x[1] = ay; }71Vec (double ax, double ay, double az)72{ x[0] = ax; x[1] = ay; x[2] = az; }73Vec (double ax, double ay, double az, double au)74{ x[0] = ax; x[1] = ay; x[2] = az; x[3] = au; }7576Vec (const Vec<D> & p2)77{ for (int i = 0; i < D; i++) x[i] = p2.x[i]; }7879explicit Vec (const Point<D> & p)80{ for (int i = 0; i < D; i++) x[i] = p(i); }8182Vec (const Vec<D> & p1, const Vec<D> & p2)83{ for(int i=0; i<D; i++) x[i] = p2(i)-p1(1); }84858687Vec & operator= (const Vec<D> & p2)88{89for (int i = 0; i < D; i++) x[i] = p2.x[i];90return *this;91}9293Vec & operator= (double s)94{95for (int i = 0; i < D; i++) x[i] = s;96return *this;97}9899double & operator() (int i) { return x[i]; }100const double & operator() (int i) const { return x[i]; }101102operator const double* () const { return x; }103104double Length () const105{106double l = 0;107for (int i = 0; i < D; i++)108l += x[i] * x[i];109return sqrt (l);110}111112double Length2 () const113{114double l = 0;115for (int i = 0; i < D; i++)116l += x[i] * x[i];117return l;118}119120const Vec<D> & Normalize ()121{122double l = Length();123if (l != 0)124for (int i = 0; i < D; i++)125x[i] /= l;126return *this;127}128129Vec<D> GetNormal () const;130};131132133134135136template <int H, int W=H>137class Mat138{139140protected:141double x[H*W];142143public:144Mat () { ; }145Mat (const Mat & b)146{ for (int i = 0; i < H*W; i++) x[i] = b.x[i]; }147148Mat & operator= (double s)149{150for (int i = 0; i < H*W; i++) x[i] = s;151return *this;152}153154Mat & operator= (const Mat & b)155{156for (int i = 0; i < H*W; i++) x[i] = b.x[i];157return *this;158}159160double & operator() (int i, int j) { return x[i*W+j]; }161const double & operator() (int i, int j) const { return x[i*W+j]; }162double & operator() (int i) { return x[i]; }163const double & operator() (int i) const { return x[i]; }164165Vec<H> Col (int i) const166{167Vec<H> hv;168for (int j = 0; j < H; j++)169hv(j) = x[j*W+i];170return hv;171}172173Vec<W> Row (int i) const174{175Vec<W> hv;176for (int j = 0; j < W; j++)177hv(j) = x[i*W+j];178return hv;179}180181void Solve (const Vec<H> & rhs, Vec<W> & sol) const182{183Mat<W,H> inv;184CalcInverse (*this, inv);185sol = inv * rhs;186}187};188189190191192template <int D>193class Box194{195protected:196Point<D> pmin, pmax;197public:198Box () { ; }199Box ( const Point<D> & p1, const Point<D> & p2)200{201for (int i = 0; i < D; i++)202{203pmin(i) = min2(p1(i), p2(i));204pmax(i) = max2(p1(i), p2(i));205}206}207208enum EB_TYPE { EMPTY_BOX = 1 };209Box ( EB_TYPE et )210{211pmin = Point<3> (1e99, 1e99, 1e99);212pmax = Point<3> (-1e99, -1e99, -1e99);213}214215const Point<D> & PMin () const { return pmin; }216const Point<D> & PMax () const { return pmax; }217218void Set (const Point<D> & p)219{ pmin = pmax = p; }220221void Add (const Point<D> & p)222{223for (int i = 0; i < D; i++)224{225if (p(i) < pmin(i)) pmin(i) = p(i);226else if (p(i) > pmax(i)) pmax(i) = p(i);227}228}229230Point<D> Center () const231{232Point<D> c;233for (int i = 0; i < D; i++)234c(i) = 0.5 * (pmin(i)+pmax(i));235return c;236}237double Diam () const { return Abs (pmax-pmin); }238239Point<D> GetPointNr (int nr) const240{241Point<D> p;242for (int i = 0; i < D; i++)243{244p(i) = (nr & 1) ? pmax(i) : pmin(i);245nr >>= 1;246}247return p;248}249250251bool Intersect (const Box<D> & box2) const252{253for (int i = 0; i < D; i++)254if (pmin(i) > box2.pmax(i) ||255pmax(i) < box2.pmin(i)) return 0;256return 1;257}258259260bool IsIn (const Point<D> & p) const261{262for (int i = 0; i < D; i++)263if (p(i) < pmin(i) || p(i) > pmax(i)) return 0;264return 1;265}266267268void Increase (double dist)269{270for (int i = 0; i < D; i++)271{272pmin(i) -= dist;273pmax(i) += dist;274}275}276};277278279280281template <int D>282class BoxSphere : public Box<D>283{284protected:285///286Point<D> c;287///288double diam;289///290double inner;291public:292///293BoxSphere () { };294///295BoxSphere (const Box<D> & box)296: Box<D> (box)297{298CalcDiamCenter();299};300301///302BoxSphere ( Point<D> apmin, Point<D> apmax )303: Box<D> (apmin, apmax)304{305CalcDiamCenter();306}307308///309const Point<D> & Center () const { return c; }310///311double Diam () const { return diam; }312///313double Inner () const { return inner; }314315316///317void GetSubBox (int nr, BoxSphere & sbox) const318{319for (int i = 0; i < D; i++)320{321if (nr & 1)322{323sbox.pmin(i) = c(i);324sbox.pmax(i) = this->pmax(i);325}326else327{328sbox.pmin(i) = this->pmin(i);329sbox.pmax(i) = c(i);330}331sbox.c(i) = 0.5 * (sbox.pmin(i) + sbox.pmax(i));332nr >>= 1;333}334sbox.diam = 0.5 * diam;335sbox.inner = 0.5 * inner;336}337338339///340void CalcDiamCenter ()341{342c = Box<D>::Center ();343diam = Dist (this->pmin, this->pmax);344345inner = this->pmax(0) - this->pmin(0);346for (int i = 1; i < D; i++)347if (this->pmax(i) - this->pmin(i) < inner)348inner = this->pmax(i) - this->pmin(i);349}350351};352353354355356357358#endif359360361