Path: blob/devel/ElmerGUI/netgen/libsrc/csg/algprim.cpp
3206 views
#include <mystdlib.h>123#include <linalg.hpp>4#include <csg.hpp>567namespace netgen8{910double11QuadraticSurface :: CalcFunctionValue (const Point<3> & p) const12{13return p(0) * (cxx * p(0) + cxy * p(1) + cxz * p(2) + cx) +14p(1) * (cyy * p(1) + cyz * p(2) + cy) +15p(2) * (czz * p(2) + cz) + c1;16}1718void19QuadraticSurface :: CalcGradient (const Point<3> & p, Vec<3> & grad) const20{21grad(0) = 2 * cxx * p(0) + cxy * p(1) + cxz * p(2) + cx;22grad(1) = 2 * cyy * p(1) + cxy * p(0) + cyz * p(2) + cy;23grad(2) = 2 * czz * p(2) + cxz * p(0) + cyz * p(1) + cz;24}2526void27QuadraticSurface :: CalcHesse (const Point<3> & /* p */, Mat<3> & hesse) const28{29hesse(0,0) = 2 * cxx;30hesse(1,1) = 2 * cyy;31hesse(2,2) = 2 * czz;32hesse(0,1) = hesse(1,0) = cxy;33hesse(0,2) = hesse(2,0) = cxz;34hesse(1,2) = hesse(2,1) = cyz;35}363738void QuadraticSurface :: Read (istream & ist)39{40ist >> cxx >> cyy >> czz >> cxy >> cxz >> cyz >> cx >> cy >> cz >> c1;41}4243void QuadraticSurface :: Print (ostream & ost) const44{45ost << cxx << " " << cyy << " " << czz << " "46<< cxy << " " << cxz << " " << cyz << " "47<< cx << " " << cy << " " << cz << " "48<< c1;49}505152void QuadraticSurface :: PrintCoeff (ostream & ost) const53{54ost << " cxx = " << cxx55<< " cyy = " << cyy56<< " czz = " << czz57<< " cxy = " << cxy58<< " cxz = " << cxz59<< " cyz = " << cyz60<< " cx = " << cx61<< " cy = " << cy62<< " cz = " << cz63<< " c1 = " << c1 << endl;64}65666768Point<3> QuadraticSurface :: GetSurfacePoint () const69{70MyError ("GetSurfacePoint called for QuadraticSurface");71return Point<3> (0, 0, 0);72}737475Plane :: Plane (const Point<3> & ap, Vec<3> an)76{77eps_base = 1e-8;7879p = ap;80n = an;81n.Normalize();8283cxx = cyy = czz = cxy = cxz = cyz = 0;84cx = n(0); cy = n(1); cz = n(2);85c1 = - (cx * p(0) + cy * p(1) + cz * p(2));86}8788Primitive * Plane :: Copy () const89{90return new Plane (p, n);91}9293void Plane :: Transform (Transformation<3> & trans)94{95Point<3> hp;96Vec<3> hn;97trans.Transform (p, hp);98trans.Transform (n, hn);99p = hp;100n = hn;101102cxx = cyy = czz = cxy = cxz = cyz = 0;103cx = n(0); cy = n(1); cz = n(2);104c1 = - (cx * p(0) + cy * p(1) + cz * p(2));105}106107108109void Plane :: GetPrimitiveData (const char *& classname,110ARRAY<double> & coeffs) const111{112classname = "plane";113coeffs.SetSize (6);114coeffs.Elem(1) = p(0);115coeffs.Elem(2) = p(1);116coeffs.Elem(3) = p(2);117coeffs.Elem(4) = n(0);118coeffs.Elem(5) = n(1);119coeffs.Elem(6) = n(2);120}121122void Plane :: SetPrimitiveData (ARRAY<double> & coeffs)123{124p(0) = coeffs.Elem(1);125p(1) = coeffs.Elem(2);126p(2) = coeffs.Elem(3);127n(0) = coeffs.Elem(4);128n(1) = coeffs.Elem(5);129n(2) = coeffs.Elem(6);130131n.Normalize();132133cxx = cyy = czz = cxy = cxz = cyz = 0;134cx = n(0); cy = n(1); cz = n(2);135c1 = - (cx * p(0) + cy * p(1) + cz * p(2));136}137138Primitive * Plane :: CreateDefault ()139{140return new Plane (Point<3> (0,0,0), Vec<3> (0,0,1));141}142143144int Plane :: IsIdentic (const Surface & s2, int & inv, double eps) const145{146const Plane * ps2 = dynamic_cast<const Plane*>(&s2);147148if(ps2)149{150Point<3> pp2 = ps2->GetSurfacePoint();151Vec<3> n2 = s2.GetNormalVector(pp2);152153if(fabs(n*n2) < 1.-eps_base)154return 0;155156if (fabs (s2.CalcFunctionValue(p)) > eps) return 0;157}158else159{160//(*testout) << "pos1" << endl;161if (fabs (s2.CalcFunctionValue(p)) > eps) return 0;162Vec<3> hv1, hv2;163hv1 = n.GetNormal ();164hv2 = Cross (n, hv1);165166Point<3> hp = p + hv1;167//(*testout) << "pos2" << endl;168//(*testout) << "eps " << eps << " s2.CalcFunctionValue(hp) " << s2.CalcFunctionValue(hp) << endl;169if (fabs (s2.CalcFunctionValue(hp)) > eps) return 0;170//(*testout) << "pos3" << endl;171hp = p + hv2;172if (fabs (s2.CalcFunctionValue(hp)) > eps) return 0;173}174175//(*testout) << "pos4" << endl;176Vec<3> n1, n2;177n1 = GetNormalVector (p);178n2 = s2.GetNormalVector (p);179inv = (n1 * n2 < 0);180//(*testout) << "inv " << inv << endl;181return 1;182}183184185186void Plane :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2)187{188Surface::DefineTangentialPlane (ap1, ap2);189}190191192void Plane :: ToPlane (const Point<3> & p3d,193Point<2> & pplane,194double h, int & zone) const195{196Vec<3> p1p;197198p1p = p3d - p1;199p1p /= h;200pplane(0) = p1p * ex;201pplane(1) = p1p * ey;202zone = 0;203}204205void Plane :: FromPlane (const Point<2> & pplane, Point<3> & p3d, double h) const206{207/*208Vec<3> p1p;209Point<2> pplane2 = pplane;210211pplane2 *= h;212p1p = pplane2(0) * ex + pplane2(1) * ey;213p3d = p1 + p1p;214*/215p3d = p1 + (h * pplane(0)) * ex + (h * pplane(1)) * ey;216}217218219void Plane :: Project (Point<3> & p3d) const220{221double val = Plane::CalcFunctionValue (p3d);222p3d -= val * n;223}224225INSOLID_TYPE Plane :: BoxInSolid (const BoxSphere<3> & box) const226{227int i;228double val;229Point<3> pp;230231val = Plane::CalcFunctionValue (box.Center());232if (val > box.Diam() / 2) return IS_OUTSIDE;233if (val < -box.Diam() / 2) return IS_INSIDE;234235if (val > 0)236{237/*238double modify =239((box.MaxX()-box.MinX()) * fabs (cx) +240(box.MaxY()-box.MinY()) * fabs (cy) +241(box.MaxZ()-box.MinZ()) * fabs (cz)) / 2;242*/243Vec<3> vdiag = box.PMax() - box.PMin();244double modify = (vdiag(0) * fabs (cx) +245vdiag(1) * fabs (cy) +246vdiag(2) * fabs (cz) ) / 2;247248if (val - modify < 0)249return DOES_INTERSECT;250return IS_OUTSIDE;251252// only outside or intersect possible253for (i = 0; i < 8; i++)254{255pp = box.GetPointNr (i);256val = Plane::CalcFunctionValue (pp);257if (val < 0)258return DOES_INTERSECT;259}260return IS_OUTSIDE;261}262else263{264/*265double modify =266((box.MaxX()-box.MinX()) * fabs (cx) +267(box.MaxY()-box.MinY()) * fabs (cy) +268(box.MaxZ()-box.MinZ()) * fabs (cz)) / 2;269*/270Vec<3> vdiag = box.PMax() - box.PMin();271double modify = (vdiag(0) * fabs (cx) +272vdiag(1) * fabs (cy) +273vdiag(2) * fabs (cz) ) / 2;274if (val + modify > 0)275return DOES_INTERSECT;276return IS_INSIDE;277278279// only inside or intersect possible280for (i = 0; i < 8; i++)281{282pp = box.GetPointNr (i);283val = Plane::CalcFunctionValue (pp);284if (val > 0)285return DOES_INTERSECT;286}287return IS_INSIDE;288}289290291292/*293for (i = 1; i <= 8; i++)294{295box.GetPointNr (i, p);296val = CalcFunctionValue (p);297if (val > 0) inside = 0;298if (val < 0) outside = 0;299}300301if (inside) return IS_INSIDE;302if (outside) return IS_OUTSIDE;303return DOES_INTERSECT;304*/305}306307308309// double Plane :: CalcFunctionValue (const Point<3> & p3d) const310// {311// return cx * p3d(0) + cy * p3d(1) + cz * p3d(2) + c1;312// }313314void Plane :: CalcGradient (const Point<3> & /* p */, Vec<3> & grad) const315{316grad(0) = cx;317grad(1) = cy;318grad(2) = cz;319}320321void Plane :: CalcHesse (const Point<3> & /* p */, Mat<3> & hesse) const322{323hesse = 0;324}325326double Plane :: HesseNorm () const327{328return 0;329}330331332Point<3> Plane :: GetSurfacePoint () const333{334return p;335}336337338void Plane :: GetTriangleApproximation339(TriangleApproximation & tas,340const Box<3> & boundingbox, double facets) const341{342// find triangle, such that343// boundingbox /cap plane is contained in it344345Point<3> c = boundingbox.Center();346double r = boundingbox.Diam();347348Project (c);349Vec<3> t1 = n.GetNormal();350Vec<3> t2 = Cross (n, t1);351352t1.Normalize();353t2.Normalize();354355tas.AddPoint (c + (-0.5 * r) * t2 + (sqrt(0.75) * r) * t1);356tas.AddPoint (c + (-0.5 * r) * t2 + (-sqrt(0.75) * r) * t1);357tas.AddPoint (c + r * t2);358359tas.AddTriangle (TATriangle (0, 0, 1, 2));360}361362363364365Sphere :: Sphere (const Point<3> & ac, double ar)366{367c = ac;368r = ar;369370cxx = cyy = czz = 0.5 / r;371cxy = cxz = cyz = 0;372cx = - c(0) / r;373cy = - c(1) / r;374cz = - c(2) / r;375c1 = (c(0) * c(0) + c(1) * c(1) + c(2) * c(2)) / (2 * r) - r / 2;376}377378void Sphere :: GetPrimitiveData (const char *& classname, ARRAY<double> & coeffs) const379{380classname = "sphere";381coeffs.SetSize (4);382coeffs.Elem(1) = c(0);383coeffs.Elem(2) = c(1);384coeffs.Elem(3) = c(2);385coeffs.Elem(4) = r;386}387388void Sphere :: SetPrimitiveData (ARRAY<double> & coeffs)389{390c(0) = coeffs.Elem(1);391c(1) = coeffs.Elem(2);392c(2) = coeffs.Elem(3);393r = coeffs.Elem(4);394395cxx = cyy = czz = 0.5 / r;396cxy = cxz = cyz = 0;397cx = - c(0) / r;398cy = - c(1) / r;399cz = - c(2) / r;400c1 = (c(0) * c(0) + c(1) * c(1) + c(2) * c(2)) / (2 * r) - r / 2;401}402403Primitive * Sphere :: CreateDefault ()404{405return new Sphere (Point<3> (0,0,0), 1);406}407408409410Primitive * Sphere :: Copy () const411{412return new Sphere (c, r);413}414415void Sphere :: Transform (Transformation<3> & trans)416{417Point<3> hp;418trans.Transform (c, hp);419c = hp;420421cxx = cyy = czz = 0.5 / r;422cxy = cxz = cyz = 0;423cx = - c(0) / r;424cy = - c(1) / r;425cz = - c(2) / r;426c1 = (c(0) * c(0) + c(1) * c(1) + c(2) * c(2)) / (2 * r) - r / 2;427}428429430431432int Sphere :: IsIdentic (const Surface & s2, int & inv, double eps) const433{434const Sphere * sp2 = dynamic_cast<const Sphere*> (&s2);435436if (!sp2) return 0;437438if (Dist (sp2->c, c) > eps) return 0;439if (fabs (sp2->r - r) > eps) return 0;440441inv = 0;442443return 1;444}445446447void Sphere :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2)448{449Surface::DefineTangentialPlane (ap1, ap2);450451ez = p1 - c;452ez /= ez.Length();453454ex = p2 - p1;455ex -= (ex * ez) * ez;456ex /= ex.Length();457458ey = Cross (ez, ex);459}460461462void Sphere :: ToPlane (const Point<3> & p, Point<2> & pplane, double h, int & zone) const463{464Vec<3> p1p;465466p1p = p - p1;467468/*469if (p1p * ez < -r)470{471zone = -1;472pplane = Point<2> (1E8, 1E8);473}474else475{476zone = 0;477p1p /= h;478pplane(0) = p1p * ex;479pplane(1) = p1p * ey;480}481*/482483Point<3> p1top = c + (c - p1);484485Vec<3> p1topp = p - p1top;486Vec<3> p1topp1 = p1 - p1top;487Vec<3> lam;488// SolveLinearSystem (ex, ey, p1topp, p1topp1, lam);489490Mat<3> m;491for (int i = 0; i < 3; i++)492{493m(i, 0) = ex(i);494m(i, 1) = ey(i);495m(i, 2) = p1topp(i);496}497m.Solve (p1topp1, lam);498499pplane(0) = -lam(0) / h;500pplane(1) = -lam(1) / h;501502if (lam(2) > 2)503zone = -1;504else505zone = 0;506}507508void Sphere :: FromPlane (const Point<2> & pplane, Point<3> & p, double h) const509{510/*511// Vec<3> p1p;512double z;513Point<2> pplane2 (pplane);514515pplane2(0) *= h;516pplane2(1) *= h;517z = -r + sqrt (sqr (r) - sqr (pplane2(0)) - sqr (pplane2(1)));518// p = p1;519p(0) = p1(0) + pplane2(0) * ex(0) + pplane2(1) * ey(0) + z * ez(0);520p(1) = p1(1) + pplane2(0) * ex(1) + pplane2(1) * ey(1) + z * ez(1);521p(2) = p1(2) + pplane2(0) * ex(2) + pplane2(1) * ey(2) + z * ez(2);522*/523524Point<2> pplane2 (pplane);525526pplane2(0) *= h;527pplane2(1) *= h;528529p(0) = p1(0) + pplane2(0) * ex(0) + pplane2(1) * ey(0);530p(1) = p1(1) + pplane2(0) * ex(1) + pplane2(1) * ey(1);531p(2) = p1(2) + pplane2(0) * ex(2) + pplane2(1) * ey(2);532Project (p);533}534535536void Sphere :: Project (Point<3> & p) const537{538Vec<3> v;539v = p - c;540v *= (r / v.Length());541p = c + v;542}543544545INSOLID_TYPE Sphere :: BoxInSolid (const BoxSphere<3> & box) const546{547double dist;548dist = Dist (box.Center(), c);549550if (dist - box.Diam()/2 > r) return IS_OUTSIDE;551if (dist + box.Diam()/2 < r) return IS_INSIDE;552return DOES_INTERSECT;553}554555double Sphere :: HesseNorm () const556{557return 2 / r;558}559560561Point<3> Sphere :: GetSurfacePoint () const562{563return c + Vec<3> (r, 0, 0);564}565566567void Sphere :: GetTriangleApproximation568(TriangleApproximation & tas,569const Box<3> & boundingbox, double facets) const570{571int i, j;572double lg, bg;573int n = int(facets) + 1;574575for (j = 0; j <= n; j++)576for (i = 0; i <= n; i++)577{578lg = 2 * M_PI * double (i) / n;579bg = M_PI * (double(j) / n - 0.5);580581Point<3> p(c(0) + r * cos(bg) * sin (lg),582c(1) + r * cos(bg) * cos (lg),583c(2) + r * sin(bg));584tas.AddPoint (p);585}586587for (j = 0; j < n; j++)588for (i = 0; i < n; i++)589{590int pi = i + (n+1) * j;591tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2));592tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1));593}594}595596597598599600Ellipsoid ::601Ellipsoid (const Point<3> & aa,602const Vec<3> & av1, const Vec<3> & av2, const Vec<3> & av3)603{604a = aa;605v1 = av1;606v2 = av2;607v3 = av3;608609CalcData();610}611612613void Ellipsoid :: CalcData ()614{615// f = (x-a, vl)^2 / |vl|^2 + (x-a, vs)^2 / |vs|^2 -1616// f = sum_{i=1}^3 (x-a,v_i)^2 / |vi|^4 - 1 = sum (x-a,hv_i)^2617618Vec<3> hv1, hv2, hv3;619double lv1 = v1.Length2 ();620if (lv1 < 1e-32) lv1 = 1;621double lv2 = v2.Length2 ();622if (lv2 < 1e-32) lv2 = 1;623double lv3 = v3.Length2 ();624if (lv3 < 1e-32) lv3 = 1;625626rmin = sqrt (min3 (lv1, lv2, lv3));627628hv1 = (1.0 / lv1) * v1;629hv2 = (1.0 / lv2) * v2;630hv3 = (1.0 / lv3) * v3;631632cxx = hv1(0) * hv1(0) + hv2(0) * hv2(0) + hv3(0) * hv3(0);633cyy = hv1(1) * hv1(1) + hv2(1) * hv2(1) + hv3(1) * hv3(1);634czz = hv1(2) * hv1(2) + hv2(2) * hv2(2) + hv3(2) * hv3(2);635636cxy = 2 * (hv1(0) * hv1(1) + hv2(0) * hv2(1) + hv3(0) * hv3(1));637cxz = 2 * (hv1(0) * hv1(2) + hv2(0) * hv2(2) + hv3(0) * hv3(2));638cyz = 2 * (hv1(1) * hv1(2) + hv2(1) * hv2(2) + hv3(1) * hv3(2));639640Vec<3> va (a);641c1 = sqr(va * hv1) + sqr(va * hv2) + sqr(va * hv3) - 1;642643Vec<3> v = -2 * (va * hv1) * hv1 - 2 * (va * hv2) * hv2 - 2 * (va * hv3) * hv3;644cx = v(0);645cy = v(1);646cz = v(2);647}648649650INSOLID_TYPE Ellipsoid :: BoxInSolid (const BoxSphere<3> & box) const651{652// double grad = 2.0 / rmin;653// double grad = 3*(box.Center()-a).Length() / (rmin*rmin*rmin);654655double ggrad = 1.0 / (rmin*rmin);656Vec<3> g;657double val = CalcFunctionValue (box.Center());658CalcGradient (box.Center(), g);659double grad = g.Length();660661double r = box.Diam() / 2;662double maxval = grad * r + ggrad * r * r;663664// (*testout) << "box = " << box << ", val = " << val << ", maxval = " << maxval << endl;665666if (val > maxval) return IS_OUTSIDE;667if (val < -maxval) return IS_INSIDE;668return DOES_INTERSECT;669}670671672double Ellipsoid :: HesseNorm () const673{674return 1.0/ (rmin * rmin);675}676677double Ellipsoid :: MaxCurvature () const678{679const double a2 = v1.Length2();680const double b2 = v2.Length2();681const double c2 = v3.Length2();682683return max3 ( sqrt(a2)/min2(b2,c2), sqrt(b2)/min2(a2,c2), sqrt(c2)/min2(a2,b2) );684}685686Point<3> Ellipsoid :: GetSurfacePoint () const687{688return a + v1;689}690691692693void Ellipsoid :: GetTriangleApproximation694(TriangleApproximation & tas,695const Box<3> & boundingbox, double facets) const696{697int i, j;698double lg, bg;699int n = int(facets) + 1;700701for (j = 0; j <= n; j++)702for (i = 0; i <= n; i++)703{704lg = 2 * M_PI * double (i) / n;705bg = M_PI * (double(j) / n - 0.5);706707708Point<3> p(a +709sin (bg) * v1 +710cos (bg) * sin (lg) * v2 +711cos (bg) * cos (lg) * v3);712713tas.AddPoint (p);714}715716for (j = 0; j < n; j++)717for (i = 0; i < n; i++)718{719int pi = i + (n+1) * j;720tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2));721tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1));722}723}724725726727728729730731732733734735736737738739740741Cylinder :: Cylinder (ARRAY<double> & coeffs)742{743SetPrimitiveData(coeffs);744}745746Cylinder :: Cylinder (const Point<3> & aa, const Point<3> & ab, double ar)747{748a = aa;749b = ab;750vab = (b - a);751vab /= vab.Length();752r = ar;753754// ( <x,x> - 2 <x,a> + <a,a>755// - <x,vab>^2 + 2 <x,vab> <a, vab> - <a, vab>^2756// - r^2) / (2r) = 0757758double hv;759cxx = cyy = czz = 0.5 / r;760cxy = cxz = cyz = 0;761cx = - a(0) / r;762cy = - a(1) / r;763cz = - a(2) / r;764c1 = (a(0) * a(0) + a(1) * a(1) + a(2) * a(2)) / (2 * r);765hv = a(0) * vab(0) + a(1) * vab(1) + a(2) * vab(2);766cxx -= vab(0) * vab(0) / (2 * r);767cyy -= vab(1) * vab(1) / (2 * r);768czz -= vab(2) * vab(2) / (2 * r);769cxy -= vab(0) * vab(1) / r;770cxz -= vab(0) * vab(2) / r;771cyz -= vab(1) * vab(2) / r;772cx += vab(0) * hv / r;773cy += vab(1) * hv / r;774cz += vab(2) * hv / r;775c1 -= hv * hv / (2 * r);776c1 -= r / 2;777// PrintCoeff ();778}779780781782783void Cylinder :: GetPrimitiveData (const char *& classname, ARRAY<double> & coeffs) const784{785classname = "cylinder";786coeffs.SetSize (7);787coeffs.Elem(1) = a(0);788coeffs.Elem(2) = a(1);789coeffs.Elem(3) = a(2);790coeffs.Elem(4) = b(0);791coeffs.Elem(5) = b(1);792coeffs.Elem(6) = b(2);793coeffs.Elem(7) = r;794}795796void Cylinder :: SetPrimitiveData (ARRAY<double> & coeffs)797{798a(0) = coeffs.Elem(1);799a(1) = coeffs.Elem(2);800a(2) = coeffs.Elem(3);801b(0) = coeffs.Elem(4);802b(1) = coeffs.Elem(5);803b(2) = coeffs.Elem(6);804r = coeffs.Elem(7);805806807vab = (b - a);808vab /= vab.Length();809810811double hv;812cxx = cyy = czz = 0.5 / r;813cxy = cxz = cyz = 0;814cx = - a(0) / r;815cy = - a(1) / r;816cz = - a(2) / r;817c1 = (a(0) * a(0) + a(1) * a(1) + a(2) * a(2)) / (2 * r);818hv = a(0) * vab(0) + a(1) * vab(1) + a(2) * vab(2);819cxx -= vab(0) * vab(0) / (2 * r);820cyy -= vab(1) * vab(1) / (2 * r);821czz -= vab(2) * vab(2) / (2 * r);822cxy -= vab(0) * vab(1) / r;823cxz -= vab(0) * vab(2) / r;824cyz -= vab(1) * vab(2) / r;825cx += vab(0) * hv / r;826cy += vab(1) * hv / r;827cz += vab(2) * hv / r;828c1 -= hv * hv / (2 * r);829c1 -= r / 2;830}831832Primitive * Cylinder :: CreateDefault ()833{834return new Cylinder (Point<3> (0,0,0), Point<3> (1,0,0), 1);835}836837838839840Primitive * Cylinder :: Copy () const841{842return new Cylinder (a, b, r);843}844845846int Cylinder :: IsIdentic (const Surface & s2, int & inv, double eps) const847{848const Cylinder * cyl2 = dynamic_cast<const Cylinder*> (&s2);849850if (!cyl2) return 0;851852if (fabs (cyl2->r - r) > eps) return 0;853854Vec<3> v1 = b - a;855Vec<3> v2 = cyl2->a - a;856857if ( fabs (v1 * v2) < (1-eps) * v1.Length() * v2.Length()) return 0;858v2 = cyl2->b - a;859if ( fabs (v1 * v2) < (1-eps) * v1.Length() * v2.Length()) return 0;860861inv = 0;862return 1;863}864865866867void Cylinder :: Transform (Transformation<3> & trans)868{869Point<3> hp;870trans.Transform (a, hp);871a = hp;872trans.Transform (b, hp);873b = hp;874875vab = (b - a);876vab /= vab.Length();877878// ( <x,x> - 2 <x,a> + <a,a>879// - <x,vab>^2 + 2 <x,vab> <a, vab> - <a, vab>^2880// - r^2) / (2r) = 0881882double hv;883cxx = cyy = czz = 0.5 / r;884cxy = cxz = cyz = 0;885cx = - a(0) / r;886cy = - a(1) / r;887cz = - a(2) / r;888c1 = (a(0) * a(0) + a(1) * a(1) + a(2) * a(2)) / (2 * r);889hv = a(0) * vab(0) + a(1) * vab(1) + a(2) * vab(2);890cxx -= vab(0) * vab(0) / (2 * r);891cyy -= vab(1) * vab(1) / (2 * r);892czz -= vab(2) * vab(2) / (2 * r);893cxy -= vab(0) * vab(1) / r;894cxz -= vab(0) * vab(2) / r;895cyz -= vab(1) * vab(2) / r;896cx += vab(0) * hv / r;897cy += vab(1) * hv / r;898cz += vab(2) * hv / r;899c1 -= hv * hv / (2 * r);900c1 -= r / 2;901// PrintCoeff ();902}903904905906907908909910911912void Cylinder :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2)913{914Surface::DefineTangentialPlane (ap1, ap2);915916ez = Center (p1, p2) - a;917ez -= (ez * vab) * vab;918ez /= ez.Length();919920ex = p2 - p1;921ex -= (ex * ez) * ez;922ex /= ex.Length();923924ey = Cross (ez, ex);925}926927928void Cylinder :: ToPlane (const Point<3> & p,929Point<2> & pplane,930double h, int & zone) const931{932Point<3> cp1p2 = Center (p1, p2);933Project (cp1p2);934935Point<3> ccp1p2 = a + ( (cp1p2 - a) * vab ) * vab;936937Vec<3> er = cp1p2 - ccp1p2;938er.Normalize();939Vec<3> ephi = Cross (vab, er);940941double co, si;942Point<2> p1p, p2p, pp;943944co = er * (p1 - ccp1p2);945si = ephi * (p1 - ccp1p2);946p1p(0) = r * atan2 (si, co);947p1p(1) = vab * (p1 - ccp1p2);948949co = er * (p2 - ccp1p2);950si = ephi * (p2 - ccp1p2);951p2p(0) = r * atan2 (si, co);952p2p(1) = vab * (p2 - ccp1p2);953954co = er * (p - ccp1p2);955si = ephi * (p - ccp1p2);956957double phi = atan2 (si, co);958pp(0) = r * phi;959pp(1) = vab * (p - ccp1p2);960961zone = 0;962if (phi > 1.57) zone = 1;963if (phi < -1.57) zone = 2;964965966967Vec<2> e2x = p2p - p1p;968e2x /= e2x.Length();969970Vec<2> e2y (-e2x(1), e2x(0));971972Vec<2> p1pp = pp - p1p;973974975pplane(0) = (p1pp * e2x) / h;976pplane(1) = (p1pp * e2y) / h;977978/*979(*testout) << "p1 = " << p1 << ", p2 = " << p2 << endl;980(*testout) << "p = " << p << ", pp = " << pp << ", pplane = " << pplane << endl;981*/982983/*984Vec<3> p1p;985986p1p = p - p1;987988if (p1p * ez < -1 * r)989{990zone = -1;991pplane(0) = 1e8;992pplane(1) = 1e8;993}994else995{996zone = 0;997p1p /= h;998pplane(0) = p1p * ex;999pplane(1) = p1p * ey;1000}1001*/1002}10031004void Cylinder :: FromPlane (const Point<2> & pplane, Point<3> & p, double h) const1005{1006Point<2> pplane2 (pplane);10071008pplane2(0) *= h;1009pplane2(1) *= h;10101011p(0) = p1(0) + pplane2(0) * ex(0) + pplane2(1) * ey(0);1012p(1) = p1(1) + pplane2(0) * ex(1) + pplane2(1) * ey(1);1013p(2) = p1(2) + pplane2(0) * ex(2) + pplane2(1) * ey(2);1014Project (p);1015}101610171018void Cylinder :: Project (Point<3> & p) const1019{1020Vec<3> v;1021Point<3> c;10221023c = a + ((p - a) * vab) * vab;1024v = p - c;1025v *= (r / v.Length());1026p = c + v;1027}1028/*1029int Cylinder :: RootInBox (const BoxSphere<3> & box) const1030{1031double dist;1032dist = sqrt (2 * CalcFunctionValue(box.Center()) * r + r * r);1033if (fabs (dist - r) > box.Diam()/2) return 0;1034return 2;1035}1036*/10371038INSOLID_TYPE Cylinder :: BoxInSolid (const BoxSphere<3> & box) const1039{1040double dist;1041// dist = sqrt (2 * CalcFunctionValue(box.Center()) * r + r * r);10421043dist = (2 * CalcFunctionValue(box.Center()) * r + r * r);1044if (dist <= 0) dist = 0;1045else dist = sqrt (dist + 1e-16);10461047if (dist - box.Diam()/2 > r) return IS_OUTSIDE;1048if (dist + box.Diam()/2 < r) return IS_INSIDE;1049return DOES_INTERSECT;1050}105110521053double Cylinder :: HesseNorm () const1054{1055return 2 / r;1056}10571058Point<3> Cylinder :: GetSurfacePoint () const1059{1060Vec<3> vr;1061if (fabs (vab(0)) > fabs(vab(2)))1062vr = Vec<3> (vab(1), -vab(0), 0);1063else1064vr = Vec<3> (0, -vab(2), vab(1));10651066vr *= (r / vr.Length());1067return a + vr;1068}10691070void Cylinder :: GetTriangleApproximation1071(TriangleApproximation & tas,1072const Box<3> & boundingbox, double facets) const1073{1074int i, j;1075double lg, bg;1076int n = int(facets) + 1;10771078Vec<3> lvab = b - a;1079Vec<3> n1 = lvab.GetNormal();1080Vec<3> n2 = Cross (lvab, n1);10811082n1.Normalize();1083n2.Normalize();108410851086for (j = 0; j <= n; j++)1087for (i = 0; i <= n; i++)1088{1089lg = 2 * M_PI * double (i) / n;1090bg = double(j) / n;10911092Point<3> p = a + (bg * lvab)1093+ ((r * cos(lg)) * n1)1094+ ((r * sin(lg)) * n2);10951096tas.AddPoint (p);1097}10981099for (j = 0; j < n; j++)1100for (i = 0; i < n; i++)1101{1102int pi = i + (n+1) * j;1103tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2));1104tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1));1105}1106}1107110811091110111111121113111411151116EllipticCylinder ::1117EllipticCylinder (const Point<3> & aa,1118const Vec<3> & avl, const Vec<3> & avs)1119{1120a = aa;1121if(avl.Length2() > avs.Length2())1122{1123vl = avl;1124vs = avs;1125}1126else1127{1128vl = avs;1129vs = avl;1130}11311132CalcData();1133// Print (cout);1134}113511361137void EllipticCylinder :: CalcData ()1138{1139// f = (x-a, vl)^2 / |vl|^2 + (x-a, vs)^2 / |vs|^2 -111401141Vec<3> hvl, hvs;1142double lvl = vl.Length2 ();1143if (lvl < 1e-32) lvl = 1;1144double lvs = vs.Length2 ();1145if (lvs < 1e-32) lvs = 1;11461147hvl = (1.0 / lvl) * vl;1148hvs = (1.0 / lvs) * vs;11491150cxx = hvl(0) * hvl(0) + hvs(0) * hvs(0);1151cyy = hvl(1) * hvl(1) + hvs(1) * hvs(1);1152czz = hvl(2) * hvl(2) + hvs(2) * hvs(2);11531154cxy = 2 * (hvl(0) * hvl(1) + hvs(0) * hvs(1));1155cxz = 2 * (hvl(0) * hvl(2) + hvs(0) * hvs(2));1156cyz = 2 * (hvl(1) * hvl(2) + hvs(1) * hvs(2));11571158Vec<3> va (a);1159c1 = pow(va * hvl,2) + pow(va * hvs,2) - 1;11601161Vec<3> v = -2 * (va * hvl) * hvl - 2 * (va * hvs) * hvs;1162cx = v(0);1163cy = v(1);1164cz = v(2);1165}116611671168INSOLID_TYPE EllipticCylinder :: BoxInSolid (const BoxSphere<3> & box) const1169{1170double grad = 2.0 / vs.Length ();1171double ggrad = 1.0 / vs.Length2 ();11721173double val = CalcFunctionValue (box.Center());1174double r = box.Diam() / 2;1175double maxval = grad * r + ggrad * r * r;11761177// (*testout) << "box = " << box << ", val = " << val << ", maxval = " << maxval << endl;11781179if (val > maxval) return IS_OUTSIDE;1180if (val < -maxval) return IS_INSIDE;1181return DOES_INTERSECT;1182}118311841185double EllipticCylinder :: HesseNorm () const1186{1187return 1.0/min(vs.Length2 (),vl.Length2());1188}11891190double EllipticCylinder :: MaxCurvature () const1191{1192double aa = vs.Length();1193double bb = vl.Length();11941195return max2(bb/(aa*aa),aa/(bb*bb));1196}11971198double EllipticCylinder :: MaxCurvatureLoc (const Point<3> & c,1199double rad) const1200{1201#ifdef JOACHIMxxx1202cout << "max curv local" << endl;1203return 0.02;1204#endif12051206// saubere Loesung wird noch notwendig !!!1207double aa = vs.Length();1208double bb = vl.Length();1209return max2(bb/(aa*aa),aa/(bb*bb));1210}1211121212131214Point<3> EllipticCylinder :: GetSurfacePoint () const1215{1216return a + vl;1217}1218121912201221void EllipticCylinder :: GetTriangleApproximation1222(TriangleApproximation & tas,1223const Box<3> & boundingbox, double facets) const1224{1225int i, j;1226double lg, bg;1227int n = int(facets) + 1;12281229Vec<3> axis = Cross (vl, vs);12301231for (j = 0; j <= n; j++)1232for (i = 0; i <= n; i++)1233{1234lg = 2 * M_PI * double (i) / n;1235bg = double(j) / n;12361237Point<3> p = a + (bg * axis)1238+ cos(lg) * vl + sin(lg) * vs;12391240tas.AddPoint (p);1241}12421243for (j = 0; j < n; j++)1244for (i = 0; i < n; i++)1245{1246int pi = i + (n+1) * j;1247tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2));1248tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1));1249}1250}12511252125312541255125612571258125912601261Cone :: Cone (const Point<3> & aa, const Point<3> & ab,1262double ara, double arb)1263{1264a = aa;1265b = ab;1266ra = ara;1267rb = arb;12681269CalcData();1270// Print (cout);1271}127212731274Primitive * Cone :: CreateDefault ()1275{1276return new Cone (Point<3> (0,0,0), Point<3> (1,0,0), 0.5, 0.2);1277}12781279128012811282void Cone :: GetPrimitiveData (const char *& classname, ARRAY<double> & coeffs) const1283{1284classname = "cone";1285coeffs.SetSize (8);1286coeffs.Elem(1) = a(0);1287coeffs.Elem(2) = a(1);1288coeffs.Elem(3) = a(2);1289coeffs.Elem(4) = b(0);1290coeffs.Elem(5) = b(1);1291coeffs.Elem(6) = b(2);1292coeffs.Elem(7) = ra;1293coeffs.Elem(8) = rb;1294}12951296void Cone :: SetPrimitiveData (ARRAY<double> & coeffs)1297{1298a(0) = coeffs.Elem(1);1299a(1) = coeffs.Elem(2);1300a(2) = coeffs.Elem(3);1301b(0) = coeffs.Elem(4);1302b(1) = coeffs.Elem(5);1303b(2) = coeffs.Elem(6);1304ra = coeffs.Elem(7);1305rb = coeffs.Elem(8);13061307CalcData();1308}13091310void Cone :: CalcData ()1311{13121313minr = (ra < rb) ? ra : rb;13141315vab = b - a;1316vabl = vab.Length();13171318Vec<3> va (a);13191320//1321// f = r(P)^2 - R(z(P))^21322//1323// z(P) = t0vec * P + t0 = (P-a, b-a)/(b-a,b-a)1324// R(z(P)) = t1vec * P + t1 = rb * z + ra * (1-z)1325// r(P)^2 =||P-a||^2 - ||a-b||^2 z^2k132613271328t0vec = vab;1329t0vec /= (vabl * vabl);1330t0 = -(va * vab) / (vabl * vabl);13311332t1vec = t0vec;1333t1vec *= (rb - ra);1334t1 = ra + (rb - ra) * t0;13351336cxx = cyy = czz = 1;1337cxy = cxz = cyz = 0;13381339cxx = 1 - (vab*vab) * t0vec(0) * t0vec(0) - t1vec(0) * t1vec(0);1340cyy = 1 - (vab*vab) * t0vec(1) * t0vec(1) - t1vec(1) * t1vec(1);1341czz = 1 - (vab*vab) * t0vec(2) * t0vec(2) - t1vec(2) * t1vec(2);13421343cxy = -2 * (vab * vab) * t0vec(0) * t0vec(1) - 2 * t1vec(0) * t1vec(1);1344cxz = -2 * (vab * vab) * t0vec(0) * t0vec(2) - 2 * t1vec(0) * t1vec(2);1345cyz = -2 * (vab * vab) * t0vec(1) * t0vec(2) - 2 * t1vec(1) * t1vec(2);13461347cx = -2 * a(0) - 2 * (vab * vab) * t0 * t0vec(0) - 2 * t1 * t1vec(0);1348cy = -2 * a(1) - 2 * (vab * vab) * t0 * t0vec(1) - 2 * t1 * t1vec(1);1349cz = -2 * a(2) - 2 * (vab * vab) * t0 * t0vec(2) - 2 * t1 * t1vec(2);13501351c1 = va.Length2() - (vab * vab) * t0 * t0 - t1 * t1;135213531354double maxr = max2(ra,rb);1355cxx /= maxr; cyy /= maxr; czz /= maxr;1356cxy /= maxr; cxz /= maxr; cyz /= maxr;1357cx /= maxr; cy /= maxr; cz /= maxr;1358c1 /= maxr;135913601361// (*testout) << "t0vec = " << t0vec << " t0 = " << t0 << endl;1362// (*testout) << "t1vec = " << t1vec << " t1 = " << t1 << endl;1363// PrintCoeff (*testout);1364}136513661367INSOLID_TYPE Cone :: BoxInSolid (const BoxSphere<3> & box) const1368{1369double rp, dist;13701371Vec<3> cv(box.Center());13721373rp = cv * t1vec + t1;1374dist = sqrt (CalcFunctionValue(box.Center()) *max2(ra,rb) + rp * rp) - rp;13751376if (dist - box.Diam() > 0) return IS_OUTSIDE;1377if (dist + box.Diam() < 0) return IS_INSIDE;1378return DOES_INTERSECT;1379}138013811382double Cone :: HesseNorm () const1383{1384return 2 / minr;1385}138613871388double Cone :: LocH (const Point<3> & p, double x,1389double c, double hmax) const1390{1391//double bloch = Surface::LocH (p, x, c, hmax);1392Vec<3> g;1393CalcGradient (p, g);13941395double lam = Abs(g);1396double meancurv =1397-( 2 * g(0)*g(1)*cxy - 2 * czz * (g(0)*g(0)+g(1)*g(1))1398+2 * g(1)*g(2)*cyz - 2 * cxx * (g(1)*g(1)+g(2)*g(2))1399+2 * g(0)*g(2)*cxz - 2 * cyy * (g(0)*g(0)+g(2)*g(2))) / (3*lam*lam*lam);14001401// cout << "type = " << typeid(*this).name() << ", baseh = " << bloch << ", meancurv = " << meancurv << endl;1402// return bloch;14031404meancurv = fabs (meancurv);1405if (meancurv < 1e-20) meancurv = 1e-20;14061407// cout << "c = " << c << ", safety = " << mparam.curvaturesafety << endl;1408double hcurv = 1.0/(4*meancurv*mparam.curvaturesafety);14091410return min2 (hmax, hcurv);1411}141214131414Point<3> Cone :: GetSurfacePoint () const1415{1416Vec<3> vr = vab.GetNormal ();14171418vr *= (ra / vr.Length());1419return a + vr;1420}142114221423142414251426void Cone :: GetTriangleApproximation1427(TriangleApproximation & tas,1428const Box<3> & boundingbox, double facets) const1429{1430int i, j;1431double lg, bg;1432int n = int(facets) + 1;14331434Vec<3> lvab = b - a;1435Vec<3> n1 = lvab.GetNormal();1436Vec<3> n2 = Cross (lvab, n1);14371438n1.Normalize();1439n2.Normalize();144014411442for (j = 0; j <= n; j++)1443for (i = 0; i <= n; i++)1444{1445lg = 2 * M_PI * double (i) / n;1446bg = double(j) / n;14471448Point<3> p = a + (bg * lvab)1449+ (( (ra+(rb-ra)*bg) * cos(lg)) * n1)1450+ (( (ra+(rb-ra)*bg) * sin(lg)) * n2);14511452tas.AddPoint (p);1453}14541455for (j = 0; j < n; j++)1456for (i = 0; i < n; i++)1457{1458int pi = i + (n+1) * j;1459tas.AddTriangle (TATriangle (0, pi, pi+1, pi+n+2));1460tas.AddTriangle (TATriangle (0, pi, pi+n+2, pi+n+1));1461}1462}1463146414651466146714681469147014711472/// Torus1473/// Lorenzo Codecasa ([email protected])1474/// April 27th, 20051475///1476/// begin...1477Torus :: Torus (const Point<3> & ac, const Vec<3> & an, double aR, double ar)1478{1479c = ac;1480n = an;1481R = aR;1482r = ar;1483}14841485void Torus :: GetPrimitiveData (const char *& classname, ARRAY<double> & coeffs) const1486{1487classname = "torus";1488coeffs.SetSize (8);1489coeffs.Elem(1) = c(0);1490coeffs.Elem(2) = c(1);1491coeffs.Elem(3) = c(2);1492coeffs.Elem(4) = n(0);1493coeffs.Elem(5) = n(1);1494coeffs.Elem(6) = n(2);1495coeffs.Elem(7) = R;1496coeffs.Elem(8) = r;1497}14981499void Torus :: SetPrimitiveData (ARRAY<double> & coeffs)1500{1501c(0) = coeffs.Elem(1);1502c(1) = coeffs.Elem(2);1503c(2) = coeffs.Elem(3);1504n(0) = coeffs.Elem(4);1505n(1) = coeffs.Elem(5);1506n(2) = coeffs.Elem(6);1507R = coeffs.Elem(7);1508r = coeffs.Elem(8);1509}15101511Primitive * Torus :: CreateDefault ()1512{1513return new Torus (Point<3> (0,0,0), Vec<3> (0,0,1), 2, 1);1514}15151516Primitive * Torus :: Copy () const1517{1518return new Torus (c, n, R, r);1519}15201521void Torus :: Transform (Transformation<3> & trans)1522{1523Point<3> hc;1524trans.Transform (c, hc);1525c = hc;15261527Vec<3> hn;1528trans.Transform (n, hn);1529n = hn;1530}15311532int Torus :: IsIdentic (const Surface & s2, int & inv, double eps) const1533{1534const Torus * torus2 = dynamic_cast<const Torus*> (&s2);15351536if (!torus2) return 0;15371538if (fabs (torus2->R - R) > eps) return 0;15391540if (fabs (torus2->r - r) > eps) return 0;15411542Vec<3> v2 = torus2->n - n;1543if ( v2 * v2 > eps ) return 0;15441545v2 = torus2->c - c;1546if ( v2 * v2 > eps ) return 0;15471548inv = 0;1549return 1;1550}15511552double Torus :: CalcFunctionValue (const Point<3> & point) const1553{1554Vec<3> v1 = point - c;1555double a1 = v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2);1556double a2 = n(0) * v1(0) + n(1) * v1(1) + n(2) * v1(2);1557double a3 = a1 + R * R - r * r;1558double a4 = n(0) * n(0) + n(1) * n(1) + n(2) * n(2);1559return ( a3 * a3 -4 * R * R * ( a1 - a2 * a2 / a4 ) ) / ( R * R * R );1560}15611562void Torus :: CalcGradient (const Point<3> & point, Vec<3> & grad) const1563{1564Vec<3> v1 = point - c;1565double a1 = v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2);1566double a2 = n(0) * v1(0) + n(1) * v1(1) + n(2) * v1(2);1567double a3 = a1 - R * R - r * r;1568double a4 = n(0) * n(0) + n(1) * n(1) + n(2) * n(2);1569grad(0) = ( 4 * a3 * v1(0) + 8 * R * R * a2 / a4 * n(0) ) / ( R * R * R );1570grad(1) = ( 4 * a3 * v1(1) + 8 * R * R * a2 / a4 * n(1) ) / ( R * R * R );1571grad(2) = ( 4 * a3 * v1(2) + 8 * R * R * a2 / a4 * n(2) ) / ( R * R * R );1572}15731574void Torus :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const1575{1576Vec<3> v1 = point - c;1577double a1 = v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2);1578double a3 = a1 - R * R - r * r;1579double a4 = n(0) * n(0) + n(1) * n(1) + n(2) * n(2);1580hesse(0,0) = ( 4 * a3 + 8 * (v1(0) * v1(0) + (R * n(0)) * (R * n(0)) / a4 ) ) / ( R * R * R );1581hesse(1,1) = ( 4 * a3 + 8 * (v1(1) * v1(1) + (R * n(1)) * (R * n(1)) / a4 ) ) / ( R * R * R );1582hesse(2,2) = ( 4 * a3 + 8 * (v1(2) * v1(2) + (R * n(2)) * (R * n(2)) / a4 ) ) / ( R * R * R );1583hesse(0,1) = hesse(1,0) = 8 * (v1(0) * v1(1) + (R * n(0)) * (R * n(1)) / a4 ) / ( R * R * R );1584hesse(1,2) = hesse(2,1) = 8 * (v1(1) * v1(2) + (R * n(1)) * (R * n(2)) / a4) / ( R * R * R );1585hesse(0,2) = hesse(2,0) = 8 * (v1(0) * v1(2) + (R * n(0)) * (R * n(2)) / a4) / ( R * R * R );1586}15871588double Torus :: HesseNorm () const1589{1590return ( 2 / r + 2 / ( R - r ) );1591}15921593Point<3> Torus :: GetSurfacePoint () const1594{1595Vec<3> vn = n.GetNormal();1596return c + ( R + r ) * vn.Normalize();1597}15981599/// void Torus :: DefineTangentialPlane (const Point<3> & ap1, const Point<3> & ap2)1600/// {1601/// }16021603/// void Torus :: ToPlane (const Point<3> & p,1604/// Point<2> & pplane,1605/// double h, int & zone) const1606/// {1607/// }16081609/// void Torus :: FromPlane (const Point<2> & pplane, Point<3> & p, double h) const1610/// {1611/// }16121613/// void Torus :: Project (Point<3> & p) const1614/// {1615/// }16161617INSOLID_TYPE Torus :: BoxInSolid (const BoxSphere<3> & box) const1618{1619Vec<3> v1 = box.Center() - c;1620double a1 = v1(0) * v1(0) + v1(1) * v1(1) + v1(2) * v1(2);1621double a2 = n(0) * v1(0) + n(1) * v1(1) + n(2) * v1(2);1622double a4 = n(0) * n(0) + n(1) * n(1) + n(2) * n(2);16231624double dist = sqrt( a1 + R * R - 2 * R * sqrt( a1 - a2 * a2 / a4) );16251626if (dist - box.Diam()/2 > r) return IS_OUTSIDE;1627if (dist + box.Diam()/2 < r) return IS_INSIDE;1628return DOES_INTERSECT;1629}16301631void Torus :: GetTriangleApproximation (TriangleApproximation & tas,1632const Box<3> & boundingbox, double facets) const1633{1634int i, j;1635double lg, bg;1636int N = int(facets) + 1;16371638Vec<3> lvab = n ;1639lvab.Normalize();16401641Vec<3> n1 = lvab.GetNormal();1642n1.Normalize();16431644Vec<3> n2 = Cross(lvab, n1);1645n2.Normalize();16461647for (j = 0; j <= N; j++)1648for (i = 0; i <= N; i++)1649{1650lg = 2 * M_PI * double (i) / N;1651bg = 2 * M_PI * double(j) / N;16521653Point<3> p = c + ( R + r * cos(lg) ) * ( cos(bg) * n1 + sin(bg) * n2 ) + r * sin(lg) * n;1654tas.AddPoint (p);1655}16561657for (j = 0; j < N; j++)1658for (i = 0; i < N; i++)1659{1660int pi = i + (N+1) * j;1661tas.AddTriangle (TATriangle (0, pi, pi+1, pi+N+2));1662tas.AddTriangle (TATriangle (0, pi, pi+N+2, pi+N+1));1663}1664}16651666void Torus :: Read (istream & ist)1667{1668ist >> c(0) >> c(1) >> c(2) >> n(0) >> n(1) >> n(2) >> R >> r;1669}16701671void Torus :: Print (ostream & ost) const1672{1673ost << c(0) << " " << c(1) << " " << c(2) << " "1674<< n(0) << " " << n(1) << " " << n(2) << " "1675<< R << " " << r << endl;1676}16771678/// end...16791680168116821683168416851686168716881689169016911692169316941695}169616971698