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