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