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