0032969: Coding - get rid of unused headers [IMeshData to PLib]
[occt.git] / src / IntPatch / IntPatch_PolyLine.cxx
1 // Created on: 1993-01-29
2 // Created by: Isabelle GRIGNON
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //-- lbr le 12 juin : Ajout des fleches sur les Lines
18 //-- msv 13.03.2002 : compute deflection for WLine; Error() returns deflection
19
20 #include <IntPatch_PolyLine.hxx>
21 #include <IntPatch_RLine.hxx>
22 #include <IntPatch_WLine.hxx>
23 #include <Precision.hxx>
24
25 #define INITDEFLE Precision::PConfusion()*100.
26
27 //=======================================================================
28 //function : IntPatch_PolyLine
29 //purpose  : 
30 //=======================================================================
31
32 IntPatch_PolyLine::IntPatch_PolyLine ()
33      : IntPatch_Polygo(INITDEFLE),
34        onfirst(Standard_False)
35 {
36 }
37
38 //=======================================================================
39 //function : IntPatch_PolyLine
40 //purpose  : 
41 //=======================================================================
42
43 IntPatch_PolyLine::IntPatch_PolyLine (const Standard_Real InitDefle)
44      : IntPatch_Polygo(InitDefle),
45        onfirst(Standard_False)       
46 {
47 }
48
49 //=======================================================================
50 //function : SetWLine
51 //purpose  : 
52 //=======================================================================
53
54 void IntPatch_PolyLine::SetWLine(const Standard_Boolean OnFirst, const Handle(IntPatch_WLine)& Line)
55 {
56   typ = IntPatch_Walking;
57   wpoly = Line;
58   onfirst = OnFirst;
59   Prepare();
60 }
61
62 //=======================================================================
63 //function : SetRLine
64 //purpose  : 
65 //=======================================================================
66
67 void IntPatch_PolyLine::SetRLine(const Standard_Boolean OnFirst, const Handle(IntPatch_RLine)& Line)
68 {
69   typ = IntPatch_Restriction;
70   rpoly = Line;
71   onfirst = OnFirst;
72   Prepare();
73 }
74
75 //=======================================================================
76 //function : Prepare
77 //purpose  : 
78 //=======================================================================
79
80 void IntPatch_PolyLine::Prepare()
81 {
82   Standard_Integer i;
83   myBox.SetVoid();
84   Standard_Integer n=NbPoints();
85   const Standard_Real eps_2 = myError * myError;
86
87   gp_Pnt2d P1, P2;
88   if (n >= 3) {
89     P1 = Point(1); P2 = Point(2);
90   }
91   for (i=1; i<=n ;i++) {
92     const gp_Pnt2d& P3 = Point(i);
93     if (i >= 3) {
94       gp_XY V13 = P3.XY() - P1.XY();
95       gp_XY V12 = P2.XY() - P1.XY();
96       Standard_Real d13_2 = V13.SquareModulus(), d_2;
97       if (d13_2 > eps_2)
98         d_2 = V13.CrossSquareMagnitude(V12) / d13_2;
99       else
100         d_2 = eps_2;
101       if (d_2 > myError * myError) {
102         // try to compute deflection more precisely using parabola interpolation
103         gp_XY V23 = P3.XY() - P2.XY();
104         Standard_Real d12 = V12.Modulus(), d23 = V23.Modulus();
105         // compute parameter of P2 (assume parameters of P1,P3 are 0,1)
106         Standard_Real tm = d12 / (d12+d23);
107         if (tm > 0.1 && tm < 0.9) {
108           tm -= (tm-0.5) * 0.6;
109           Standard_Real tm1mtm = tm*(1-tm);
110           // coefficients of parabola
111           Standard_Real Ax = (tm*V13.X() - V12.X()) / tm1mtm;
112           Standard_Real Bx = (V12.X() - tm*tm*V13.X()) / tm1mtm;
113           Standard_Real Cx = P1.X();
114           Standard_Real Ay = (tm*V13.Y() - V12.Y()) / tm1mtm;
115           Standard_Real By = (V12.Y() - tm*tm*V13.Y()) / tm1mtm;
116           Standard_Real Cy = P1.Y();
117           // equations of lines P1-P2 and P2-P3
118           Standard_Real A1 = V12.Y() / d12;
119           Standard_Real B1 = -V12.X() / d12;
120           Standard_Real C1 = (P2.X()*P1.Y() - P1.X()*P2.Y()) / d12;
121           Standard_Real A2 = V23.Y() / d23;
122           Standard_Real B2 = -V23.X() / d23;
123           Standard_Real C2 = (P3.X()*P2.Y() - P2.X()*P3.Y()) / d23;
124           // points on parabola with max deflection
125           Standard_Real t1 = -0.5 * (A1*Bx + B1*By) / (A1*Ax + B1*Ay);
126           Standard_Real t2 = -0.5 * (A2*Bx + B2*By) / (A2*Ax + B2*Ay);
127           Standard_Real xt1 = Ax*t1*t1 + Bx*t1 + Cx;
128           Standard_Real yt1 = Ay*t1*t1 + By*t1 + Cy;
129           Standard_Real xt2 = Ax*t2*t2 + Bx*t2 + Cx;
130           Standard_Real yt2 = Ay*t2*t2 + By*t2 + Cy;
131           // max deflection on segments P1-P2 and P2-P3
132           Standard_Real d1 = Abs (A1*xt1 + B1*yt1 + C1);
133           Standard_Real d2 = Abs (A2*xt2 + B2*yt2 + C2);
134           if (d2 > d1) d1 = d2;
135           // select min deflection from linear and parabolic ones
136           if (d1 * d1 < d_2) d_2 = d1 * d1;
137         }
138         if (d_2 > myError * myError) myError=Sqrt(d_2);
139       }
140       P1 = P2; P2 = P3;
141     }
142     myBox.Add(P3);
143   }
144   myBox.Enlarge(myError);  
145 }
146
147 //=======================================================================
148 //function : ResetError
149 //purpose  : 
150 //=======================================================================
151
152 void IntPatch_PolyLine::ResetError()
153 {
154   myError = INITDEFLE;
155 }
156
157 //=======================================================================
158 //function : NbPoints
159 //purpose  : 
160 //=======================================================================
161
162 Standard_Integer IntPatch_PolyLine::NbPoints() const
163 {
164   return (typ == IntPatch_Walking ? wpoly->NbPnts() : rpoly->NbPnts());
165 }
166
167 //=======================================================================
168 //function : Point
169 //purpose  : 
170 //=======================================================================
171
172 gp_Pnt2d IntPatch_PolyLine::Point(const Standard_Integer Index )  const 
173
174   Standard_Real X,Y,X1,Y1,DX,DY;
175   DX=DY=0;
176   if (onfirst) {
177     if (typ == IntPatch_Walking) {
178       wpoly->Point(Index).ParametersOnS1(X,Y);
179       if(Index==1) { 
180         wpoly->Point(2).ParametersOnS1(X1,Y1);
181         DX=0.0000001*(X-X1);
182         DY=0.0000001*(Y-Y1);    
183       }
184       else if(Index==wpoly->NbPnts()) { 
185         wpoly->Point(Index-1).ParametersOnS1(X1,Y1);
186         DX=0.0000001*(X-X1);
187         DY=0.0000001*(Y-Y1);    
188       }
189     }
190     else {
191       rpoly->Point(Index).ParametersOnS1(X,Y);
192     }
193   }
194   else {
195     if (typ == IntPatch_Walking) {
196       wpoly->Point(Index).ParametersOnS2(X,Y);
197       if(Index==1) { 
198         wpoly->Point(2).ParametersOnS2(X1,Y1);
199         DX=0.0000001*(X-X1);
200         DY=0.0000001*(Y-Y1);    
201       }
202       else if(Index==wpoly->NbPnts()) { 
203         wpoly->Point(Index-1).ParametersOnS2(X1,Y1);
204         DX=0.0000001*(X-X1);
205         DY=0.0000001*(Y-Y1);    
206       }
207     }
208     else {
209       rpoly->Point(Index).ParametersOnS2(X,Y);
210     }
211   }
212
213   return(gp_Pnt2d(X+DX,Y+DY));
214 }