Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1994-03-10 |
2 | // Created by: Yves FRICAUD | |
3 | // Copyright (c) 1994-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 | |
42cf5bc1 | 17 | |
7fd59977 | 18 | #include <Bisector.hxx> |
42cf5bc1 | 19 | #include <Bisector_BisecPC.hxx> |
20 | #include <ElCLib.hxx> | |
21 | #include <GccEnt_Position.hxx> | |
22 | #include <Geom2d_CartesianPoint.hxx> | |
7fd59977 | 23 | #include <Geom2d_Curve.hxx> |
42cf5bc1 | 24 | #include <Geom2d_Geometry.hxx> |
7fd59977 | 25 | #include <Geom2d_Line.hxx> |
42cf5bc1 | 26 | #include <Geom2d_TrimmedCurve.hxx> |
27 | #include <Geom2dAdaptor_Curve.hxx> | |
28 | #include <Geom2dAPI_ProjectPointOnCurve.hxx> | |
7fd59977 | 29 | #include <Geom2dGcc.hxx> |
7fd59977 | 30 | #include <Geom2dGcc_Circ2d2TanRad.hxx> |
31 | #include <Geom2dGcc_QualifiedCurve.hxx> | |
42cf5bc1 | 32 | #include <Geom2dInt_GInter.hxx> |
7fd59977 | 33 | #include <Geom2dLProp_CLProps2d.hxx> |
42cf5bc1 | 34 | #include <gp.hxx> |
35 | #include <gp_Ax2d.hxx> | |
7fd59977 | 36 | #include <gp_Pnt2d.hxx> |
42cf5bc1 | 37 | #include <gp_Trsf2d.hxx> |
7fd59977 | 38 | #include <gp_Vec2d.hxx> |
7fd59977 | 39 | #include <IntRes2d_IntersectionPoint.hxx> |
42cf5bc1 | 40 | #include <Precision.hxx> |
7fd59977 | 41 | #include <Standard_DivideByZero.hxx> |
42cf5bc1 | 42 | #include <Standard_DomainError.hxx> |
7fd59977 | 43 | #include <Standard_NotImplemented.hxx> |
42cf5bc1 | 44 | #include <Standard_RangeError.hxx> |
45 | #include <Standard_Type.hxx> | |
7fd59977 | 46 | |
47 | //============================================================================= | |
48 | //function : | |
49 | // purpose : | |
50 | //============================================================================= | |
51 | Bisector_BisecPC::Bisector_BisecPC() | |
52 | { | |
53 | } | |
54 | ||
55 | //============================================================================= | |
56 | //function : | |
57 | // purpose : | |
58 | //============================================================================= | |
59 | Bisector_BisecPC::Bisector_BisecPC(const Handle(Geom2d_Curve)& Cu, | |
60 | const gp_Pnt2d& P, | |
61 | const Standard_Real Side, | |
62 | const Standard_Real DistMax) | |
63 | { | |
64 | Perform (Cu,P,Side,DistMax); | |
65 | } | |
66 | ||
67 | //============================================================================= | |
68 | //function : | |
69 | // purpose : | |
70 | //============================================================================= | |
71 | Bisector_BisecPC::Bisector_BisecPC(const Handle(Geom2d_Curve)& Cu, | |
72 | const gp_Pnt2d& P, | |
73 | const Standard_Real Side, | |
74 | const Standard_Real UMin, | |
75 | const Standard_Real UMax) | |
76 | ||
77 | { | |
78 | curve = Handle (Geom2d_Curve)::DownCast(Cu->Copy()); | |
79 | point = P; | |
80 | sign = Side; | |
81 | startIntervals.Append(UMin); | |
82 | endIntervals .Append(UMax); | |
83 | bisInterval = 1; | |
84 | extensionStart = Standard_False; | |
85 | extensionEnd = Standard_False; | |
86 | pointStartBis = Value(UMin); | |
87 | pointEndBis = Value(UMax); | |
88 | isConvex = Bisector::IsConvex(curve,sign); | |
89 | } | |
90 | ||
91 | //============================================================================= | |
92 | //function : Perform | |
93 | // purpose : | |
94 | //============================================================================= | |
95 | void Bisector_BisecPC::Perform(const Handle(Geom2d_Curve)& Cu, | |
96 | const gp_Pnt2d& P, | |
97 | const Standard_Real Side, | |
98 | const Standard_Real DistMax) | |
99 | { | |
100 | curve = Handle (Geom2d_Curve)::DownCast(Cu->Copy()); | |
101 | point = P; | |
102 | distMax = DistMax; | |
103 | sign = Side; | |
104 | isConvex = Bisector::IsConvex(curve,sign); | |
105 | //-------------------------------------------- | |
0d969553 | 106 | // Calculate interval of definition. |
7fd59977 | 107 | //-------------------------------------------- |
108 | ComputeIntervals(); | |
109 | if (isEmpty) return; | |
110 | ||
111 | //------------------------- | |
112 | // Construction extensions. | |
113 | //------------------------- | |
114 | bisInterval = 1; | |
115 | extensionStart = Standard_False; | |
116 | extensionEnd = Standard_False; | |
117 | pointStartBis = Value(startIntervals.First()); | |
118 | pointEndBis = Value(endIntervals .Last()); | |
119 | ||
120 | if (!isConvex) { | |
121 | if (point.IsEqual(curve->Value(curve->FirstParameter()), | |
122 | Precision::Confusion()) ) { | |
123 | extensionStart = Standard_True; | |
124 | Standard_Real UFirst = startIntervals.First() - P.Distance(pointStartBis); | |
125 | startIntervals.InsertBefore(1,UFirst); | |
126 | endIntervals .InsertBefore(1,startIntervals.Value(2)); | |
127 | bisInterval = 2; | |
128 | } | |
129 | else if (point.IsEqual(curve->Value(curve->LastParameter()), | |
130 | Precision::Confusion()) ) { | |
131 | extensionEnd = Standard_True; | |
132 | Standard_Real ULast = endIntervals.Last() + P.Distance(pointEndBis); | |
133 | startIntervals.Append(endIntervals.Last()); | |
134 | endIntervals .Append(ULast); | |
135 | bisInterval = 1; | |
136 | } | |
137 | } | |
138 | } | |
139 | ||
140 | //============================================================================= | |
141 | //function : IsExtendAtStart | |
142 | //purpose : | |
143 | //============================================================================= | |
144 | Standard_Boolean Bisector_BisecPC::IsExtendAtStart() const | |
145 | { | |
146 | return extensionStart; | |
147 | } | |
148 | ||
149 | //============================================================================= | |
150 | //function : IsExtendAtEnd | |
151 | //purpose : | |
152 | //============================================================================= | |
153 | Standard_Boolean Bisector_BisecPC::IsExtendAtEnd() const | |
154 | { | |
155 | return extensionEnd; | |
156 | } | |
157 | ||
158 | //============================================================================= | |
159 | //function : Reverse | |
160 | //purpose : | |
161 | //============================================================================= | |
162 | void Bisector_BisecPC::Reverse() | |
163 | { | |
164 | Standard_NotImplemented::Raise(); | |
165 | } | |
166 | ||
167 | //============================================================================= | |
168 | //function : ReversedParameter | |
169 | //purpose : | |
170 | //============================================================================= | |
171 | Standard_Real Bisector_BisecPC::ReversedParameter(const Standard_Real U) const | |
172 | { | |
173 | return LastParameter() + FirstParameter() - U; | |
174 | } | |
175 | ||
176 | //============================================================================= | |
177 | //function : Copy | |
178 | //purpose : | |
179 | //============================================================================= | |
180 | Handle(Geom2d_Geometry) Bisector_BisecPC::Copy() const | |
181 | { | |
182 | Handle(Geom2d_Curve) CopyC = Handle(Geom2d_Curve)::DownCast(curve->Copy()); | |
183 | Handle(Bisector_BisecPC) C = new Bisector_BisecPC(); | |
184 | ||
185 | C->Init (CopyC,point,sign, | |
186 | startIntervals,endIntervals,bisInterval,currentInterval, | |
187 | shiftParameter,distMax,isEmpty,isConvex,extensionStart,extensionEnd, | |
188 | pointStartBis,pointEndBis); | |
189 | return C; | |
190 | } | |
191 | ||
192 | //============================================================================= | |
193 | //function : Transform | |
194 | //purpose : | |
195 | //============================================================================= | |
196 | void Bisector_BisecPC::Transform(const gp_Trsf2d& T) | |
197 | { | |
198 | curve ->Transform(T); | |
199 | point . Transform(T); | |
200 | pointStartBis. Transform(T); | |
201 | pointEndBis . Transform(T); | |
202 | } | |
203 | ||
204 | //============================================================================= | |
205 | //function : IsCN | |
206 | //purpose : | |
207 | //============================================================================= | |
208 | Standard_Boolean Bisector_BisecPC::IsCN(const Standard_Integer N) const | |
209 | { | |
210 | return curve->IsCN(N+1); | |
211 | } | |
212 | ||
213 | //============================================================================= | |
214 | //function : FirstParameter | |
215 | //purpose : | |
216 | //============================================================================= | |
217 | Standard_Real Bisector_BisecPC::FirstParameter() const | |
218 | { | |
219 | return startIntervals.First(); | |
220 | } | |
221 | ||
222 | //============================================================================= | |
223 | //function : LastParameter | |
224 | //purpose : | |
225 | //============================================================================= | |
226 | Standard_Real Bisector_BisecPC::LastParameter() const | |
227 | { | |
228 | return endIntervals.Last(); | |
229 | } | |
230 | ||
231 | //============================================================================= | |
232 | //function : Continuity | |
233 | //purpose : | |
234 | //============================================================================= | |
235 | GeomAbs_Shape Bisector_BisecPC::Continuity() const | |
236 | { | |
237 | GeomAbs_Shape Cont = curve->Continuity(); | |
238 | switch (Cont) { | |
239 | case GeomAbs_C1 : return GeomAbs_C0; | |
240 | case GeomAbs_C2 : return GeomAbs_C1; | |
241 | case GeomAbs_C3 : return GeomAbs_C2; | |
242 | case GeomAbs_CN : return GeomAbs_CN; | |
7fd59977 | 243 | default: break; |
7fd59977 | 244 | } |
245 | return GeomAbs_C0; | |
246 | } | |
247 | ||
248 | //============================================================================= | |
249 | //function : NbIntervals | |
250 | //purpose : | |
251 | //============================================================================= | |
252 | Standard_Integer Bisector_BisecPC::NbIntervals() const | |
253 | { | |
254 | return startIntervals.Length(); | |
255 | } | |
256 | ||
257 | //============================================================================= | |
258 | //function : IntervalFirst | |
259 | //purpose : | |
260 | //============================================================================= | |
261 | Standard_Real Bisector_BisecPC::IntervalFirst(const Standard_Integer I) const | |
262 | { | |
263 | return startIntervals.Value(I); | |
264 | } | |
265 | ||
266 | //============================================================================= | |
267 | //function : IntervalLast | |
268 | //purpose : | |
269 | //============================================================================= | |
270 | Standard_Real Bisector_BisecPC::IntervalLast(const Standard_Integer I) const | |
271 | { | |
272 | return endIntervals.Value(I); | |
273 | } | |
274 | ||
275 | //============================================================================= | |
276 | //function : IntervalContinuity | |
277 | //purpose : | |
278 | //============================================================================= | |
279 | GeomAbs_Shape Bisector_BisecPC::IntervalContinuity() const | |
280 | { | |
281 | GeomAbs_Shape Cont = curve->Continuity(); | |
282 | switch (Cont) { | |
283 | case GeomAbs_C1 : return GeomAbs_C0; | |
284 | case GeomAbs_C2 : return GeomAbs_C1; | |
285 | case GeomAbs_C3 : return GeomAbs_C2; | |
286 | case GeomAbs_CN : return GeomAbs_CN; | |
7fd59977 | 287 | default: break; |
7fd59977 | 288 | } |
289 | return GeomAbs_C0; | |
290 | } | |
291 | ||
292 | //============================================================================= | |
293 | //function : IsClosed | |
294 | //purpose : | |
295 | //============================================================================= | |
296 | Standard_Boolean Bisector_BisecPC::IsClosed() const | |
297 | { | |
298 | if (curve->IsClosed()) { | |
299 | //----------------------------------------------------------------------- | |
0d969553 Y |
300 | // The bisectrice is closed if the curve is closed and the bissectrice |
301 | // has only one domain of continuity equal to the one of the curve. | |
7fd59977 | 302 | // ----------------------------------------------------------------------- |
303 | if (startIntervals.First() == curve->FirstParameter() && | |
304 | endIntervals .First() == curve->LastParameter () ) | |
305 | return Standard_True; | |
306 | } | |
307 | return Standard_False; | |
308 | } | |
309 | ||
310 | //============================================================================= | |
311 | //function : IsPeriodic | |
312 | //purpose : | |
313 | //============================================================================= | |
314 | Standard_Boolean Bisector_BisecPC::IsPeriodic() const | |
315 | { | |
316 | return Standard_False; | |
317 | } | |
318 | ||
319 | //============================================================================= | |
320 | //function : Extension | |
321 | // purpose : | |
322 | //============================================================================= | |
323 | void Bisector_BisecPC::Extension(const Standard_Real U, | |
324 | gp_Pnt2d& P, | |
325 | gp_Vec2d& V1, | |
326 | gp_Vec2d& V2, | |
327 | gp_Vec2d& V3 ) const | |
328 | { | |
329 | gp_Dir2d DirExt; | |
330 | Standard_Real dU; | |
331 | ||
332 | if ( U < startIntervals.Value(bisInterval)) { | |
333 | dU = U - startIntervals.Value(bisInterval); | |
334 | DirExt.SetCoord(pointStartBis.X() - point.X(), | |
335 | pointStartBis.Y() - point.Y()); | |
336 | P.SetCoord(pointStartBis.X() + dU*DirExt.X(), | |
337 | pointStartBis.Y() + dU*DirExt.Y()); | |
338 | } | |
339 | else if ( U > endIntervals.Value(bisInterval)) { | |
340 | dU = U - endIntervals.Value(bisInterval); | |
341 | DirExt.SetCoord(point.X() - pointEndBis.X(), | |
342 | point.Y() - pointEndBis.Y()); | |
343 | P.SetCoord(pointEndBis.X() + dU*DirExt.X(), | |
344 | pointEndBis.Y() + dU*DirExt.Y()); | |
345 | } | |
346 | V1.SetCoord(DirExt.X(),DirExt.Y()); | |
347 | V2.SetCoord(0. ,0. ); | |
348 | V3.SetCoord(0. ,0. ); | |
349 | } | |
350 | ||
351 | ||
352 | //============================================================================= | |
353 | //function : Values | |
0d969553 Y |
354 | // purpose : To each point of the curve is associated a point on the |
355 | // bissectrice. The equation of the bissectrice is: | |
7fd59977 | 356 | // || PP(u)||**2 |
357 | // F(u) = P(u) - 1/2* -------------- * N(u) | |
358 | // (N(u)|PP(u)) | |
359 | // | |
0d969553 Y |
360 | // N(u) normal to the curve by u. |
361 | // ( | ) designation of the scalar product. | |
7fd59977 | 362 | //============================================================================= |
363 | void Bisector_BisecPC::Values(const Standard_Real U, | |
364 | const Standard_Integer N, | |
365 | gp_Pnt2d& P, | |
366 | gp_Vec2d& V1, | |
367 | gp_Vec2d& V2, | |
368 | gp_Vec2d& V3 ) const | |
369 | { | |
370 | if ( U < startIntervals.Value(bisInterval)) { | |
371 | Extension(U,P,V1,V2,V3); | |
372 | return; | |
373 | } | |
374 | else if ( U > endIntervals.Value(bisInterval)) { | |
375 | Extension(U,P,V1,V2,V3); | |
376 | return; | |
377 | } | |
378 | Standard_Real UOnCurve = LinkBisCurve(U); | |
379 | ||
380 | gp_Vec2d Tu,Tuu,T3u; | |
381 | gp_Pnt2d PC; | |
382 | ||
383 | switch (N) { | |
384 | case 0 : {curve->D1(UOnCurve,PC,Tu) ;break;} | |
385 | case 1 : {curve->D2(UOnCurve,PC,Tu,Tuu) ;break;} | |
386 | case 2 : {curve->D3(UOnCurve,PC,Tu,Tuu,T3u);break;} | |
387 | } | |
388 | ||
389 | gp_Vec2d PPC(PC.X() - point.X(), PC.Y() - point.Y()); | |
390 | gp_Vec2d Nor( - Tu.Y(), Tu.X()); | |
391 | ||
392 | Standard_Real SquarePPC = PPC.SquareMagnitude(); | |
393 | Standard_Real NorPPC = Nor.Dot(PPC); | |
394 | Standard_Real A1; | |
395 | ||
396 | if (Abs(NorPPC) > gp::Resolution() && (NorPPC*sign) < 0.) { | |
397 | A1 = 0.5*SquarePPC/NorPPC; | |
398 | P.SetCoord(PC.X() - Nor.X()*A1, PC.Y() - Nor.Y()*A1); | |
399 | } | |
400 | else {return; } | |
401 | ||
0d969553 | 402 | if (N == 0) return; // End Calculation Point; |
7fd59977 | 403 | |
0d969553 | 404 | gp_Vec2d Nu ( - Tuu.Y() , Tuu.X()); // derivative of the normal by U. |
7fd59977 | 405 | Standard_Real NuPPC = Nu .Dot(PPC); |
406 | Standard_Real TuPPC = Tu .Dot(PPC); | |
407 | Standard_Real NorPPCE2 = NorPPC*NorPPC; | |
408 | Standard_Real A2 = TuPPC/NorPPC - 0.5*NuPPC*SquarePPC/NorPPCE2; | |
409 | ||
410 | //-------------------------- | |
411 | V1 = Tu - A1*Nu - A2*Nor; | |
412 | //-------------------------- | |
0d969553 | 413 | if (N == 1) return; // End calculation D1. |
7fd59977 | 414 | |
415 | gp_Vec2d Nuu ( - T3u.Y() , T3u.X()); | |
416 | ||
417 | Standard_Real NorPPCE4 = NorPPCE2*NorPPCE2; | |
418 | Standard_Real NuuPPC = Nuu.Dot(PPC); | |
419 | Standard_Real TuuPPC = Tuu.Dot(PPC); | |
420 | ||
421 | Standard_Real A21 = TuuPPC/NorPPC - TuPPC*NuPPC/NorPPCE2; | |
422 | Standard_Real A22 = (0.5*NuuPPC*SquarePPC + NuPPC*TuPPC)/NorPPCE2 - | |
423 | NuPPC*SquarePPC*NorPPC*NuPPC/NorPPCE4; | |
424 | Standard_Real A2u = A21 - A22; | |
425 | //---------------------------------------- | |
426 | V2 = Tuu - 2*A2*Nu - A1*Nuu - A2u*Nor; | |
427 | //---------------------------------------- | |
428 | } | |
429 | ||
430 | //============================================================================= | |
431 | //function : Curvature | |
432 | //purpose : | |
433 | //============================================================================= | |
434 | // Unused : | |
0797d9d3 | 435 | #ifdef OCCT_DEBUG_CUR |
7fd59977 | 436 | static Standard_Real Curvature (const Handle(Geom2d_Curve)& C, |
437 | Standard_Real U, | |
438 | Standard_Real Tol) | |
439 | { | |
440 | Standard_Real K1; | |
441 | gp_Vec2d D1,D2; | |
442 | gp_Pnt2d P; | |
443 | C->D2(U,P,D1,D2); | |
444 | Standard_Real Norm2 = D1.SquareMagnitude();; | |
445 | if (Norm2 < Tol) { | |
446 | K1 = 0.0; | |
447 | } | |
448 | else { | |
449 | K1 = (D1^D2)/(Norm2*sqrt(Norm2)); | |
450 | } | |
451 | return K1; | |
452 | } | |
453 | #endif | |
454 | ||
455 | //============================================================================= | |
456 | //function : Distance | |
0d969553 | 457 | //purpose : distance at the square of the point of parameter U to the curve and at point: |
7fd59977 | 458 | // |
459 | // 2 ||PP(u)||**4 2 | |
460 | // d = 1/4* ------------------- ||Nor|| | |
461 | // (Nor(u)/PP(u))**2 | |
462 | // | |
0d969553 | 463 | // where Nor is the normal to the curve by U. |
7fd59977 | 464 | //============================================================================= |
465 | Standard_Real Bisector_BisecPC::Distance (const Standard_Real U) const | |
466 | { | |
467 | gp_Vec2d Tan; | |
468 | gp_Pnt2d PC; | |
469 | ||
470 | Standard_Real UOnCurve = LinkBisCurve(U); | |
471 | ||
472 | curve->D1(UOnCurve,PC,Tan); | |
473 | gp_Vec2d PPC(PC.X() - point.X(), PC.Y() - point.Y()); | |
474 | gp_Vec2d Nor( - Tan.Y(), Tan.X()); | |
475 | ||
476 | Standard_Real NorNor = Nor.SquareMagnitude(); | |
477 | Standard_Real SquareMagPPC = PPC.SquareMagnitude(); | |
478 | Standard_Real Prosca = Nor.Dot(PPC); | |
479 | ||
480 | if (point.IsEqual(PC,Precision::Confusion())) { | |
481 | if (isConvex) { return 0.;} | |
482 | //---------------------------------------------------- | |
0d969553 Y |
483 | // the point is on a concave curve. |
484 | // The required point is not the common point. | |
485 | // This can avoid the discontinuity of the bisectrice. | |
7fd59977 | 486 | //---------------------------------------------------- |
487 | else { return Precision::Infinite();} | |
488 | } | |
489 | ||
490 | if (Abs(Prosca) < Precision::Confusion() || (Prosca*sign) > 0. ) { | |
491 | return Precision::Infinite(); | |
492 | } | |
493 | else { | |
494 | Standard_Real A = 0.5*SquareMagPPC/Prosca; | |
495 | Standard_Real Dist = A*A*NorNor; | |
0797d9d3 | 496 | #ifdef OCCT_DEBUG_CUR |
7fd59977 | 497 | //---------------------------------------- |
0d969553 | 498 | // Test Curvature if the curve is concave. |
7fd59977 | 499 | //---------------------------------------- |
4e18e72a | 500 | if (!isConvex){ |
501 | Standard_Real K = Curvature(curve,UOnCurve,Precision::Confusion()); | |
502 | if (K != 0.) { | |
503 | if (Dist > 1/(K*K)) { Dist = Precision::Infinite();} | |
504 | } | |
505 | } | |
506 | #endif | |
7fd59977 | 507 | return Dist; |
508 | } | |
509 | } | |
510 | ||
511 | ||
512 | ||
513 | //============================================================================= | |
514 | //function : D0 | |
515 | // purpose : | |
516 | //============================================================================= | |
517 | void Bisector_BisecPC::D0(const Standard_Real U, | |
518 | gp_Pnt2d& P) const | |
519 | { | |
520 | P = point; | |
521 | gp_Vec2d V1,V2,V3; | |
522 | Values(U,0,P,V1,V2,V3); | |
523 | } | |
524 | ||
525 | ||
526 | //============================================================================= | |
527 | //function : D1 | |
528 | // purpose : | |
529 | //============================================================================= | |
530 | void Bisector_BisecPC::D1(const Standard_Real U, | |
531 | gp_Pnt2d& P, | |
532 | gp_Vec2d& V ) const | |
533 | { | |
534 | P = point; | |
535 | V.SetCoord(0.,0.); | |
536 | gp_Vec2d V2,V3; | |
537 | Values(U,1,P,V,V2,V3); | |
538 | } | |
539 | ||
540 | ||
541 | //============================================================================= | |
542 | //function : D2 | |
543 | // purpose : | |
544 | //============================================================================= | |
545 | void Bisector_BisecPC::D2(const Standard_Real U, | |
546 | gp_Pnt2d& P, | |
547 | gp_Vec2d& V1, | |
548 | gp_Vec2d& V2) const | |
549 | { | |
550 | P = point; | |
551 | V1.SetCoord(0.,0.); | |
552 | V2.SetCoord(0.,0.); | |
553 | gp_Vec2d V3; | |
554 | Values(U,2,P,V1,V2,V3); | |
555 | } | |
556 | ||
557 | //============================================================================= | |
558 | //function : D3 | |
559 | // purpose : | |
560 | //============================================================================= | |
561 | void Bisector_BisecPC::D3(const Standard_Real U, | |
562 | gp_Pnt2d& P, | |
563 | gp_Vec2d& V1, | |
564 | gp_Vec2d& V2, | |
565 | gp_Vec2d& V3) const | |
566 | { | |
567 | P = point; | |
568 | V1.SetCoord(0.,0.); | |
569 | V2.SetCoord(0.,0.); | |
570 | V3.SetCoord(0.,0.); | |
571 | Values(U,3,P,V1,V2,V3); | |
572 | } | |
573 | ||
574 | ||
575 | //============================================================================= | |
576 | //function : DN | |
577 | // purpose : | |
578 | //============================================================================= | |
579 | gp_Vec2d Bisector_BisecPC::DN (const Standard_Real U, | |
580 | const Standard_Integer N) const | |
581 | { | |
582 | gp_Pnt2d P = point; | |
583 | gp_Vec2d V1(0.,0.); | |
584 | gp_Vec2d V2(0.,0.); | |
585 | gp_Vec2d V3(0.,0.); | |
586 | Values (U,N,P,V1,V2,V3); | |
587 | switch (N) { | |
588 | case 1 : return V1; | |
589 | case 2 : return V2; | |
590 | case 3 : return V3; | |
591 | default: { | |
592 | Standard_NotImplemented::Raise(); | |
593 | } | |
594 | } | |
595 | return V1; | |
596 | } | |
597 | ||
598 | //============================================================================= | |
599 | //function : SearchBound | |
600 | // purpose : | |
601 | //============================================================================= | |
602 | Standard_Real Bisector_BisecPC::SearchBound (const Standard_Real U1, | |
603 | const Standard_Real U2) const | |
604 | { | |
96a95605 | 605 | Standard_Real Dist1,DistMid,U11,U22; |
7fd59977 | 606 | Standard_Real UMid = 0.; |
7fd59977 | 607 | Standard_Real Tol = Precision::PConfusion(); |
608 | Standard_Real DistMax2 = distMax*distMax; | |
609 | U11 = U1; U22 = U2; | |
610 | Dist1 = Distance(U11); | |
7fd59977 | 611 | |
612 | while ((U22 - U11) > Tol) { | |
613 | UMid = 0.5*( U22 + U11); | |
614 | DistMid = Distance(UMid); | |
615 | if ((Dist1 > DistMax2) == (DistMid > DistMax2)) { | |
616 | U11 = UMid; | |
617 | Dist1 = DistMid; | |
618 | } | |
619 | else { | |
620 | U22 = UMid; | |
7fd59977 | 621 | } |
622 | } | |
623 | return UMid; | |
624 | } | |
625 | ||
626 | //============================================================================= | |
627 | //function : CuspFilter | |
628 | // purpose : | |
629 | //============================================================================= | |
630 | void Bisector_BisecPC::CuspFilter() | |
631 | { | |
632 | Standard_NotImplemented::Raise(); | |
633 | } | |
634 | ||
635 | //============================================================================= | |
636 | //function : ComputeIntervals | |
637 | // purpose : | |
638 | //============================================================================= | |
639 | void Bisector_BisecPC::ComputeIntervals () | |
640 | { | |
7fd59977 | 641 | Standard_Real U1 =0.,U2 =0.,UProj =0.; |
b7c077b9 | 642 | Standard_Real UStart = 0., UEnd = 0.; |
7fd59977 | 643 | Standard_Real Dist1,Dist2,DistProj; |
644 | isEmpty = Standard_False; | |
645 | shiftParameter = 0.; | |
646 | Standard_Boolean YaProj = Standard_False; | |
647 | Standard_Real DistMax2 = distMax*distMax; | |
648 | ||
649 | U1 = curve->FirstParameter(); | |
650 | U2 = curve->LastParameter(); | |
651 | Dist1 = Distance(U1); | |
652 | Dist2 = Distance(U2); | |
653 | DistProj = Precision::Infinite(); | |
654 | ||
655 | Geom2dAPI_ProjectPointOnCurve Proj(point,curve,U1,U2); | |
656 | if (Proj.NbPoints() > 0) { | |
657 | UProj = Proj.LowerDistanceParameter(); | |
658 | DistProj = Distance(UProj); | |
659 | YaProj = Standard_True; | |
660 | } | |
661 | ||
662 | if (Dist1 < DistMax2 && Dist2 < DistMax2) { | |
663 | if (DistProj > DistMax2 && YaProj) { | |
664 | isEmpty = Standard_True; | |
665 | } | |
666 | else { | |
667 | startIntervals.Append(U1); | |
668 | endIntervals .Append(U2); | |
669 | } | |
670 | return; | |
671 | } | |
672 | else if (Dist1 > DistMax2 && Dist2 > DistMax2) { | |
673 | if (DistProj < DistMax2) { | |
674 | UStart = SearchBound(U1,UProj); | |
675 | UEnd = SearchBound(UProj,U2); | |
676 | } | |
677 | else { | |
678 | isEmpty = Standard_True; | |
679 | return; | |
680 | } | |
681 | } | |
682 | else if (Dist1 < DistMax2) { | |
683 | UStart = U1; | |
684 | UEnd = SearchBound(U1,U2); | |
685 | } | |
686 | else if (Dist2 < DistMax2) { | |
687 | UEnd = U2; | |
688 | UStart = SearchBound(U1,U2); | |
689 | } | |
690 | startIntervals.Append(UStart); | |
691 | endIntervals .Append(UEnd); | |
692 | ||
693 | //------------------------------------------------------------------------ | |
0d969553 Y |
694 | // Eventual offset of the parameter on the curve correspondingly to the one |
695 | // on the curve. The offset can be done if the curve is periodical and the | |
696 | // point of initial parameter is less then the interval of continuity. | |
7fd59977 | 697 | //------------------------------------------------------------------------ |
698 | if (curve->IsPeriodic()) { | |
699 | if (startIntervals.Length() > 1) { // Plusieurs intervals. | |
700 | if (endIntervals .Last() == curve->LastParameter() && | |
701 | startIntervals.First() == curve->FirstParameter() ) { | |
702 | //--------------------------------------------------------------- | |
0d969553 Y |
703 | // the bissectrice is defined at the origin. |
704 | // => Fusion of the first and the last interval. | |
705 | // => 0 on the bisectrice becomes the start of the first interval | |
706 | // => offset of parameter on all limits of intervals. | |
7fd59977 | 707 | //--------------------------------------------------------------- |
708 | startIntervals.Remove(1); | |
709 | endIntervals .Remove(endIntervals.Length()); | |
710 | ||
711 | shiftParameter = Period() - startIntervals.First() ; | |
712 | for (Standard_Integer k = 1; k <= startIntervals.Length(); k++) { | |
713 | endIntervals .ChangeValue(k) += shiftParameter; | |
714 | startIntervals.ChangeValue(k) += shiftParameter; | |
715 | } | |
716 | startIntervals.ChangeValue(1) = 0.; | |
717 | } | |
718 | } | |
719 | } | |
720 | } | |
721 | ||
722 | //============================================================================= | |
723 | //function : LinkBisCurve | |
724 | //purpose : | |
725 | //============================================================================= | |
726 | Standard_Real Bisector_BisecPC::LinkBisCurve(const Standard_Real U) const | |
727 | { | |
728 | return (U - shiftParameter); | |
729 | } | |
730 | ||
731 | //============================================================================= | |
732 | //function : LinkCurveBis | |
733 | //purpose : | |
734 | //============================================================================= | |
735 | Standard_Real Bisector_BisecPC::LinkCurveBis(const Standard_Real U) const | |
736 | { | |
737 | return (U + shiftParameter); | |
738 | } | |
739 | ||
740 | //============================================================================= | |
741 | //function : IsEmpty | |
742 | //purpose : | |
743 | //============================================================================= | |
744 | Standard_Boolean Bisector_BisecPC::IsEmpty() const | |
745 | { | |
746 | return isEmpty; | |
747 | } | |
748 | ||
749 | //========================================================================== | |
750 | //function : Parameter | |
751 | //purpose : | |
752 | //========================================================================== | |
753 | Standard_Real Bisector_BisecPC::Parameter(const gp_Pnt2d& P) const | |
754 | { | |
755 | Standard_Real Tol = Precision::Confusion(); | |
756 | ||
757 | if (P.IsEqual(pointStartBis,Tol)) {return startIntervals.Value(bisInterval);} | |
758 | if (P.IsEqual(pointEndBis ,Tol)) {return endIntervals .Value(bisInterval);} | |
759 | ||
760 | if (extensionStart) { | |
761 | gp_Ax2d Axe(pointStartBis,gp_Dir2d(pointStartBis.X() - P.X(), | |
762 | pointStartBis.Y() - P.Y())); | |
763 | Standard_Real U = ElCLib::LineParameter(Axe,P); | |
764 | gp_Pnt2d Proj = ElCLib::LineValue(U,Axe); | |
765 | if (Proj.IsEqual(P,Tol) && U < 0.) { | |
766 | return U + startIntervals.Value(bisInterval); | |
767 | } | |
768 | } | |
769 | if (extensionEnd) { | |
770 | gp_Ax2d Axe(pointEndBis,gp_Dir2d(P.X() - pointEndBis.X(), | |
771 | P.Y() - pointEndBis.Y())); | |
772 | Standard_Real U = ElCLib::LineParameter(Axe,P); | |
773 | gp_Pnt2d Proj = ElCLib::LineValue(U,Axe); | |
774 | if (Proj.IsEqual(P,Tol) && U > 0.) { | |
775 | return U + endIntervals.Value(bisInterval); | |
776 | } | |
777 | } | |
7fd59977 | 778 | Standard_Real UOnCurve = 0.; |
7fd59977 | 779 | Geom2dAPI_ProjectPointOnCurve Proj(P,curve, |
780 | curve->FirstParameter(),curve->LastParameter()); | |
781 | if (Proj.NbPoints() > 0) { | |
782 | UOnCurve = Proj.LowerDistanceParameter(); | |
783 | } | |
784 | return LinkCurveBis(UOnCurve); | |
785 | } | |
786 | ||
787 | ||
788 | //============================================================================= | |
789 | //function : Indent | |
790 | // purpose : | |
791 | //============================================================================= | |
792 | static void Indent(const Standard_Integer Offset) { | |
793 | if (Offset > 0) { | |
794 | for (Standard_Integer i = 0; i < Offset; i++) {cout << " ";} | |
795 | } | |
796 | } | |
797 | ||
798 | //============================================================================= | |
799 | //function : Init | |
800 | // purpose : | |
801 | //============================================================================= | |
857ffd5e | 802 | void Bisector_BisecPC::Init (const Handle(Geom2d_Curve)& Curve, |
7fd59977 | 803 | const gp_Pnt2d& Point, |
804 | const Standard_Real Sign, | |
805 | const TColStd_SequenceOfReal& StartIntervals, | |
806 | const TColStd_SequenceOfReal& EndIntervals, | |
807 | const Standard_Integer BisInterval, | |
808 | const Standard_Integer CurrentInterval, | |
809 | const Standard_Real ShiftParameter, | |
810 | const Standard_Real DistMax, | |
811 | const Standard_Boolean IsEmpty, | |
812 | const Standard_Boolean IsConvex, | |
813 | const Standard_Boolean ExtensionStart, | |
814 | const Standard_Boolean ExtensionEnd, | |
815 | const gp_Pnt2d& PointStartBis, | |
816 | const gp_Pnt2d& PointEndBis) | |
817 | { | |
818 | curve = Curve; | |
819 | point = Point; | |
820 | sign = Sign ; | |
821 | startIntervals = StartIntervals; | |
822 | endIntervals = EndIntervals; | |
823 | bisInterval = BisInterval; | |
824 | currentInterval = CurrentInterval; | |
825 | shiftParameter = ShiftParameter; | |
826 | distMax = DistMax; | |
827 | isEmpty = IsEmpty; | |
828 | isConvex = IsConvex; | |
829 | extensionStart = ExtensionStart; | |
830 | extensionEnd = ExtensionEnd; | |
831 | pointStartBis = PointStartBis; | |
832 | pointEndBis = PointEndBis; | |
833 | } | |
834 | ||
835 | //============================================================================= | |
836 | //function : Dump | |
837 | // purpose : | |
838 | //============================================================================= | |
839 | //void Bisector_BisecPC::Dump(const Standard_Integer Deep, | |
840 | void Bisector_BisecPC::Dump(const Standard_Integer , | |
841 | const Standard_Integer Offset) const | |
842 | { | |
843 | Indent (Offset); | |
844 | cout <<"Bisector_BisecPC :"<<endl; | |
845 | Indent (Offset); | |
846 | cout <<"Point :"<<endl; | |
847 | cout <<" X = "<<point.X()<<endl; | |
848 | cout <<" Y = "<<point.Y()<<endl; | |
849 | cout <<"Sign :"<<sign<<endl; | |
850 | cout <<"Number Of Intervals :"<<startIntervals.Length()<<endl; | |
851 | for (Standard_Integer i = 1; i <= startIntervals.Length(); i++) { | |
852 | cout <<"Interval number :"<<i<<"Start :"<<startIntervals.Value(i) | |
853 | <<" end :"<< endIntervals.Value(i)<<endl ; | |
854 | } | |
855 | cout <<"Index Current Interval :"<<currentInterval<<endl; | |
856 | } | |
857 | ||
858 | ||
859 | ||
860 | ||
861 | ||
862 |