// Created on: 1993-01-27 // Created by: Isabelle GRIGNON // Copyright (c) 1993-1999 Matra Datavision // Copyright (c) 1999-2012 OPEN CASCADE SAS // // The content of this file is subject to the Open CASCADE Technology Public // License Version 6.5 (the "License"). You may not use the content of this file // except in compliance with the License. Please obtain a copy of the License // at http://www.opencascade.org and read it completely before using this file. // // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. // // The Original Code and all software distributed under the License is // distributed on an "AS IS" basis, without warranty of any kind, and the // Initial Developer hereby disclaims all such warranties, including without // limitation, any warranties of merchantability, fitness for a particular // purpose or non-infringement. Please see the License for the specific terms // and conditions governing the rights and limitations under the License. #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); myBox.SetVoid(); myBox.Add(brise(1)); myError =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); myError =Max (myError , Xm); Xs = X; Ys = Y; } if(IndexInf > IndexSup) { r+=r; r2 = r*r*49.; //-- cout<<" Le rayon : "<1) IndexInf--; //if(IndexSup IndexSup) && nbloop<=10); myError*=1.2; if(myError<0.00000001) myError = 0.00000001; myBox.Enlarge(myError); ferme = (Line->Value(aPdeb).Distance(Line->Value(aPfin)) <= 1e-7); } 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; myBox.Get(xmin,ymin,xmax,ymax); g = myBox.GetGap(); myBox.SetVoid(); myBox.Update(xmin-offsetx,ymin-offsety, xmax-offsetx,ymax-offsety); offsetx = ox; offsety = oy; myBox.Update(xmin+offsetx,ymin+offsety, xmax+offsetx,ymax+offsety); myBox.SetGap(g); }