1 // Created on: 1993-01-27
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Adaptor2d_HCurve2d.hxx>
19 #include <Bnd_Box2d.hxx>
20 #include <gp_Pnt2d.hxx>
21 #include <IntPatch_PolyArc.hxx>
22 #include <Standard_ConstructionError.hxx>
24 inline void MinMax (const Standard_Real a1, const Standard_Real a2,
25 Standard_Real& amin, Standard_Real& amax)
35 IntPatch_PolyArc::IntPatch_PolyArc(const Handle(Adaptor2d_HCurve2d)& Line ,
36 const Standard_Integer NbSample,
37 const Standard_Real aPdeb,
38 const Standard_Real aPfin,
39 const Bnd_Box2d& BoxOtherPolygon):
40 brise(1,Max(1,NbSample)),
41 param(1,Max(1,NbSample)),
45 Standard_Real Pdeb = aPdeb;
46 Standard_Real Pfin = aPfin;
49 if (Pdeb == RealFirst() || Pfin == RealLast() || NbSample <= 1) {
50 Standard_ConstructionError::Raise();
52 //----------------------------------------------------------------------
53 //-- On veut eviter les cas ou le present polygone est beaucoup plus
54 //-- grand que l objet en second.
56 //-- Par exemple lorsque l objet en second est une ligne de cheminement
57 //-- qui contient de nombreux segments (>>100), une fleche nulle
58 //-- et ce polygone quelques segments et une fleche qui contient
59 //-- toute la ligne de cheminement.
61 //-- Dans ce cas (tout un polygone compris dans la zone d influence)
62 //-- les calculs deviennent tres longs (N2)
63 //----------------------------------------------------------------------
64 Standard_Integer IndexInf = NbSample+1;
65 Standard_Integer IndexSup = 0;
67 Standard_Real bx0,by0,bxmin,bxmax,bymin,bymax,r,r2;
69 BoxOtherPolygon.Get(bxmin,bymin,bxmax,bymax);
70 r=(bxmax-bxmin)+(bymax-bymin);
71 bx0=(bxmax+bxmin)*0.5;
72 by0=(bymax+bymin)*0.5;
75 Standard_Real X,Y,Xs,Ys,Xm,Ym,XXs,YYs;
79 Standard_Integer nbloop=0;
83 Pas = (Pfin-Pdeb)/(NbSample-1);
86 Xs = p2d.X(); Ys = p2d.Y();
87 brise(1).SetCoord(Xs,Ys);
94 for (Standard_Integer i =2; i<=NbSample;i++) {
95 param(i) = Pdeb + (i-1)*Pas;
96 Line->D0(param(i),p2d);
97 X = p2d.X(); Y = p2d.Y();
98 brise(i).SetCoord(X,Y);
101 //------------------------------------------------------------
102 //-- On recherche le debut et la fin de la zone significative
103 //------------------------------------------------------------
104 // MSV: (see cda 002 H2) if segment is too large (>>r) we have
105 // a risk to jump through BoxOtherPolygon, therefore we should
106 // check this condition if the first one is failure.
107 Standard_Boolean isMidPtInBox = (Abs(bx0-XXs) + Abs(by0-YYs)) < r;
108 Standard_Boolean isSegOut = Standard_True;
110 Standard_Real d = (X-Xs)*(X-Xs)+(Y-Ys)*(Y-Ys);
112 Standard_Real xmin,xmax,ymin,ymax;
113 MinMax (Xs,X, xmin,xmax);
114 MinMax (Ys,Y, ymin,ymax);
115 isSegOut = (xmax < bxmin || xmin > bxmax ||
116 ymax < bymin || ymin > bymax);
119 if(isMidPtInBox || !isSegOut) {
120 // MSV: take the previous and the next segments too, because of
121 // we check only the middle point (see BUC60946)
122 //if(IndexInf>i) IndexInf=i-1;
123 //if(IndexSup<i) IndexSup=i;
124 if(IndexInf>i) IndexInf=Max(i-2,1);
125 if(IndexSup<i) IndexSup=Min(i+1,NbSample);
129 Line->D0(param(i)-Pas*0.5,p2d);
132 Xm = Sqrt(Xm*Xm+Ym*Ym);
133 myError =Max (myError , Xm);
137 if(IndexInf > IndexSup) {
140 //-- cout<<" Le rayon : "<<r<<" est insuffisant "<<endl;
143 //----------------------------------------------
144 //-- Si le nombre de points significatifs est
145 //-- insuffisant, on reechantillonne une fois
147 //----------------------------------------------
148 if((IndexSup-IndexInf)<(NbSample/2)) {
149 //-- cout<<" --- On remet ca entre les index "<<IndexInf<<" et "<<IndexSup<<endl;
151 //if(IndexInf>1) IndexInf--;
152 //if(IndexSup<NbSample) IndexSup++;
153 Pdeb = param(IndexInf);
154 Pfin = param(IndexSup);
155 //IndexInf = IndexSup+1;
156 IndexInf = NbSample+1;
161 while((IndexInf > IndexSup) && nbloop<=10);
163 if(myError<0.00000001)
164 myError = 0.00000001;
165 myBox.Enlarge(myError);
167 ferme = (Line->Value(aPdeb).Distance(Line->Value(aPfin)) <= 1e-7);
170 Standard_Boolean IntPatch_PolyArc::Closed() const { return ferme;}
172 Standard_Integer IntPatch_PolyArc::NbPoints() const {return brise.Length();}
174 gp_Pnt2d IntPatch_PolyArc::Point(const Standard_Integer Index ) const
176 if(offsetx == 0.0 && offsety==0.0)
177 return(brise(Index));
179 const gp_Pnt2d& P = brise(Index);
180 return (gp_Pnt2d(P.X()+offsetx,P.Y()+offsety));
183 Standard_Real IntPatch_PolyArc::Parameter(const Standard_Integer Index ) const
184 { return param(Index);}
187 void IntPatch_PolyArc::SetOffset(const Standard_Real ox,const Standard_Real oy) {
188 Standard_Real xmin,ymin,xmax,ymax,g;
189 myBox.Get(xmin,ymin,xmax,ymax);
194 myBox.Update(xmin-offsetx,ymin-offsety,
195 xmax-offsetx,ymax-offsety);
198 myBox.Update(xmin+offsetx,ymin+offsety,
199 xmax+offsetx,ymax+offsety);