Path: blob/devel/ElmerGUI/netgen/libsrc/gprim/geom3d.cpp
3206 views
#include <algorithm>1#include <mystdlib.h>23#include <myadt.hpp>4#include <gprim.hpp>56namespace netgen7{8ostream & operator<<(ostream & s, const Point3d & p)9{10return s << "(" << p.x[0] << ", " << p.x[1] << ", " << p.x[2] << ")";11}1213ostream & operator<<(ostream & s, const Vec3d & v)14{15return s << "(" << v.x[0] << ", " << v.x[1] << ", " << v.x[2] << ")";16}1718double Angle (const Vec3d & v1, const Vec3d & v2)19{20double co = (v1 * v2) / (v1.Length() * v2.Length());21if (co > 1) co = 1;22if (co < -1) co = -1;23return acos ( co );24}252627void Vec3d :: GetNormal (Vec3d & n) const28{29if (fabs (X()) > fabs (Z()))30{31n.X() = -Y();32n.Y() = X();33n.Z() = 0;34}35else36{37n.X() = 0;38n.Y() = Z();39n.Z() = -Y();40}41double len = n.Length();42if (len == 0)43{44n.X() = 1;45n.Y() = n.Z() = 0;46}47else48n /= len;49}5051/*52ostream & operator<<(ostream & s, const ROTDenseMatrix3D & r)53{54return s << "{ (" << r.txx << ", " << r.txy << ", " << r.txz << ") , ("55<< r.tyx << ", " << r.tyy << ", " << r.tyz << ") , ("56<< r.tzx << ", " << r.tzy << ", " << r.tzz << ") }";57}58*/5960/*61Vec3d operator- (const Point3d & p1, const Point3d & p2)62{63return Vec3d (p1.X() - p2.X(), p1.Y() - p2.Y(),p1.Z() - p2.Z());64}6566Point3d operator- (const Point3d & p1, const Vec3d & v)67{68return Point3d (p1.X() - v.X(), p1.Y() - v.Y(),p1.Z() - v.Z());69}7071Point3d operator+ (const Point3d & p1, const Vec3d & v)72{73return Point3d (p1.X() + v.X(), p1.Y() + v.Y(),p1.Z() + v.Z());74}7576Vec3d operator- (const Vec3d & v1, const Vec3d & v2)77{78return Vec3d (v1.X() - v2.X(), v1.Y() - v2.Y(),v1.Z() - v2.Z());79}8081Vec3d operator+ (const Vec3d & v1, const Vec3d & v2)82{83return Vec3d (v1.X() + v2.X(), v1.Y() + v2.Y(),v1.Z() + v2.Z());84}8586Vec3d operator* (double scal, const Vec3d & v)87{88return Vec3d (scal * v.X(), scal * v.Y(), scal * v.Z());89}90*/91/*92double operator* (const Vec3d & v1, const Vec3d & v2)93{94return v1.X() * v2.X() + v1.Y() * v2.Y() + v1.Z() * v2.Z();95}9697double Cross (const Vec3d & v1, const Vec3d & v2)98{99return v1.X() * v2.Y() - v1.Y() * v2.X();100}101*/102103/*104void ROTDenseMatrix3D :: CalcRotMat(double ag, double bg, double lg, double size2, Vec3d r)105{106size = size2;107txx=size * ( cos(bg) * cos(lg) );108txy=size * ( cos(bg) * sin(lg) );109txz=size * (-sin(bg) );110111tyx=size * ( sin(ag) * sin(bg) * cos(lg) - cos(ag) * sin(lg) );112tyy=size * ( sin(ag) * sin(bg) * sin(lg) + cos(ag) * cos(lg) );113tyz=size * ( sin(ag) * cos(bg) );114115tzx=size * ( cos(ag) * sin(bg) * cos(lg) + sin(ag) * sin(lg) );116tzy=size * ( cos(ag) * sin(bg) * sin(lg) - sin(ag) * cos(lg) );117tzz=size * ( cos(ag) * cos(bg) );118119deltaR=r;120}121ROTDenseMatrix3D :: ROTDenseMatrix3D(double ag, double bg, double lg, double size2, Vec3d r)122{CalcRotMat(ag, bg, lg, size2, r); }123124ROTDenseMatrix3D :: ROTDenseMatrix3D(Vec3d rot2)125{126Vec3d r2(0,0,0);127CalcRotMat(rot2.X(), rot2.Y(), rot2.Z(), 1, r2);128}129130ROTDenseMatrix3D ROTDenseMatrix3D :: INV()131{132ROTDenseMatrix3D rinv(txx/sqr(size),tyx/sqr(size),tzx/sqr(size),133txy/sqr(size),tyy/sqr(size),tzy/sqr(size),134txz/sqr(size),tyz/sqr(size),tzz/sqr(size),1351/size,deltaR);136return rinv;137}138139Vec3d operator* (const ROTDenseMatrix3D & r, const Vec3d & v)140{141return Vec3d (r.XX() * v.X() + r.XY() * v.Y() + r.XZ() * v.Z(),142r.YX() * v.X() + r.YY() * v.Y() + r.YZ() * v.Z(),143r.ZX() * v.X() + r.ZY() * v.Y() + r.ZZ() * v.Z() );144}145146Point3d operator* (const ROTDenseMatrix3D & r, const Point3d & p)147{148return Point3d (r.XX() * p.X() + r.XY() * p.Y() + r.XZ() * p.Z(),149r.YX() * p.X() + r.YY() * p.Y() + r.YZ() * p.Z(),150r.ZX() * p.X() + r.ZY() * p.Y() + r.ZZ() * p.Z() );151}152*/153154155156157158159160Box3d :: Box3d ( double aminx, double amaxx,161double aminy, double amaxy,162double aminz, double amaxz )163{164minx[0] = aminx; maxx[0] = amaxx;165minx[1] = aminy; maxx[1] = amaxy;166minx[2] = aminz; maxx[2] = amaxz;167}168169Box3d :: Box3d ( const Box3d & b2 )170{171for (int i = 0; i < 3; i++)172{173minx[i] = b2.minx[i];174maxx[i] = b2.maxx[i];175}176}177178Box3d :: Box3d ( const Box<3> & b2 )179{180for (int i = 0; i < 3; i++)181{182minx[i] = b2.PMin()(i);183maxx[i] = b2.PMax()(i);184}185}186187188/*189int Box3d :: Intersect (const Box3d & box2) const190{191int i;192for (i = 0; i <= 2; i++)193if (minx[i] > box2.maxx[i] || maxx[i] < box2.minx[i])194return 0;195return 1;196}197*/198199/*200void Box3d :: SetPoint (const Point3d & p)201{202minx[0] = maxx[0] = p.X();203minx[1] = maxx[1] = p.Y();204minx[2] = maxx[2] = p.Z();205}206207void Box3d :: AddPoint (const Point3d & p)208{209if (p.X() < minx[0]) minx[0] = p.X();210if (p.X() > maxx[0]) maxx[0] = p.X();211if (p.Y() < minx[1]) minx[1] = p.Y();212if (p.Y() > maxx[1]) maxx[1] = p.Y();213if (p.Z() < minx[2]) minx[2] = p.Z();214if (p.Z() > maxx[2]) maxx[2] = p.Z();215}216*/217218void Box3d :: GetPointNr (int i, Point3d & point) const219{220i--;221point.X() = (i & 1) ? maxx[0] : minx[0];222point.Y() = (i & 2) ? maxx[1] : minx[1];223point.Z() = (i & 4) ? maxx[2] : minx[2];224}225226227void Box3d :: Increase (double d)228{229for (int i = 0; i <= 2; i++)230{231minx[i] -= d;232maxx[i] += d;233}234}235236void Box3d :: IncreaseRel (double /* rel */)237{238for (int i = 0; i <= 2; i++)239{240double d = 0.5 * (maxx[i] - minx[i]);241minx[i] -= d;242maxx[i] += d;243}244}245246247Box3d :: Box3d (const Point3d& p1, const Point3d& p2)248{249minx[0] = min2 (p1.X(), p2.X());250minx[1] = min2 (p1.Y(), p2.Y());251minx[2] = min2 (p1.Z(), p2.Z());252maxx[0] = max2 (p1.X(), p2.X());253maxx[1] = max2 (p1.Y(), p2.Y());254maxx[2] = max2 (p1.Z(), p2.Z());255}256257const Box3d& Box3d :: operator+=(const Box3d& b)258{259minx[0] = min2 (minx[0], b.minx[0]);260minx[1] = min2 (minx[1], b.minx[1]);261minx[2] = min2 (minx[2], b.minx[2]);262maxx[0] = max2 (maxx[0], b.maxx[0]);263maxx[1] = max2 (maxx[1], b.maxx[1]);264maxx[2] = max2 (maxx[2], b.maxx[2]);265266return *this;267}268269Point3d Box3d :: MaxCoords() const270{271return Point3d(maxx[0], maxx[1], maxx[2]);272}273274Point3d Box3d :: MinCoords() const275{276return Point3d(minx[0], minx[1], minx[2]);277}278279/*280void Box3d :: CreateNegMinMaxBox()281{282minx[0] = MAXDOUBLE;283minx[1] = MAXDOUBLE;284minx[2] = MAXDOUBLE;285maxx[0] = MINDOUBLE;286maxx[1] = MINDOUBLE;287maxx[2] = MINDOUBLE;288289}290*/291292void Box3d :: WriteData(ofstream& fout) const293{294for(int i = 0; i < 3; i++)295{296fout << minx[i] << " " << maxx[i] << " ";297}298fout << "\n";299}300301void Box3d :: ReadData(ifstream& fin)302{303for(int i = 0; i < 3; i++)304{305fin >> minx[i];306fin >> maxx[i];307}308}309310311312313Box3dSphere :: Box3dSphere ( double aminx, double amaxx,314double aminy, double amaxy,315double aminz, double amaxz )316: Box3d (aminx, amaxx, aminy, amaxy, aminz, amaxz)317{318CalcDiamCenter ();319}320321322void Box3dSphere :: CalcDiamCenter ()323{324diam = sqrt( sqr (maxx[0] - minx[0]) +325sqr (maxx[1] - minx[1]) +326sqr (maxx[2] - minx[2]));327328c.X() = 0.5 * (minx[0] + maxx[0]);329c.Y() = 0.5 * (minx[1] + maxx[1]);330c.Z() = 0.5 * (minx[2] + maxx[2]);331332inner = min2 ( min2 (maxx[0] - minx[0], maxx[1] - minx[1]), maxx[2] - minx[2]) / 2;333}334335336void Box3dSphere :: GetSubBox (int i, Box3dSphere & sbox) const337{338i--;339if (i & 1)340{341sbox.minx[0] = c.X();342sbox.maxx[0] = maxx[0];343}344else345{346sbox.minx[0] = minx[0];347sbox.maxx[0] = c.X();348}349if (i & 2)350{351sbox.minx[1] = c.Y();352sbox.maxx[1] = maxx[1];353}354else355{356sbox.minx[1] = minx[1];357sbox.maxx[1] = c.Y();358}359if (i & 4)360{361sbox.minx[2] = c.Z();362sbox.maxx[2] = maxx[2];363}364else365{366sbox.minx[2] = minx[2];367sbox.maxx[2] = c.Z();368}369370// sbox.CalcDiamCenter ();371372sbox.c.X() = 0.5 * (sbox.minx[0] + sbox.maxx[0]);373sbox.c.Y() = 0.5 * (sbox.minx[1] + sbox.maxx[1]);374sbox.c.Z() = 0.5 * (sbox.minx[2] + sbox.maxx[2]);375sbox.diam = 0.5 * diam;376sbox.inner = 0.5 * inner;377}378379380381382/*383double Determinant (const Vec3d & col1,384const Vec3d & col2,385const Vec3d & col3)386{387return388col1.x[0] * ( col2.x[1] * col3.x[2] - col2.x[2] * col3.x[1]) +389col1.x[1] * ( col2.x[2] * col3.x[0] - col2.x[0] * col3.x[2]) +390col1.x[2] * ( col2.x[0] * col3.x[1] - col2.x[1] * col3.x[0]);391}392*/393394void Transpose (Vec3d & v1, Vec3d & v2, Vec3d & v3)395{396Swap (v1.Y(), v2.X());397Swap (v1.Z(), v3.X());398Swap (v2.Z(), v3.Y());399}400401402int SolveLinearSystem (const Vec3d & col1, const Vec3d & col2,403const Vec3d & col3, const Vec3d & rhs,404Vec3d & sol)405{406// changed by MW407double matrix[3][3];408double locrhs[3];409int retval = 0;410411for(int i=0; i<3; i++)412{413matrix[i][0] = col1.X(i+1);414matrix[i][1] = col2.X(i+1);415matrix[i][2] = col3.X(i+1);416locrhs[i] = rhs.X(i+1);417}418419for(int i=0; i<2; i++)420{421int pivot = i;422double maxv = fabs(matrix[i][i]);423for(int j=i+1; j<3; j++)424if(fabs(matrix[j][i]) > maxv)425{426maxv = fabs(matrix[j][i]);427pivot = j;428}429430if(fabs(maxv) > 1e-40)431{432if(pivot != i)433{434swap(matrix[i][0],matrix[pivot][0]);435swap(matrix[i][1],matrix[pivot][1]);436swap(matrix[i][2],matrix[pivot][2]);437swap(locrhs[i],locrhs[pivot]);438}439for(int j=i+1; j<3; j++)440{441double fac = matrix[j][i] / matrix[i][i];442443for(int k=i+1; k<3; k++)444matrix[j][k] -= fac*matrix[i][k];445locrhs[j] -= fac*locrhs[i];446}447}448else449retval = 1;450}451452if(fabs(matrix[2][2]) < 1e-40)453retval = 1;454455if(retval != 0)456return retval;457458459for(int i=2; i>=0; i--)460{461double sum = locrhs[i];462for(int j=2; j>i; j--)463sum -= matrix[i][j]*sol.X(j+1);464465sol.X(i+1) = sum/matrix[i][i];466}467468return 0;469470471472473474/*475double det = Determinant (col1, col2, col3);476if (fabs (det) < 1e-40)477return 1;478479sol.X() = Determinant (rhs, col2, col3) / det;480sol.Y() = Determinant (col1, rhs, col3) / det;481sol.Z() = Determinant (col1, col2, rhs) / det;482483return 0;484*/485/*486Vec3d cr;487Cross (col1, col2, cr);488double det = cr * col3;489490if (fabs (det) < 1e-40)491return 1;492493if (fabs(cr.Z()) > 1e-12)494{495// solve for 3. component496sol.Z() = (cr * rhs) / det;497498// 2x2 system for 1. and 2. component499double res1 = rhs.X() - sol.Z() * col3.X();500double res2 = rhs.Y() - sol.Z() * col3.Y();501502sol.X() = (col2.Y() * res1 - col2.X() * res2) / cr.Z();503sol.Y() = (col1.X() * res2 - col1.Y() * res1) / cr.Z();504505}506else507{508det = Determinant (col1, col2, col3);509if (fabs (det) < 1e-40)510return 1;511512sol.X() = Determinant (rhs, col2, col3) / det;513sol.Y() = Determinant (col1, rhs, col3) / det;514sol.Z() = Determinant (col1, col2, rhs) / det;515}516517return 0;518*/519}520521522int SolveLinearSystemLS (const Vec3d & col1,523const Vec3d & col2,524const Vec2d & rhs,525Vec3d & sol)526{527double a11 = col1 * col1;528double a12 = col1 * col2;529double a22 = col2 * col2;530531double det = a11 * a22 - a12 * a12;532533if (det*det <= 1e-24 * a11 * a22)534{535sol = Vec3d (0, 0, 0);536return 1;537}538539Vec2d invrhs;540invrhs.X() = ( a22 * rhs.X() - a12 * rhs.Y()) / det;541invrhs.Y() = (-a12 * rhs.X() + a11 * rhs.Y()) / det;542543sol.X() = invrhs.X() * col1.X() + invrhs.Y() * col2.X();544sol.Y() = invrhs.X() * col1.Y() + invrhs.Y() * col2.Y();545sol.Z() = invrhs.X() * col1.Z() + invrhs.Y() * col2.Z();546547return 0;548549/*550Vec3d inv1, inv2;551int err =552PseudoInverse (col1, col2, inv1, inv2);553554sol = rhs.X() * inv1 + rhs.Y() * inv2;555return err;556*/557}558559int SolveLinearSystemLS2 (const Vec3d & col1,560const Vec3d & col2,561const Vec2d & rhs,562Vec3d & sol, double & x, double & y)563{564double a11 = col1 * col1;565double a12 = col1 * col2;566double a22 = col2 * col2;567568double det = a11 * a22 - a12 * a12;569570if (fabs (det) <= 1e-12 * col1.Length() * col2.Length() ||571col1.Length2() == 0 || col2.Length2() == 0)572{573sol = Vec3d (0, 0, 0);574x = 0; y = 0;575return 1;576}577578Vec2d invrhs;579invrhs.X() = ( a22 * rhs.X() - a12 * rhs.Y()) / det;580invrhs.Y() = (-a12 * rhs.X() + a11 * rhs.Y()) / det;581582sol.X() = invrhs.X() * col1.X() + invrhs.Y() * col2.X();583sol.Y() = invrhs.X() * col1.Y() + invrhs.Y() * col2.Y();584sol.Z() = invrhs.X() * col1.Z() + invrhs.Y() * col2.Z();585586x = invrhs.X();587y = invrhs.Y();588589return 0;590591/*592Vec3d inv1, inv2;593int err =594PseudoInverse (col1, col2, inv1, inv2);595596sol = rhs.X() * inv1 + rhs.Y() * inv2;597return err;598*/599}600601int PseudoInverse (const Vec3d & col1,602const Vec3d & col2,603Vec3d & inv1,604Vec3d & inv2)605{606double a11 = col1 * col1;607double a12 = col1 * col2;608double a22 = col2 * col2;609610double det = a11 * a22 - a12 * a12;611612if (fabs (det) < 1e-12 * col1.Length() * col2.Length())613{614inv1 = Vec3d (0, 0, 0);615inv2 = Vec3d (0, 0, 0);616return 1;617}618619double ia11 = a22 / det;620double ia12 = -a12 / det;621double ia22 = a11 / det;622623inv1 = ia11 * col1 + ia12 * col2;624inv2 = ia12 * col1 + ia22 * col2;625626return 0;627}628629630631632QuadraticFunction3d ::633QuadraticFunction3d (const Point3d & p, const Vec3d & v)634{635Vec3d hv(v);636hv /= (hv.Length() + 1e-12);637Vec3d t1, t2;638hv.GetNormal (t1);639Cross (hv, t1, t2);640641double t1p = t1.X() * p.X() + t1.Y() * p.Y() + t1.Z() * p.Z();642double t2p = t2.X() * p.X() + t2.Y() * p.Y() + t2.Z() * p.Z();643c0 = sqr (t1p) + sqr (t2p);644cx = -2 * (t1p * t1.X() + t2p * t2.X());645cy = -2 * (t1p * t1.Y() + t2p * t2.Y());646cz = -2 * (t1p * t1.Z() + t2p * t2.Z());647648cxx = t1.X() * t1.X() + t2.X() * t2.X();649cyy = t1.Y() * t1.Y() + t2.Y() * t2.Y();650czz = t1.Z() * t1.Z() + t2.Z() * t2.Z();651652cxy = 2 * t1.X() * t1.Y() + 2 * t2.X() * t2.Y();653cxz = 2 * t1.X() * t1.Z() + 2 * t2.X() * t2.Z();654cyz = 2 * t1.Y() * t1.Z() + 2 * t2.Y() * t2.Z();655656/*657(*testout) << "c0 = " << c0658<< " clin = " << cx << " " << cy << " " << cz659<< " cq = " << cxx << " " << cyy << " " << czz660<< cxy << " " << cyz << " " << cyz << endl;661*/662}663664// QuadraticFunction3d gqf (Point3d (0,0,0), Vec3d (1, 0, 0));665666667668669670void referencetransform :: Set (const Point3d & p1, const Point3d & p2,671const Point3d & p3, double ah)672{673ex = p2 - p1;674ex /= ex.Length();675ey = p3 - p1;676ey -= (ex * ey) * ex;677ey /= ey.Length();678ez = Cross (ex, ey);679rp = p1;680h = ah;681682exh = ah * ex;683eyh = ah * ey;684ezh = ah * ez;685ah = 1 / ah;686ex_h = ah * ex;687ey_h = ah * ey;688ez_h = ah * ez;689}690691void referencetransform :: ToPlain (const Point3d & p, Point3d & pp) const692{693Vec3d v;694v = p - rp;695pp.X() = (ex_h * v);696pp.Y() = (ey_h * v);697pp.Z() = (ez_h * v);698}699700void referencetransform :: ToPlain (const ARRAY<Point3d> & p,701ARRAY<Point3d> & pp) const702{703Vec3d v;704int i;705706pp.SetSize (p.Size());707for (i = 1; i <= p.Size(); i++)708{709v = p.Get(i) - rp;710pp.Elem(i).X() = (ex_h * v);711pp.Elem(i).Y() = (ey_h * v);712pp.Elem(i).Z() = (ez_h * v);713}714}715716void referencetransform :: FromPlain (const Point3d & pp, Point3d & p) const717{718Vec3d v;719// v = (h * pp.X()) * ex + (h * pp.Y()) * ey + (h * pp.Z()) * ez;720// p = rp + v;721v.X() = pp.X() * exh.X() + pp.Y() * eyh.X() + pp.Z() * ezh.X();722v.Y() = pp.X() * exh.Y() + pp.Y() * eyh.Y() + pp.Z() * ezh.Y();723v.Z() = pp.X() * exh.Z() + pp.Y() * eyh.Z() + pp.Z() * ezh.Z();724p.X() = rp.X() + v.X();725p.Y() = rp.Y() + v.Y();726p.Z() = rp.Z() + v.Z();727}728729730}731732733