Path: blob/devel/ElmerGUI/netgen/libsrc/csg/revolution.cpp
3206 views
#include <mystdlib.h>12#include <linalg.hpp>3#include <csg.hpp>45namespace netgen6{7void RevolutionFace :: Init(void)8{9const LineSeg<2> * line = dynamic_cast<const LineSeg<2>*>(spline);10const SplineSeg3<2> * spline3 = dynamic_cast<const SplineSeg3<2>*>(spline);1112if(line)13{14checklines_start.Append(new Point<2>(line->StartPI()));15checklines_vec.Append(new Vec<2>(line->EndPI() - line->StartPI()));16(*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!!17}18else if (spline3)19{20checklines_start.Append(new Point<2>(spline3->EndPI()));21checklines_start.Append(new Point<2>(spline3->TangentPoint()));22checklines_start.Append(new Point<2>(spline3->StartPI()));23checklines_vec.Append(new Vec<2>(spline3->StartPI() - spline3->EndPI()));24(*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!!25checklines_vec.Append(new Vec<2>(spline3->EndPI() - spline3->TangentPoint()));26(*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!!27checklines_vec.Append(new Vec<2>(spline3->TangentPoint() - spline3->StartPI()));28(*checklines_vec.Last()) *= 1./pow(checklines_vec.Last()->Length(),2); //!!2930}3132for(int i=0; i<checklines_vec.Size(); i++)33{34checklines_normal.Append(new Vec<2>);35(*checklines_normal.Last())(0) = - (*checklines_vec[i])(1);36(*checklines_normal.Last())(1) = (*checklines_vec[i])(0);37checklines_normal.Last()->Normalize();38}39}4041RevolutionFace :: RevolutionFace(const SplineSeg<2> & spline_in,42const Point<3> & p,43const Vec<3> & vec,44bool first,45bool last,46const int id_in) :47spline(&spline_in), p0(p), v_axis(vec), isfirst(first), islast(last), id(id_in)48{49deletable = false;50Init();51}525354RevolutionFace :: RevolutionFace(const ARRAY<double> & raw_data)55{56deletable = true;5758int pos = 0;5960ARRAY< Point<2> > p(3);6162int stype = int(raw_data[pos]); pos++;6364for(int i=0; i<stype; i++)65{66p[i](0) = raw_data[pos]; pos++;67p[i](1) = raw_data[pos]; pos++;68}6970if(stype == 2)71{72spline = new LineSeg<2>(GeomPoint<2>(p[0],1),73GeomPoint<2>(p[1],1));74//(*testout) << "appending LineSeg<2> " << p[0]75// << " to " << p[1] << endl;76}77else if(stype == 3)78{79spline = new SplineSeg3<2>(GeomPoint<2>(p[0],1),80GeomPoint<2>(p[1],1),81GeomPoint<2>(p[2],1));82//(*testout) << "appending SplineSeg<3> "83// << p[0] << " -- " << p[1] << " -- " << p[2] << endl;84}8586for(int i=0; i<3; i++)87{88p0(i) = raw_data[pos];89pos++;90}91for(int i=0; i<3; i++)92{93v_axis(i) = raw_data[pos];94pos++;95}96isfirst = (raw_data[pos] > 0.9);97pos++;98islast = (raw_data[pos] < 0.1);99pos++;100101102}103104105RevolutionFace :: ~RevolutionFace()106{107for(int i=0; i<checklines_start.Size(); i++)108{109delete checklines_start[i];110delete checklines_vec[i];111delete checklines_normal[i];112}113114if(deletable)115delete spline;116}117118void RevolutionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d,119const Vec<3> & vector3d, Vec<2> & vector2d) const120{121Vec<3> pmp0 = point3d-p0;122CalcProj0(pmp0,point2d);123Vec<3> y=pmp0-point2d(0)*v_axis; y.Normalize();124vector2d(0) = vector3d*v_axis;125vector2d(1) = vector3d*y;126}127128129void RevolutionFace :: CalcProj(const Point<3> & point3d, Point<2> & point2d) const130{131Vec<3> pmp0 = point3d-p0;132CalcProj0(pmp0,point2d);133}134135void RevolutionFace :: CalcProj0(const Vec<3> & point3d_minus_p0, Point<2> & point2d) const136{137point2d(0) = point3d_minus_p0 * v_axis;138point2d(1) = sqrt( point3d_minus_p0 * point3d_minus_p0 - point2d(0)*point2d(0) );139}140141142int RevolutionFace ::IsIdentic (const Surface & s2, int & inv, double eps) const143{144const RevolutionFace * rev2 = dynamic_cast<const RevolutionFace*>(&s2);145146if(!rev2) return 0;147148if(rev2 == this)149return 1;150151return 0;152}153154double RevolutionFace :: CalcFunctionValue (const Point<3> & point) const155{156if(spline_coefficient.Size() == 0)157spline->GetCoeff(spline_coefficient);158159Point<2> p;160CalcProj(point,p);161162return spline_coefficient(0)*p(0)*p(0) + spline_coefficient(1)*p(1)*p(1)163+ spline_coefficient(2)*p(0)*p(1) + spline_coefficient(3)*p(0)164+ spline_coefficient(4)*p(1) + spline_coefficient(5);165}166167void RevolutionFace :: CalcGradient (const Point<3> & point, Vec<3> & grad) const168{169if(spline_coefficient.Size() == 0)170spline->GetCoeff(spline_coefficient);171172Vec<3> point_minus_p0 = point-p0;173174Point<2> p;175CalcProj0(point_minus_p0,p);176177const double dFdxbar = 2.*spline_coefficient(0)*p(0) + spline_coefficient(2)*p(1) + spline_coefficient(3);178179if(fabs(p(1)) > 1e-10)180{181const double dFdybar = 2.*spline_coefficient(1)*p(1) + spline_coefficient(2)*p(0) + spline_coefficient(4);182183grad(0) = dFdxbar*v_axis(0) + dFdybar * ( point_minus_p0(0)-v_axis(0)*p(0) )/p(1);184grad(1) = dFdxbar*v_axis(1) + dFdybar * ( point_minus_p0(1)-v_axis(1)*p(0) )/p(1);185grad(2) = dFdxbar*v_axis(2) + dFdybar * ( point_minus_p0(2)-v_axis(2)*p(0) )/p(1);186//(*testout) << "grad1("<<point<<") = " << grad << endl;187}188else189{190grad(0) = dFdxbar*v_axis(0);191grad(1) = dFdxbar*v_axis(1);192grad(2) = dFdxbar*v_axis(2);193//(*testout) << "grad2("<<point<<") = " << grad << endl;194}195}196197198void RevolutionFace :: CalcHesse (const Point<3> & point, Mat<3> & hesse) const199{200if(spline_coefficient.Size() == 0)201spline->GetCoeff(spline_coefficient);202203Vec<3> point_minus_p0 = point-p0;204205Point<2> p;206CalcProj0(point_minus_p0,p);207208209if(fabs(p(1)) > 1e-10)210{211const double dFdybar = 2.*spline_coefficient(1)*p(1) + spline_coefficient(2)*p(0) + spline_coefficient(4);212213const double aux = -pow(p(1),-3);214const double aux0 = point_minus_p0(0) - v_axis(0)*p(0);215const double aux1 = point_minus_p0(1) - v_axis(1)*p(0);216const double aux2 = point_minus_p0(2) - v_axis(2)*p(0);217218219const double dybardx = aux0/p(1);220const double dybardy = aux1/p(1);221const double dybardz = aux2/p(1);222223const double dybardxx = aux*aux0*aux0 + (1.-v_axis(0)*v_axis(0))/p(1);224const double dybardyy = aux*aux1*aux1 + (1.-v_axis(1)*v_axis(1))/p(1);225const double dybardzz = aux*aux2*aux2 + (1.-v_axis(2)*v_axis(2))/p(1);226const double dybardxy = aux*aux0*aux1 - v_axis(0)*v_axis(1)/p(1);227const double dybardxz = aux*aux0*aux2 - v_axis(0)*v_axis(2)/p(1);228const double dybardyz = aux*aux1*aux2 - v_axis(1)*v_axis(2)/p(1);229230hesse(0,0) = 2.*spline_coefficient(0)*v_axis(0)*v_axis(0) + 2.*spline_coefficient(2)*v_axis(0)*dybardx + 2.*spline_coefficient(1)*dybardx*dybardx231+ dFdybar*dybardxx;232hesse(1,1) = 2.*spline_coefficient(0)*v_axis(1)*v_axis(1) + 2.*spline_coefficient(2)*v_axis(1)*dybardy + 2.*spline_coefficient(1)*dybardy*dybardy233+ dFdybar*dybardyy;234hesse(2,2) = 2.*spline_coefficient(0)*v_axis(2)*v_axis(2) + 2.*spline_coefficient(2)*v_axis(2)*dybardz + 2.*spline_coefficient(1)*dybardz*dybardz235+ dFdybar*dybardzz;236237hesse(0,1) = hesse(1,0) = 2.*spline_coefficient(0)*v_axis(0)*v_axis(1) + spline_coefficient(2)*v_axis(0)*dybardy + spline_coefficient(2)*dybardx*v_axis(1)238+ 2.*spline_coefficient(2)*dybardx*dybardy + dFdybar*dybardxy;239hesse(0,2) = hesse(2,0) = 2.*spline_coefficient(0)*v_axis(0)*v_axis(2) + spline_coefficient(2)*v_axis(0)*dybardz + spline_coefficient(2)*dybardx*v_axis(2)240+ 2.*spline_coefficient(2)*dybardx*dybardz + dFdybar*dybardxz;241hesse(1,2) = hesse(2,1) = 2.*spline_coefficient(0)*v_axis(1)*v_axis(2) + spline_coefficient(2)*v_axis(1)*dybardz + spline_coefficient(2)*dybardy*v_axis(2)242+ 2.*spline_coefficient(2)*dybardy*dybardz + dFdybar*dybardyz;243244//(*testout) << "hesse1: " << hesse <<endl;245}246else if (fabs(spline_coefficient(2)) + fabs(spline_coefficient(4)) < 1.e-9 &&247fabs(spline_coefficient(0)) > 1e-10)248{249double aux = spline_coefficient(0)-spline_coefficient(1);250251hesse(0,0) = aux*v_axis(0)*v_axis(0) + spline_coefficient(1);252hesse(0,0) = aux*v_axis(1)*v_axis(1) + spline_coefficient(1);253hesse(0,0) = aux*v_axis(2)*v_axis(2) + spline_coefficient(1);254255hesse(0,1) = hesse(1,0) = aux*v_axis(0)*v_axis(1);256hesse(0,2) = hesse(2,0) = aux*v_axis(0)*v_axis(2);257hesse(1,2) = hesse(2,1) = aux*v_axis(1)*v_axis(2);258//(*testout) << "hesse2: " << hesse <<endl;259260}261else if (fabs(spline_coefficient(1)) + fabs(spline_coefficient(3)) + fabs(spline_coefficient(4)) + fabs(spline_coefficient(5)) < 1.e-9) // line262{263hesse = 0;264//(*testout) << "hesse3: " << hesse <<endl;265}266else267{268(*testout) << "hesse4: " << hesse <<endl;269}270}271272273274double RevolutionFace ::HesseNorm () const275{276if (fabs(spline_coefficient(1)) + fabs(spline_coefficient(3)) + fabs(spline_coefficient(4)) + fabs(spline_coefficient(5)) < 1.e-9) // line277return 0;278279if (fabs(spline_coefficient(2)) + fabs(spline_coefficient(4)) < 1.e-9 &&280fabs(spline_coefficient(0)) > 1e-10)281return 2.*max2(fabs(spline_coefficient(0)),fabs(spline_coefficient(1)));282283284double alpha = fabs(spline_coefficient(2)*(spline->StartPI()(0)-spline->EndPI()(0))) /285max2(fabs(spline->StartPI()(1)),fabs(spline->EndPI()(1)));286287return max2(2.*fabs(spline_coefficient(0))+sqrt(2.)*fabs(spline_coefficient(2)),2882.*fabs(spline_coefficient(1))+spline_coefficient(2)+1.5*alpha);289}290291double RevolutionFace :: MaxCurvature() const292{293double retval = spline->MaxCurvature();294295ARRAY < Point<2> > checkpoints;296297const SplineSeg3<2> * ss3 = dynamic_cast<const SplineSeg3<2> *>(spline);298const LineSeg<2> * ls = dynamic_cast<const LineSeg<2> *>(spline);299300if(ss3)301{302checkpoints.Append(ss3->StartPI());303checkpoints.Append(ss3->TangentPoint());304checkpoints.Append(ss3->TangentPoint());305checkpoints.Append(ss3->EndPI());306}307else if(ls)308{309checkpoints.Append(ls->StartPI());310checkpoints.Append(ls->EndPI());311}312313for(int i=0; i<checkpoints.Size(); i+=2)314{315Vec<2> v = checkpoints[i+1]-checkpoints[i];316Vec<2> n(v(1),-v(0)); n.Normalize();317318//if(ss3)319// (*testout) << "n " << n << endl;320321if(fabs(n(1)) < 1e-15)322continue;323324double t1 = -checkpoints[i](1)/n(1);325double t2 = -checkpoints[i+1](1)/n(1);326327double c1 = (t1 > 0) ? (1./t1) : -1;328double c2 = (t2 > 0) ? (1./t2) : -1;329330//if(ss3)331// (*testout) << "t1 " << t1 << " t2 " << t2 << " c1 " << c1 << " c2 " << c2 << endl;332333if(c1 > retval)334retval = c1;335if(c2 > retval)336retval = c2;337}338339//if(ss3)340// (*testout) << "curvature " << retval << endl;341342return retval;343344/*345346347// find smallest y value of spline:348ARRAY<double> testt;349350if(!isfirst)351testt.Append(0);352if(!islast)353testt.Append(1);354355const SplineSegment3 * s3 = dynamic_cast<const SplineSegment3 *>(&spline);356357if(s3)358{359double denom = (2.-sqrt(2.))*(s3->EndPI()(1) - s3->StartPI()(1));360361if(fabs(denom) < 1e-20)362testt.Append(0.5);363else364{365double sD = sqrt(pow(s3->TangentPoint()(1) - s3->StartPI()(1),2)+366pow(s3->TangentPoint()(1) - s3->EndPI()(1),2));367testt.Append((s3->StartPI()(1)*(sqrt(2.)-1.) - sqrt(2.)*s3->TangentPoint()(1) + s3->EndPI()(1) + sD)/denom);368testt.Append((s3->StartPI()(1)*(sqrt(2.)-1.) - sqrt(2.)*s3->TangentPoint()(1) + s3->EndPI()(1) - sD)/denom);369}370}371372double miny = fabs(spline.GetPoint(testt[0])(1));373for(int i=1; i<testt.Size(); i++)374{375double thisy = fabs(spline.GetPoint(testt[i])(1));376if(thisy < miny)377miny = thisy;378}379380return max2(splinecurvature,1./miny);381*/382}383384void RevolutionFace :: Project (Point<3> & p) const385{386Point<2> p2d;387388CalcProj(p,p2d);389390const Vec<3> y = (p-p0)-p2d(0)*v_axis;391const double yl = y.Length();392393double dummy;394395spline->Project(p2d,p2d,dummy);396397p = p0 + p2d(0)*v_axis;398399if(yl > 1e-20*Dist(spline->StartPI(),spline->EndPI()))400p+= (p2d(1)/yl)*y;401}402403404405406Point<3> RevolutionFace :: GetSurfacePoint () const407{408Vec<3> random_vec(0.760320,-0.241175,0.60311534);409410Vec<3> n = Cross(v_axis,random_vec); n.Normalize();411412Point<2> sp = spline->GetPoint(0.5);413414Point<3> retval = p0 + sp(0)*v_axis + sp(1)*n;415416return retval;417}418419420void RevolutionFace :: Print (ostream & str) const421{422if(spline_coefficient.Size() == 0)423spline->GetCoeff(spline_coefficient);424425str << p0(0) << " " << p0(1) << " " << p0(2) << " "426<< v_axis(0) << " " << v_axis(1) << " " << v_axis(2) << " ";427for(int i=0; i<6; i++) str << spline_coefficient(i) << " ";428str << endl;429}430431432void RevolutionFace :: GetTriangleApproximation (TriangleApproximation & tas,433const Box<3> & boundingbox,434double facets) const435{436Vec<3> random_vec(0.760320,-0.241175,0.60311534);437438Vec<3> v1 = Cross(v_axis,random_vec); v1.Normalize();439Vec<3> v2 = Cross(v1,v_axis); v2.Normalize();440441int n = int(2.*facets) + 1;442443int i,j;444double phi;445Point<3> p;446447for(i=0; i<=n; i++)448{449Point<2> sp = spline->GetPoint(double(i)/double(n));450for(j=0; j<=n; j++)451{452phi = 2.*M_PI*double(j)/double(n);453454p = p0 + sp(0)*v_axis + sp(1)*cos(phi)*v1 + sp(1)*sin(phi)*v2;455tas.AddPoint(p);456}457}458459for(i=0; i<n; i++)460for(j=0; j<n; j++)461{462int pi = (n+1)*i+j;463464tas.AddTriangle( TATriangle (id, pi,pi+1,pi+n+1));465tas.AddTriangle( TATriangle (id, pi+1,pi+n+1,pi+n+2));466}467}468469470bool RevolutionFace :: BoxIntersectsFace(const Box<3> & box) const471{472Point<3> center = box.Center();473474Project(center);475476return (Dist(box.Center(),center) < 0.5*box.Diam());477}478479480/*481bool RevolutionFace :: BoxIntersectsFace (const BoxSphere<3> & box, bool & uncertain) const482{483Point<2> c,pmin,pmax;484CalcProj(box.Center(),c);485double aux = box.Diam()/sqrt(8.);486pmin(0) = c(0)-aux; pmin(1) = c(1)-aux;487pmax(0) = c(0)+aux; pmax(1) = c(1)+aux;488489BoxSphere<2> box2d(pmin,pmax);490return BoxIntersectsFace(box2d, uncertain);491}492493bool RevolutionFace :: BoxIntersectsFace (const BoxSphere<2> & box, bool & uncertain) const494{495const LineSegment * line = dynamic_cast<const LineSegment*>(&spline);496const SplineSegment3 * spline3 = dynamic_cast<const SplineSegment3*>(&spline);497498bool always_right = true, always_left = true;499500bool retval = false;501bool thisint;502bool intdirect = false;503bool inttangent = false;504uncertain = false;505506if(line) inttangent = true;507508for(int i=0; i<checklines_start.Size(); i++)509{510Vec<2> b = box.Center()- (*checklines_start[i]);511512double d;513514double checkdist = b * (*checklines_vec[i]);515double ncomp = b * (*checklines_normal[i]);516517if(checkdist < 0)518d = b.Length();519else if (checkdist > 1)520{521if(spline3)522d = Dist(box.Center(),*checklines_start[(i+1)%3]);523else524d = Dist(box.Center(),(*checklines_start[i])525+ pow(checklines_vec[i]->Length(),2)*(*checklines_vec[i]));526}527else528d = fabs(ncomp);529530thisint = (box.Diam() >= 2.*d);531retval = retval || thisint;532if(thisint)533{534if(i==0)535intdirect = true;536else537inttangent = true;538}539540if(ncomp > 0) always_right = false;541else if(ncomp < 0) always_left = false;542}543544if(retval && !(intdirect && inttangent))545uncertain = true;546547if(!retval && spline3 && (always_right || always_left))548{549retval = true;550uncertain = true;551}552553return retval;554}555*/556557558INSOLID_TYPE RevolutionFace :: PointInFace (const Point<3> & p, const double eps) const559{560Point<2> p2d;561CalcProj(p,p2d);562563double val = spline_coefficient(0)*p2d(0)*p2d(0) + spline_coefficient(1)*p2d(1)*p2d(1) + spline_coefficient(2)*p2d(0)*p2d(1) +564spline_coefficient(3)*p2d(0) + spline_coefficient(4)*p2d(1) + spline_coefficient(5);565566if(val > eps)567return IS_OUTSIDE;568if(val < -eps)569return IS_INSIDE;570571return DOES_INTERSECT;572}573574575576void RevolutionFace :: GetRawData(ARRAY<double> & data) const577{578data.DeleteAll();579spline->GetRawData(data);580for(int i=0; i<3; i++)581data.Append(p0(i));582for(int i=0; i<3; i++)583data.Append(v_axis(i));584data.Append((isfirst) ? 1. : 0.);585data.Append((islast) ? 1. : 0.);586}587588589590Revolution :: Revolution(const Point<3> & p0_in,591const Point<3> & p1_in,592const SplineGeometry2d & spline_in) :593p0(p0_in), p1(p1_in), splinecurve(spline_in),594nsplines(spline_in.GetNSplines())595{596surfaceactive.SetSize(0);597surfaceids.SetSize(0);598599v_axis = p1-p0;600601v_axis.Normalize();602603if(splinecurve.GetSpline(0).StartPI()(1) <= 0. &&604splinecurve.GetSpline(nsplines-1).EndPI()(1) <= 0.)605type = 2;606else if (Dist(splinecurve.GetSpline(0).StartPI(),607splinecurve.GetSpline(nsplines-1).EndPI()) < 1e-7)608type = 1;609else610cerr << "Surface of revolution cannot be constructed" << endl;611612for(int i=0; i<splinecurve.GetNSplines(); i++)613{614RevolutionFace * face = new RevolutionFace(splinecurve.GetSpline(i),615p0,v_axis,616type==2 && i==0,617type==2 && i==splinecurve.GetNSplines()-1);618faces.Append(face);619surfaceactive.Append(1);620surfaceids.Append(0);621}622}623624Revolution::~Revolution()625{626for(int i=0; i<faces.Size(); i++)627delete faces[i];628}629630631INSOLID_TYPE Revolution :: BoxInSolid (const BoxSphere<3> & box) const632{633for(int i=0; i<faces.Size(); i++)634if(faces[i]->BoxIntersectsFace(box))635return DOES_INTERSECT;636637638return PointInSolid(box.Center(),0);639640641/*642Point<2> c,pmin,pmax;643faces[0]->CalcProj(box.Center(),c);644double aux = box.Diam()/sqrt(8.);645pmin(0) = c(0)-aux; pmin(1) = c(1)-aux;646pmax(0) = c(0)+aux; pmax(1) = c(1)+aux;647648649BoxSphere<2> box2d(pmin,pmax);650651bool intersection = false;652bool uncertain = true;653654for(int i=0; !(intersection && !uncertain) && i<faces.Size(); i++)655{656bool thisintersects;657bool thisuncertain;658thisintersects = faces[i]->BoxIntersectsFace(box2d,thisuncertain);659intersection = intersection || thisintersects;660if(thisintersects && !thisuncertain)661uncertain = false;662}663664if(intersection)665{666if(!uncertain)667return DOES_INTERSECT;668else669{670ARRAY < Point<3> > pext(2);671Point<3> p;672673pext[0] = box.PMin();674pext[1] = box.PMax();675676INSOLID_TYPE position;677bool firsttime = true;678679for(int i=0; i<2; i++)680for(int j=0; j<2; j++)681for(int k=0; k<2; k++)682{683p(0) = pext[i](0);684p(1) = pext[j](1);685p(2) = pext[k](2);686INSOLID_TYPE ppos = PointInSolid(p,0);687if(ppos == DOES_INTERSECT)688return DOES_INTERSECT;689690if(firsttime)691{692firsttime = false;693position = ppos;694}695if(position != ppos)696return DOES_INTERSECT;697}698return position;699700}701}702703return PointInSolid(box.Center(),0);704*/705}706707INSOLID_TYPE Revolution :: PointInSolid (const Point<3> & p,708double eps) const709{710Point<2> p2d;711faces[0]->CalcProj(p,p2d);712713int intersections_before(0), intersections_after(0);714double randomx = 7.42357;715double randomy = 1.814756;716randomx *= 1./sqrt(randomx*randomx+randomy*randomy);717randomy *= 1./sqrt(randomx*randomx+randomy*randomy);718719720const double a = randomy;721const double b = -randomx;722const double c = -a*p2d(0)-b*p2d(1);723724ARRAY < Point<2> > points;725726//(*testout) << "face intersections at: " << endl;727for(int i=0; i<faces.Size(); i++)728{729faces[i]->GetSpline().LineIntersections(a,b,c,points,eps);730731for(int j=0; j<points.Size(); j++)732{733double t = (points[j](0)-p2d(0))/randomx;734735//(*testout) << t << endl;736if ( t < -eps )737intersections_before++;738else if ( t > eps )739intersections_after++;740else741{742intersecting_face = i;743return DOES_INTERSECT;744}745}746}747748if(intersections_before % 2 == 0)749return IS_OUTSIDE;750else751return IS_INSIDE;752}753754INSOLID_TYPE Revolution :: VecInSolid (const Point<3> & p,755const Vec<3> & v,756double eps) const757{758INSOLID_TYPE pInSolid = PointInSolid(p,eps);759760if(pInSolid != DOES_INTERSECT)761{762//(*testout) << "pInSolid" << endl;763return pInSolid;764}765766ARRAY<int> intersecting_faces;767768for(int i=0; i<faces.Size(); i++)769if(faces[i]->PointInFace(p,eps) == DOES_INTERSECT)770intersecting_faces.Append(i);771772Vec<3> hv;773774if(intersecting_faces.Size() == 1)775{776faces[intersecting_faces[0]]->CalcGradient(p,hv);777778double hv1;779hv1 = v * hv;780781if (hv1 <= -eps)782return IS_INSIDE;783if (hv1 >= eps)784return IS_OUTSIDE;785786return DOES_INTERSECT;787}788else if(intersecting_faces.Size() == 2)789{790Point<2> p2d;791Vec<2> v2d;792faces[intersecting_faces[0]]->CalcProj(p,p2d,v,v2d);793794if(Dist(faces[intersecting_faces[0]]->GetSpline().StartPI(),p2d) <795Dist(faces[intersecting_faces[0]]->GetSpline().EndPI(),p2d))796{797int aux = intersecting_faces[0];798intersecting_faces[0] = intersecting_faces[1];799intersecting_faces[1] = aux;800}801802const SplineSeg3<2> * splinesegment3 =803dynamic_cast<const SplineSeg3<2> *>(&faces[intersecting_faces[0]]->GetSpline());804const LineSeg<2> * linesegment =805dynamic_cast<const LineSeg<2> *>(&faces[intersecting_faces[0]]->GetSpline());806807Vec<2> t1,t2;808809if(linesegment)810t1 = linesegment->StartPI() - linesegment->EndPI();811else if(splinesegment3)812t1 = splinesegment3->TangentPoint() - splinesegment3->EndPI();813814linesegment =815dynamic_cast<const LineSeg<2> *>(&faces[intersecting_faces[1]]->GetSpline());816splinesegment3 =817dynamic_cast<const SplineSeg3<2> *>(&faces[intersecting_faces[1]]->GetSpline());818819if(linesegment)820t2 = linesegment->EndPI() - linesegment->StartPI();821else if(splinesegment3)822t2 = splinesegment3->TangentPoint() - splinesegment3->StartPI();823824t1.Normalize();825t2.Normalize();826827double d1 = v2d*t1;828double d2 = v2d*t2;829830Vec<2> n;831832if(d1 > d2)833{834n(0) = t1(1);835n(1) = -t1(0);836}837else838{839n(0) = -t2(1);840n(1) = t2(0);841}842843double d = v2d*n;844845if(d > eps)846return IS_OUTSIDE;847else if (d < -eps)848return IS_INSIDE;849else850return DOES_INTERSECT;851852853}854else855{856cerr << "Jo gibt's denn des?" << endl;857}858859return DOES_INTERSECT;860}861862INSOLID_TYPE Revolution :: VecInSolid2 (const Point<3> & p,863const Vec<3> & v1,864const Vec<3> & v2,865double eps) const866{867INSOLID_TYPE ret1 = VecInSolid(p,v1,eps);868if(ret1 != DOES_INTERSECT)869return ret1;870871return VecInSolid(p,v2,eps);872}873874int Revolution :: GetNSurfaces() const875{876return faces.Size();877}878879Surface & Revolution :: GetSurface (int i)880{881return *faces[i];882}883884const Surface & Revolution :: GetSurface (int i) const885{886return *faces[i];887}888889890void Revolution :: Reduce (const BoxSphere<3> & box)891{892//bool dummy;893for(int i=0; i<faces.Size(); i++)894surfaceactive[i] = (faces[i]->BoxIntersectsFace(box));895//surfaceactive[i] = (faces[i]->BoxIntersectsFace(box,dummy));896}897898void Revolution :: UnReduce ()899{900for(int i=0; i<faces.Size(); i++)901surfaceactive[i] = true;902}903}904905906