// File: IntPatch_PolyArc.cxx // Created: Wed Jan 27 09:44:03 1993 // Author: Isabelle GRIGNON // Copyright: Matra Datavision 1993 #include #include inline void MinMax (const Standard_Real a1, const Standard_Real a2, Standard_Real& amin, Standard_Real& amax) { if (a1 < a2) { amin = a1; amax = a2; } else { amin = a2; amax = a1; } } IntPatch_PolyArc::IntPatch_PolyArc(const Handle(Adaptor2d_HCurve2d)& Line , const Standard_Integer NbSample, const Standard_Real aPdeb, const Standard_Real aPfin, const Bnd_Box2d& BoxOtherPolygon): brise(1,Max(1,NbSample)), param(1,Max(1,NbSample)), offsetx(0.0), offsety(0.0) { Standard_Real Pdeb = aPdeb; Standard_Real Pfin = aPfin; gp_Pnt2d p2d; if (Pdeb == RealFirst() || Pfin == RealLast() || NbSample <= 1) { Standard_ConstructionError::Raise(); } //---------------------------------------------------------------------- //-- On veut eviter les cas ou le present polygone est beaucoup plus //-- grand que l objet en second. //-- //-- Par exemple lorsque l objet en second est une ligne de cheminement //-- qui contient de nombreux segments (>>100), une fleche nulle //-- et ce polygone quelques segments et une fleche qui contient //-- toute la ligne de cheminement. //-- //-- Dans ce cas (tout un polygone compris dans la zone d influence) //-- les calculs deviennent tres longs (N2) //---------------------------------------------------------------------- Standard_Integer IndexInf = NbSample+1; Standard_Integer IndexSup = 0; Standard_Real bx0,by0,bxmin,bxmax,bymin,bymax,r,r2; BoxOtherPolygon.Get(bxmin,bymin,bxmax,bymax); r=(bxmax-bxmin)+(bymax-bymin); bx0=(bxmax+bxmin)*0.5; by0=(bymax+bymin)*0.5; Standard_Real Pas; Standard_Real X,Y,Xs,Ys,Xm,Ym,XXs,YYs; r*=0.8; r2 = r*r*49.; Standard_Integer nbloop=0; do { nbloop++; Pas = (Pfin-Pdeb)/(NbSample-1); param(1) = Pdeb; Line->D0(Pdeb,p2d); Xs = p2d.X(); Ys = p2d.Y(); brise(1).SetCoord(Xs,Ys); boite.SetVoid(); boite.Add(brise(1)); fleche =0.; for (Standard_Integer i =2; i<=NbSample;i++) { param(i) = Pdeb + (i-1)*Pas; Line->D0(param(i),p2d); X = p2d.X(); Y = p2d.Y(); brise(i).SetCoord(X,Y); XXs = 0.5*(Xs+X); YYs = 0.5*(Ys+Y); //------------------------------------------------------------ //-- On recherche le debut et la fin de la zone significative //------------------------------------------------------------ // MSV: (see cda 002 H2) if segment is too large (>>r) we have // a risk to jump through BoxOtherPolygon, therefore we should // check this condition if the first one is failure. Standard_Boolean isMidPtInBox = (Abs(bx0-XXs) + Abs(by0-YYs)) < r; Standard_Boolean isSegOut = Standard_True; if(!isMidPtInBox) { Standard_Real d = (X-Xs)*(X-Xs)+(Y-Ys)*(Y-Ys); if (d > r2) { Standard_Real xmin,xmax,ymin,ymax; MinMax (Xs,X, xmin,xmax); MinMax (Ys,Y, ymin,ymax); isSegOut = (xmax < bxmin || xmin > bxmax || ymax < bymin || ymin > bymax); } } if(isMidPtInBox || !isSegOut) { // MSV: take the previous and the next segments too, because of // we check only the middle point (see BUC60946) //if(IndexInf>i) IndexInf=i-1; //if(IndexSupi) IndexInf=Max(i-2,1); if(IndexSupD0(param(i)-Pas*0.5,p2d); Xm = p2d.X() - XXs; Ym = p2d.Y() - YYs; Xm = Sqrt(Xm*Xm+Ym*Ym); fleche =Max (fleche , Xm); Xs = X; Ys = Y; } if(IndexInf > IndexSup) { r+=r; r2 = r*r*49.; //-- cout<<" Le rayon : "<1) IndexInf--; //if(IndexSup IndexSup) && nbloop<=10); fleche*=1.2; if(fleche<0.00000001) fleche = 0.00000001; boite.Enlarge(fleche); if(Line->Value(aPdeb).Distance(Line->Value(aPfin))<=1e-7) { ferme=Standard_True; } else { ferme=Standard_False; } } const Bnd_Box2d& IntPatch_PolyArc::Bounding() const { return(boite); } Standard_Real IntPatch_PolyArc::Error() const {return fleche;} Standard_Boolean IntPatch_PolyArc::Closed() const { return ferme;} Standard_Integer IntPatch_PolyArc::NbPoints() const {return brise.Length();} gp_Pnt2d IntPatch_PolyArc::Point(const Standard_Integer Index ) const { if(offsetx == 0.0 && offsety==0.0) return(brise(Index)); const gp_Pnt2d& P = brise(Index); return (gp_Pnt2d(P.X()+offsetx,P.Y()+offsety)); } Standard_Real IntPatch_PolyArc::Parameter(const Standard_Integer Index ) const { return param(Index);} void IntPatch_PolyArc::SetOffset(const Standard_Real ox,const Standard_Real oy) { Standard_Real xmin,ymin,xmax,ymax,g; boite.Get(xmin,ymin,xmax,ymax); g = boite.GetGap(); boite.SetVoid(); boite.Update(xmin-offsetx,ymin-offsety, xmax-offsetx,ymax-offsety); offsetx = ox; offsety = oy; boite.Update(xmin+offsetx,ymin+offsety, xmax+offsetx,ymax+offsety); boite.SetGap(g); }