#ifndef FILE_OBJECTS #define FILE_OBJECTS /* *************************************************************************/ /* File: geomobjects.hpp */ /* Author: Joachim Schoeberl */ /* Date: 20. Jul. 02 */ /* *************************************************************************/ namespace netgen { template class Vec; template class Point; template class Point : public ngsimd::AlignedAlloc> { protected: T x[D]; public: Point () { ; } Point (T ax) { for (int i = 0; i < D; i++) x[i] = ax; } Point (T ax, T ay) { // static_assert(D==2, "Point constructor with 2 args called"); x[0] = ax; x[1] = ay; } Point (T ax, T ay, T az) { // static_assert(D==3, "Point constructor with 3 args called"); x[0] = ax; x[1] = ay; x[2] = az; } Point (T ax, T ay, T az, T au) { x[0] = ax; x[1] = ay; x[2] = az; x[3] = au;} template Point (const Point & p2) { for (int i = 0; i < D; i++) x[i] = p2(i); } explicit Point (const Vec & v) { for (int i = 0; i < D; i++) x[i] = v(i); } template Point & operator= (const Point & p2) { for (int i = 0; i < D; i++) x[i] = p2(i); return *this; } Point & operator= (T val) { for (int i = 0; i < D; i++) x[i] = val; return *this; } T & operator() (int i) { return x[i]; } const T & operator() (int i) const { return x[i]; } operator const T* () const { return x; } }; template class Vec : public ngsimd::AlignedAlloc> { protected: T x[D]; public: Vec () { ; } // for (int i = 0; i < D; i++) x[i] = 0; } Vec (T ax) { for (int i = 0; i < D; i++) x[i] = ax; } Vec (T ax, T ay) { // static_assert(D==2, "Vec constructor with 2 args called"); x[0] = ax; x[1] = ay; } Vec (T ax, T ay, T az) { // static_assert(D==3, "Vec constructor with 3 args called"); x[0] = ax; x[1] = ay; x[2] = az; } Vec (T ax, T ay, T az, T au) { x[0] = ax; x[1] = ay; x[2] = az; x[3] = au; } Vec (const Vec & p2) { for (int i = 0; i < D; i++) x[i] = p2.x[i]; } explicit Vec (const Point & p) { for (int i = 0; i < D; i++) x[i] = p(i); } Vec (const Vec & p1, const Vec & p2) { for(int i=0; i Vec & operator= (const Vec & p2) { for (int i = 0; i < D; i++) x[i] = p2(i); return *this; } Vec & operator= (T s) { for (int i = 0; i < D; i++) x[i] = s; return *this; } T & operator() (int i) { return x[i]; } const T & operator() (int i) const { return x[i]; } operator const T* () const { return x; } T Length () const { T l = 0; for (int i = 0; i < D; i++) l += x[i] * x[i]; return sqrt (l); } T Length2 () const { T l = 0; for (int i = 0; i < D; i++) l += x[i] * x[i]; return l; } Vec & Normalize () { T l = Length(); // if (l != 0) for (int i = 0; i < D; i++) x[i] /= (l+1e-40); return *this; } Vec GetNormal () const; }; template class Mat : public ngsimd::AlignedAlloc> { protected: T x[H*W]; public: Mat () { ; } Mat (const Mat & b) { for (int i = 0; i < H*W; i++) x[i] = b.x[i]; } Mat & operator= (T s) { for (int i = 0; i < H*W; i++) x[i] = s; return *this; } Mat & operator= (const Mat & b) { for (int i = 0; i < H*W; i++) x[i] = b.x[i]; return *this; } T & operator() (int i, int j) { return x[i*W+j]; } const T & operator() (int i, int j) const { return x[i*W+j]; } T & operator() (int i) { return x[i]; } const T & operator() (int i) const { return x[i]; } Vec Col (int i) const { Vec hv; for (int j = 0; j < H; j++) hv(j) = x[j*W+i]; return hv; } Vec Row (int i) const { Vec hv; for (int j = 0; j < W; j++) hv(j) = x[i*W+j]; return hv; } void Solve (const Vec & rhs, Vec & sol) const { Mat inv; CalcInverse (*this, inv); sol = inv * rhs; } }; template class Box { protected: Point pmin, pmax; public: Box () { ; } Box ( const Point & p1) { for (int i = 0; i < D; i++) pmin(i) = pmax(i) = p1(i); } Box ( const Point & p1, const Point & p2) { for (int i = 0; i < D; i++) { pmin(i) = min2(p1(i), p2(i)); pmax(i) = max2(p1(i), p2(i)); } } enum EB_TYPE { EMPTY_BOX = 1 }; Box ( EB_TYPE et ) { for (int i = 0; i < D; i++) { pmin(i) = 1e99; pmax(i) = -1e99; } // pmin = Point (1e99, 1e99, 1e99); // pmax = Point (-1e99, -1e99, -1e99); } const Point & PMin () const { return pmin; } const Point & PMax () const { return pmax; } void Set (const Point & p) { pmin = pmax = p; } void Add (const Point & p) { for (int i = 0; i < D; i++) { if (p(i) < pmin(i)) pmin(i) = p(i); else if (p(i) > pmax(i)) pmax(i) = p(i); } } template void Set (const IndirectArray & points) { Set (points[points.Begin()]); for (int i = points.Begin()+1; i < points.End(); i++) Add (points[i]); } template void Add (const IndirectArray & points) { for (int i = points.Begin(); i < points.End(); i++) Add (points[i]); } Point Center () const { Point c; for (int i = 0; i < D; i++) c(i) = 0.5 * (pmin(i)+pmax(i)); return c; } double Diam () const { return Abs (pmax-pmin); } Point GetPointNr (int nr) const { Point p; for (int i = 0; i < D; i++) { p(i) = (nr & 1) ? pmax(i) : pmin(i); nr >>= 1; } return p; } bool Intersect (const Box & box2) const { for (int i = 0; i < D; i++) if (pmin(i) > box2.pmax(i) || pmax(i) < box2.pmin(i)) return 0; return 1; } bool IsIn (const Point & p) const { for (int i = 0; i < D; i++) if (p(i) < pmin(i) || p(i) > pmax(i)) return 0; return 1; } void Increase (double dist) { for (int i = 0; i < D; i++) { pmin(i) -= dist; pmax(i) += dist; } } }; template class BoxSphere : public Box { protected: /// Point c; /// double diam; /// double inner; public: /// BoxSphere () { }; /// BoxSphere (const Box & box) : Box (box) { CalcDiamCenter(); }; /// BoxSphere ( Point apmin, Point apmax ) : Box (apmin, apmax) { CalcDiamCenter(); } /// const Point & Center () const { return c; } /// double Diam () const { return diam; } /// double Inner () const { return inner; } /// void GetSubBox (int nr, BoxSphere & sbox) const { for (int i = 0; i < D; i++) { if (nr & 1) { sbox.pmin(i) = c(i); sbox.pmax(i) = this->pmax(i); } else { sbox.pmin(i) = this->pmin(i); sbox.pmax(i) = c(i); } sbox.c(i) = 0.5 * (sbox.pmin(i) + sbox.pmax(i)); nr >>= 1; } sbox.diam = 0.5 * diam; sbox.inner = 0.5 * inner; } /// void CalcDiamCenter () { c = Box::Center (); diam = Dist (this->pmin, this->pmax); inner = this->pmax(0) - this->pmin(0); for (int i = 1; i < D; i++) if (this->pmax(i) - this->pmin(i) < inner) inner = this->pmax(i) - this->pmin(i); } }; #ifdef PARALLEL template <> inline MPI_Datatype MyGetMPIType > () { static MPI_Datatype MPI_T = 0; if (!MPI_T) { MPI_Type_contiguous ( 3, MPI_DOUBLE, &MPI_T); MPI_Type_commit ( &MPI_T ); } return MPI_T; }; #endif } #endif