Path: blob/devel/ElmerGUI/netgen/libsrc/gprim/geom3d.hpp
3206 views
#ifndef FILE_GEOM3D1#define FILE_GEOM3D23/* *************************************************************************/4/* File: geom3d.hh */5/* Author: Joachim Schoeberl */6/* Date: 5. Aug. 95 */7/* *************************************************************************/89101112extern void MyError (const char * ch);1314class Point3d;15class Vec3d;1617inline Vec3d operator- (const Point3d & p1, const Point3d & p2);18inline Point3d operator- (const Point3d & p1, const Vec3d & v);19inline Point3d operator+ (const Point3d & p1, const Vec3d & v);20Point3d & Add (double d, const Vec3d & v);21Point3d & Add2 (double d, const Vec3d & v,22double d2, const Vec3d & v2);23inline Point3d Center (const Point3d & p1, const Point3d & p2);24inline Point3d Center (const Point3d & p1, const Point3d & p2, const Point3d & p3);25inline Point3d Center (const Point3d & p1, const Point3d & p2,26const Point3d & p3, const Point3d & p4);27ostream & operator<<(ostream & s, const Point3d & p);28inline Vec3d operator- (const Vec3d & p1, const Vec3d & v);29inline Vec3d operator+ (const Vec3d & p1, const Vec3d & v);30inline Vec3d operator* (double scal, const Vec3d & v);31inline double operator* (const Vec3d & v1, const Vec3d & v2);32inline Vec3d Cross (const Vec3d & v1, const Vec3d & v2);33inline void Cross (const Vec3d & v1, const Vec3d & v2, Vec3d & prod);34double Angle (const Vec3d & v);35double FastAngle (const Vec3d & v);36double Angle (const Vec3d & v1, const Vec3d & v2);37double FastAngle (const Vec3d & v1, const Vec3d & v2);38ostream & operator<<(ostream & s, const Vec3d & v);39void Transpose (Vec3d & v1, Vec3d & v2, Vec3d & v3);40int SolveLinearSystem (const Vec3d & col1,41const Vec3d & col2,42const Vec3d & col3,43const Vec3d & rhs,44Vec3d & sol);45int SolveLinearSystemLS (const Vec3d & col1,46const Vec3d & col2,47const Vec2d & rhs,48Vec3d & sol);49int SolveLinearSystemLS2 (const Vec3d & col1,50const Vec3d & col2,51const Vec2d & rhs,52Vec3d & sol,53double & x, double & y);54int PseudoInverse (const Vec3d & col1,55const Vec3d & col2,56Vec3d & inv1,57Vec3d & inv2);58double Determinant (const Vec3d & col1,59const Vec3d & col2,60const Vec3d & col3);6162/// Point in R363class Point3d64{65protected:66///67double x[3];6869public:70///71Point3d () { x[0] = x[1] = x[2] = 0; }72///73Point3d(double ax, double ay, double az)74{ x[0] = ax; x[1] = ay; x[2] = az; }75///76Point3d(double ax[3])77{ x[0] = ax[0]; x[1] = ax[1]; x[2] = ax[2]; }7879///80Point3d(const Point3d & p2)81{ x[0] = p2.x[0]; x[1] = p2.x[1]; x[2] = p2.x[2]; }8283Point3d (const Point<3> & p2)84{85for (int i = 0; i < 3; i++)86x[i] = p2(i);87}8889///90Point3d & operator= (const Point3d & p2)91{ x[0] = p2.x[0]; x[1] = p2.x[1]; x[2] = p2.x[2]; return *this; }9293///94int operator== (const Point3d& p) const95{ return (x[0] == p.x[0] && x[1] == p.x[1] && x[2] == p.x[2]); }9697///98double & X() { return x[0]; }99///100double & Y() { return x[1]; }101///102double & Z() { return x[2]; }103///104double X() const { return x[0]; }105///106double Y() const { return x[1]; }107///108double Z() const { return x[2]; }109///110double & X(int i) { return x[i-1]; }111///112double X(int i) const { return x[i-1]; }113///114const Point3d & SetToMin (const Point3d & p2)115{116if (p2.x[0] < x[0]) x[0] = p2.x[0];117if (p2.x[1] < x[1]) x[1] = p2.x[1];118if (p2.x[2] < x[2]) x[2] = p2.x[2];119return *this;120}121122///123const Point3d & SetToMax (const Point3d & p2)124{125if (p2.x[0] > x[0]) x[0] = p2.x[0];126if (p2.x[1] > x[1]) x[1] = p2.x[1];127if (p2.x[2] > x[2]) x[2] = p2.x[2];128return *this;129}130131///132friend inline Vec3d operator- (const Point3d & p1, const Point3d & p2);133///134friend inline Point3d operator- (const Point3d & p1, const Vec3d & v);135///136friend inline Point3d operator+ (const Point3d & p1, const Vec3d & v);137///138inline Point3d & operator+= (const Vec3d & v);139inline Point3d & operator-= (const Vec3d & v);140///141inline Point3d & Add (double d, const Vec3d & v);142///143inline Point3d & Add2 (double d, const Vec3d & v,144double d2, const Vec3d & v2);145///146friend inline double Dist (const Point3d & p1, const Point3d & p2)147{ return sqrt ( (p1.x[0]-p2.x[0]) * (p1.x[0]-p2.x[0]) +148(p1.x[1]-p2.x[1]) * (p1.x[1]-p2.x[1]) +149(p1.x[2]-p2.x[2]) * (p1.x[2]-p2.x[2])); }150///151inline friend double Dist2 (const Point3d & p1, const Point3d & p2)152{ return ( (p1.x[0]-p2.x[0]) * (p1.x[0]-p2.x[0]) +153(p1.x[1]-p2.x[1]) * (p1.x[1]-p2.x[1]) +154(p1.x[2]-p2.x[2]) * (p1.x[2]-p2.x[2])); }155156///157friend inline Point3d Center (const Point3d & p1, const Point3d & p2);158///159friend inline Point3d Center (const Point3d & p1, const Point3d & p2, const Point3d & p3);160///161friend inline Point3d Center (const Point3d & p1, const Point3d & p2,162const Point3d & p3, const Point3d & p4);163///164friend ostream & operator<<(ostream & s, const Point3d & p);165166///167friend class Vec3d;168///169friend class Box3d;170171172operator Point<3> () const173{174return Point<3> (x[0], x[1], x[2]);175}176};177178179///180class Vec3d181{182protected:183///184double x[3];185186public:187///188inline Vec3d() { x[0] = x[1] = x[2] = 0; }189///190inline Vec3d(double ax, double ay, double az)191{ x[0] = ax; x[1] = ay; x[2] = az; }192///193Vec3d(double ax[3])194{ x[0] = ax[0]; x[1] = ax[1]; x[2] = ax[2]; }195///196inline Vec3d(const Vec3d & v2)197{ x[0] = v2.x[0]; x[1] = v2.x[1]; x[2] = v2.x[2]; }198///199inline Vec3d(const Point3d & p1, const Point3d & p2)200{201x[0] = p2.x[0] - p1.x[0];202x[1] = p2.x[1] - p1.x[1];203x[2] = p2.x[2] - p1.x[2];204}205///206inline Vec3d(const Point3d & p1)207{208x[0] = p1.x[0];209x[1] = p1.x[1];210x[2] = p1.x[2];211}212213Vec3d (const Vec<3> & v2)214{215for (int i = 0; i < 3; i++)216x[i] = v2(i);217}218219operator Vec<3> () const220{221return Vec<3> (x[0], x[1], x[2]);222}223224225Vec3d & operator= (const Vec3d & v2)226{ x[0] = v2.x[0]; x[1] = v2.x[1]; x[2] = v2.x[2]; return *this; }227///228Vec3d & operator= (double val)229{ x[0] = x[1] = x[2] = val; return *this; }230///231double & X() { return x[0]; }232///233double & Y() { return x[1]; }234///235double & Z() { return x[2]; }236///237double & X(int i) { return x[i-1]; }238239///240double X() const { return x[0]; }241///242double Y() const { return x[1]; }243///244double Z() const { return x[2]; }245///246double X(int i) const { return x[i-1]; }247248///249double Length() const250{ return sqrt (x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); }251///252double Length2() const253{ return x[0] * x[0] + x[1] * x[1] + x[2] * x[2]; }254255///256Vec3d & operator+= (const Vec3d & v2);257///258Vec3d & operator-= (const Vec3d & v2);259///260Vec3d & operator*= (double s);261///262Vec3d & operator/= (double s);263///264inline Vec3d & Add (double d, const Vec3d & v);265///266inline Vec3d & Add2 (double d, const Vec3d & v,267double d2, const Vec3d & v2);268269///270friend inline Vec3d operator- (const Point3d & p1, const Point3d & p2);271///272friend inline Point3d operator- (const Point3d & p1, const Vec3d & v);273///274friend inline Point3d operator+ (const Point3d & p1, const Vec3d & v);275///276friend inline Vec3d operator- (const Vec3d & p1, const Vec3d & v);277///278friend inline Vec3d operator+ (const Vec3d & p1, const Vec3d & v);279///280friend inline Vec3d operator* (double scal, const Vec3d & v);281282///283friend inline double operator* (const Vec3d & v1, const Vec3d & v2);284///285friend inline Vec3d Cross (const Vec3d & v1, const Vec3d & v2);286///287friend inline void Cross (const Vec3d & v1, const Vec3d & v2, Vec3d & prod);288289/// Returns one normal-vector to n290void GetNormal (Vec3d & n) const;291///292friend double Angle (const Vec3d & v);293///294friend double FastAngle (const Vec3d & v);295///296friend double Angle (const Vec3d & v1, const Vec3d & v2);297///298friend double FastAngle (const Vec3d & v1, const Vec3d & v2);299300void Normalize()301{302double len = (x[0] * x[0] + x[1] * x[1] + x[2] * x[2]);303if (len == 0) return;304len = sqrt (len);305x[0] /= len; x[1] /= len; x[2] /= len;306}307308///309friend ostream & operator<<(ostream & s, const Vec3d & v);310311///312friend class Point3d;313friend void Transpose (Vec3d & v1, Vec3d & v2, Vec3d & v3);314friend int SolveLinearSystem (const Vec3d & col1,315const Vec3d & col2,316const Vec3d & col3,317const Vec3d & rhs,318Vec3d & sol);319friend int SolveLinearSystemLS (const Vec3d & col1,320const Vec3d & col2,321const Vec2d & rhs,322Vec3d & sol);323friend int SolveLinearSystemLS2 (const Vec3d & col1,324const Vec3d & col2,325const Vec2d & rhs,326Vec3d & sol,327double & x, double & y);328friend int PseudoInverse (const Vec3d & col1,329const Vec3d & col2,330Vec3d & inv1,331Vec3d & inv2);332friend double Determinant (const Vec3d & col1,333const Vec3d & col2,334const Vec3d & col3);335};336337338339class QuadraticFunction3d340{341double c0, cx, cy, cz;342double cxx, cyy, czz, cxy, cxz, cyz;343344public:345QuadraticFunction3d (const Point3d & p, const Vec3d & v);346double Eval (const Point3d & p)347{348return349c0350+ p.X() * (cx + cxx * p.X() + cxy * p.Y() + cxz * p.Z())351+ p.Y() * (cy + cyy * p.Y() + cyz * p.Z())352+ p.Z() * (cz + czz * p.Z());353}354};355356357358inline Point3d Center (const Point3d & p1, const Point3d & p2)359{360return Point3d (0.5 * (p1.x[0] + p2.x[0]),3610.5 * (p1.x[1] + p2.x[1]),3620.5 * (p1.x[2] + p2.x[2]));363}364365366inline Point3d Center (const Point3d & p1, const Point3d & p2,367const Point3d & p3)368{369return Point3d (1.0/3.0 * (p1.x[0] + p2.x[0] + p3.x[0]),3701.0/3.0 * (p1.x[1] + p2.x[1] + p3.x[1]),3711.0/3.0 * (p1.x[2] + p2.x[2] + p3.x[2]));372}373374inline Point3d Center (const Point3d & p1, const Point3d & p2,375const Point3d & p3, const Point3d & p4)376{377return Point3d (0.25 * (p1.x[0] + p2.x[0] + p3.x[0] + p4.x[0]),3780.25 * (p1.x[1] + p2.x[1] + p3.x[1] + p4.x[1]),3790.25 * (p1.x[2] + p2.x[2] + p3.x[2] + p4.x[2]));380}381382383384inline Vec3d & Vec3d :: operator+= (const Vec3d & v2)385{386x[0] += v2.x[0];387x[1] += v2.x[1];388x[2] += v2.x[2];389return *this;390}391392inline Vec3d & Vec3d :: operator-= (const Vec3d & v2)393{394x[0] -= v2.x[0];395x[1] -= v2.x[1];396x[2] -= v2.x[2];397return *this;398}399400401inline Vec3d & Vec3d :: operator*= (double s)402{403x[0] *= s;404x[1] *= s;405x[2] *= s;406return *this;407}408409410inline Vec3d & Vec3d :: operator/= (double s)411{412if (s != 0)413{414x[0] /= s;415x[1] /= s;416x[2] /= s;417}418#ifdef DEBUG419else420{421cerr << "Vec div by 0, v = " << (*this) << endl;422// MyError ("Vec3d::operator /=: Divisioin by zero");423}424#endif425return *this;426}427428inline Vec3d & Vec3d::Add (double d, const Vec3d & v)429{430x[0] += d * v.x[0];431x[1] += d * v.x[1];432x[2] += d * v.x[2];433return *this;434}435436inline Vec3d & Vec3d::Add2 (double d, const Vec3d & v,437double d2, const Vec3d & v2)438{439x[0] += d * v.x[0] + d2 * v2.x[0];440x[1] += d * v.x[1] + d2 * v2.x[1];441x[2] += d * v.x[2] + d2 * v2.x[2];442return *this;443}444445446447448449450451452inline Vec3d operator- (const Point3d & p1, const Point3d & p2)453{454return Vec3d (p1.x[0] - p2.x[0], p1.x[1] - p2.x[1],p1.x[2] - p2.x[2]);455}456457458inline Point3d operator- (const Point3d & p1, const Vec3d & v)459{460return Point3d (p1.x[0] - v.x[0], p1.x[1] - v.x[1],p1.x[2] - v.x[2]);461}462463464inline Point3d operator+ (const Point3d & p1, const Vec3d & v)465{466return Point3d (p1.x[0] + v.x[0], p1.x[1] + v.x[1],p1.x[2] + v.x[2]);467}468469inline Point3d & Point3d::operator+= (const Vec3d & v)470{471x[0] += v.x[0];472x[1] += v.x[1];473x[2] += v.x[2];474return *this;475}476477inline Point3d & Point3d::operator-= (const Vec3d & v)478{479x[0] -= v.x[0];480x[1] -= v.x[1];481x[2] -= v.x[2];482return *this;483}484485inline Point3d & Point3d::Add (double d, const Vec3d & v)486{487x[0] += d * v.x[0];488x[1] += d * v.x[1];489x[2] += d * v.x[2];490return *this;491}492493inline Point3d & Point3d::Add2 (double d, const Vec3d & v,494double d2, const Vec3d & v2)495{496x[0] += d * v.x[0] + d2 * v2.x[0];497x[1] += d * v.x[1] + d2 * v2.x[1];498x[2] += d * v.x[2] + d2 * v2.x[2];499return *this;500}501502503inline Vec3d operator- (const Vec3d & v1, const Vec3d & v2)504{505return Vec3d (v1.x[0] - v2.x[0], v1.x[1] - v2.x[1],v1.x[2] - v2.x[2]);506}507508509inline Vec3d operator+ (const Vec3d & v1, const Vec3d & v2)510{511return Vec3d (v1.x[0] + v2.x[0], v1.x[1] + v2.x[1],v1.x[2] + v2.x[2]);512}513514515inline Vec3d operator* (double scal, const Vec3d & v)516{517return Vec3d (scal * v.x[0], scal * v.x[1], scal * v.x[2]);518}519520521522inline double operator* (const Vec3d & v1, const Vec3d & v2)523{524return v1.x[0] * v2.x[0] + v1.x[1] * v2.x[1] + v1.x[2] * v2.x[2];525}526527528529inline Vec3d Cross (const Vec3d & v1, const Vec3d & v2)530{531return Vec3d532( v1.x[1] * v2.x[2] - v1.x[2] * v2.x[1],533v1.x[2] * v2.x[0] - v1.x[0] * v2.x[2],534v1.x[0] * v2.x[1] - v1.x[1] * v2.x[0]);535}536537inline void Cross (const Vec3d & v1, const Vec3d & v2, Vec3d & prod)538{539prod.x[0] = v1.x[1] * v2.x[2] - v1.x[2] * v2.x[1];540prod.x[1] = v1.x[2] * v2.x[0] - v1.x[0] * v2.x[2];541prod.x[2] = v1.x[0] * v2.x[1] - v1.x[1] * v2.x[0];542}543544inline double Determinant (const Vec3d & col1,545const Vec3d & col2,546const Vec3d & col3)547{548return549col1.x[0] * ( col2.x[1] * col3.x[2] - col2.x[2] * col3.x[1]) +550col1.x[1] * ( col2.x[2] * col3.x[0] - col2.x[0] * col3.x[2]) +551col1.x[2] * ( col2.x[0] * col3.x[1] - col2.x[1] * col3.x[0]);552}553554555///556class Box3d557{558protected:559///560double minx[3], maxx[3];561562public:563///564Box3d () { };565///566Box3d ( double aminx, double amaxx,567double aminy, double amaxy,568double aminz, double amaxz );569///570Box3d ( const Box3d & b2 );571///572Box3d (const Point3d& p1, const Point3d& p2);573///574Box3d (const Box<3> & b2);575///576double MinX () const { return minx[0]; }577///578double MaxX () const { return maxx[0]; }579///580double MinY () const { return minx[1]; }581///582double MaxY () const { return maxx[1]; }583///584double MinZ () const { return minx[2]; }585///586double MaxZ () const { return maxx[2]; }587588///589double Mini (int i) const { return minx[i-1]; }590///591double Maxi (int i) const { return maxx[i-1]; }592593///594Point3d PMin () const { return Point3d(minx[0], minx[1], minx[2]); }595///596Point3d PMax () const { return Point3d(maxx[0], maxx[1], maxx[2]); }597598///599void GetPointNr (int i, Point3d & point) const;600/// increase Box at each side with dist601void Increase (double dist);602/// increase Box by factor rel603void IncreaseRel (double rel);604/// return 1 if closures are intersecting605int Intersect (const Box3d & box2) const606{607if (minx[0] > box2.maxx[0] || maxx[0] < box2.minx[0] ||608minx[1] > box2.maxx[1] || maxx[1] < box2.minx[1] ||609minx[2] > box2.maxx[2] || maxx[2] < box2.minx[2])610return 0;611return 1;612}613/// return 1 if point p in closure614int IsIn (const Point3d & p) const615{616if (minx[0] <= p.x[0] && maxx[0] >= p.x[0] &&617minx[1] <= p.x[1] && maxx[1] >= p.x[1] &&618minx[2] <= p.x[2] && maxx[2] >= p.x[2])619return 1;620return 0;621}622///623inline void SetPoint (const Point3d & p)624{625minx[0] = maxx[0] = p.X();626minx[1] = maxx[1] = p.Y();627minx[2] = maxx[2] = p.Z();628}629630///631inline void AddPoint (const Point3d & p)632{633if (p.x[0] < minx[0]) minx[0] = p.x[0];634if (p.x[0] > maxx[0]) maxx[0] = p.x[0];635if (p.x[1] < minx[1]) minx[1] = p.x[1];636if (p.x[1] > maxx[1]) maxx[1] = p.x[1];637if (p.x[2] < minx[2]) minx[2] = p.x[2];638if (p.x[2] > maxx[2]) maxx[2] = p.x[2];639}640641///642const Box3d& operator+=(const Box3d& b);643644///645Point3d MaxCoords() const;646///647Point3d MinCoords() const;648649/// Make a negative sized box;650// void CreateNegMinMaxBox();651652///653Point3d CalcCenter () const { return Point3d(0.5*(minx[0] + maxx[0]),6540.5*(minx[1] + maxx[1]),6550.5*(minx[2] + maxx[2])); }656///657double CalcDiam () const { return sqrt(sqr(maxx[0]-minx[0])+658sqr(maxx[1]-minx[1])+659sqr(maxx[2]-minx[2])); }660661///662void WriteData(ofstream& fout) const;663///664void ReadData(ifstream& fin);665};666667668class Box3dSphere : public Box3d669{670protected:671///672double diam, inner;673///674Point3d c;675public:676///677Box3dSphere () { };678///679Box3dSphere ( double aminx, double amaxx,680double aminy, double amaxy,681double aminz, double amaxz);682///683const Point3d & Center () const { return c; }684685///686double Diam () const { return diam; }687///688double Inner () const { return inner; }689///690void GetSubBox (int i, Box3dSphere & sbox) const;691692// private:693///694void CalcDiamCenter ();695};696697698699700///701class referencetransform702{703///704Vec3d ex, ey, ez;705///706Vec3d exh, eyh, ezh;707///708Vec3d ex_h, ey_h, ez_h;709///710Point3d rp;711///712double h;713714public:715716///717void Set (const Point3d & p1, const Point3d & p2,718const Point3d & p3, double ah);719720///721void ToPlain (const Point3d & p, Point3d & pp) const;722///723void ToPlain (const ARRAY<Point3d> & p, ARRAY<Point3d> & pp) const;724///725void FromPlain (const Point3d & pp, Point3d & p) const;726};727728729730#endif731732733