b311480e |
1 | // Created on: 1993-01-29 |
2 | // Created by: Isabelle GRIGNON |
3 | // Copyright (c) 1993-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | //-- lbr le 12 juin : Ajout des fleches sur les Lines |
23 | //-- msv 13.03.2002 : compute deflection for WLine; Error() returns deflection |
24 | |
25 | #include <IntPatch_PolyLine.ixx> |
26 | |
27 | #include <Precision.hxx> |
28 | |
29 | #define INITDEFLE Precision::PConfusion()*100. |
30 | |
31 | //======================================================================= |
32 | //function : IntPatch_PolyLine |
33 | //purpose : |
34 | //======================================================================= |
35 | |
36 | IntPatch_PolyLine::IntPatch_PolyLine () |
9530af27 |
37 | : IntPatch_Polygo(INITDEFLE) |
7fd59977 |
38 | {} |
39 | |
40 | //======================================================================= |
41 | //function : IntPatch_PolyLine |
42 | //purpose : |
43 | //======================================================================= |
44 | |
45 | IntPatch_PolyLine::IntPatch_PolyLine (const Standard_Real InitDefle) |
9530af27 |
46 | : IntPatch_Polygo(InitDefle) |
7fd59977 |
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; |
9530af27 |
83 | myBox.SetVoid(); |
7fd59977 |
84 | Standard_Integer n=NbPoints(); |
9530af27 |
85 | Standard_Real eps = myError; |
7fd59977 |
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 = V13.Modulus(), d; |
97 | if (d13 > eps) |
98 | d = V13.CrossMagnitude(V12) / d13; |
99 | else |
100 | d = eps; |
9530af27 |
101 | if (d > myError) { |
7fd59977 |
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 < d) d = d1; |
137 | } |
9530af27 |
138 | if (d > myError) myError=d; |
7fd59977 |
139 | } |
140 | P1 = P2; P2 = P3; |
141 | } |
9530af27 |
142 | myBox.Add(P3); |
7fd59977 |
143 | } |
9530af27 |
144 | myBox.Enlarge(myError); |
7fd59977 |
145 | } |
146 | |
147 | //======================================================================= |
148 | //function : ResetError |
149 | //purpose : |
150 | //======================================================================= |
151 | |
152 | void IntPatch_PolyLine::ResetError() |
153 | { |
9530af27 |
154 | myError = INITDEFLE; |
7fd59977 |
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 | } |