Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 1994-03-10 |
2 | // Created by: Yves FRICAUD | |
3 | // Copyright (c) 1994-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 | #include <Bisector_BisecPC.ixx> | |
23 | #include <Bisector.hxx> | |
24 | #include <Geom2dAdaptor_Curve.hxx> | |
25 | #include <Geom2d_Curve.hxx> | |
26 | #include <Geom2d_Line.hxx> | |
27 | #include <Geom2d_CartesianPoint.hxx> | |
28 | #include <Geom2dInt_GInter.hxx> | |
29 | #include <Geom2dGcc.hxx> | |
30 | #include <GccEnt_Position.hxx> | |
31 | #include <Geom2dGcc_Circ2d2TanRad.hxx> | |
32 | #include <Geom2dGcc_QualifiedCurve.hxx> | |
33 | #include <Geom2d_TrimmedCurve.hxx> | |
34 | #include <Geom2dAPI_ProjectPointOnCurve.hxx> | |
35 | #include <Geom2dLProp_CLProps2d.hxx> | |
36 | #include <gp_Pnt2d.hxx> | |
37 | #include <gp_Vec2d.hxx> | |
38 | #include <gp_Ax2d.hxx> | |
39 | #include <gp.hxx> | |
40 | #include <Precision.hxx> | |
41 | #include <ElCLib.hxx> | |
42 | #include <IntRes2d_IntersectionPoint.hxx> | |
43 | ||
44 | #include <Standard_DivideByZero.hxx> | |
45 | #include <Standard_NotImplemented.hxx> | |
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; | |
243 | #ifndef DEB | |
244 | default: break; | |
245 | #endif | |
246 | } | |
247 | return GeomAbs_C0; | |
248 | } | |
249 | ||
250 | //============================================================================= | |
251 | //function : NbIntervals | |
252 | //purpose : | |
253 | //============================================================================= | |
254 | Standard_Integer Bisector_BisecPC::NbIntervals() const | |
255 | { | |
256 | return startIntervals.Length(); | |
257 | } | |
258 | ||
259 | //============================================================================= | |
260 | //function : IntervalFirst | |
261 | //purpose : | |
262 | //============================================================================= | |
263 | Standard_Real Bisector_BisecPC::IntervalFirst(const Standard_Integer I) const | |
264 | { | |
265 | return startIntervals.Value(I); | |
266 | } | |
267 | ||
268 | //============================================================================= | |
269 | //function : IntervalLast | |
270 | //purpose : | |
271 | //============================================================================= | |
272 | Standard_Real Bisector_BisecPC::IntervalLast(const Standard_Integer I) const | |
273 | { | |
274 | return endIntervals.Value(I); | |
275 | } | |
276 | ||
277 | //============================================================================= | |
278 | //function : IntervalContinuity | |
279 | //purpose : | |
280 | //============================================================================= | |
281 | GeomAbs_Shape Bisector_BisecPC::IntervalContinuity() const | |
282 | { | |
283 | GeomAbs_Shape Cont = curve->Continuity(); | |
284 | switch (Cont) { | |
285 | case GeomAbs_C1 : return GeomAbs_C0; | |
286 | case GeomAbs_C2 : return GeomAbs_C1; | |
287 | case GeomAbs_C3 : return GeomAbs_C2; | |
288 | case GeomAbs_CN : return GeomAbs_CN; | |
289 | #ifndef DEB | |
290 | default: break; | |
291 | #endif | |
292 | } | |
293 | return GeomAbs_C0; | |
294 | } | |
295 | ||
296 | //============================================================================= | |
297 | //function : IsClosed | |
298 | //purpose : | |
299 | //============================================================================= | |
300 | Standard_Boolean Bisector_BisecPC::IsClosed() const | |
301 | { | |
302 | if (curve->IsClosed()) { | |
303 | //----------------------------------------------------------------------- | |
0d969553 Y |
304 | // The bisectrice is closed if the curve is closed and the bissectrice |
305 | // has only one domain of continuity equal to the one of the curve. | |
7fd59977 | 306 | // ----------------------------------------------------------------------- |
307 | if (startIntervals.First() == curve->FirstParameter() && | |
308 | endIntervals .First() == curve->LastParameter () ) | |
309 | return Standard_True; | |
310 | } | |
311 | return Standard_False; | |
312 | } | |
313 | ||
314 | //============================================================================= | |
315 | //function : IsPeriodic | |
316 | //purpose : | |
317 | //============================================================================= | |
318 | Standard_Boolean Bisector_BisecPC::IsPeriodic() const | |
319 | { | |
320 | return Standard_False; | |
321 | } | |
322 | ||
323 | //============================================================================= | |
324 | //function : Extension | |
325 | // purpose : | |
326 | //============================================================================= | |
327 | void Bisector_BisecPC::Extension(const Standard_Real U, | |
328 | gp_Pnt2d& P, | |
329 | gp_Vec2d& V1, | |
330 | gp_Vec2d& V2, | |
331 | gp_Vec2d& V3 ) const | |
332 | { | |
333 | gp_Dir2d DirExt; | |
334 | Standard_Real dU; | |
335 | ||
336 | if ( U < startIntervals.Value(bisInterval)) { | |
337 | dU = U - startIntervals.Value(bisInterval); | |
338 | DirExt.SetCoord(pointStartBis.X() - point.X(), | |
339 | pointStartBis.Y() - point.Y()); | |
340 | P.SetCoord(pointStartBis.X() + dU*DirExt.X(), | |
341 | pointStartBis.Y() + dU*DirExt.Y()); | |
342 | } | |
343 | else if ( U > endIntervals.Value(bisInterval)) { | |
344 | dU = U - endIntervals.Value(bisInterval); | |
345 | DirExt.SetCoord(point.X() - pointEndBis.X(), | |
346 | point.Y() - pointEndBis.Y()); | |
347 | P.SetCoord(pointEndBis.X() + dU*DirExt.X(), | |
348 | pointEndBis.Y() + dU*DirExt.Y()); | |
349 | } | |
350 | V1.SetCoord(DirExt.X(),DirExt.Y()); | |
351 | V2.SetCoord(0. ,0. ); | |
352 | V3.SetCoord(0. ,0. ); | |
353 | } | |
354 | ||
355 | ||
356 | //============================================================================= | |
357 | //function : Values | |
0d969553 Y |
358 | // purpose : To each point of the curve is associated a point on the |
359 | // bissectrice. The equation of the bissectrice is: | |
7fd59977 | 360 | // || PP(u)||**2 |
361 | // F(u) = P(u) - 1/2* -------------- * N(u) | |
362 | // (N(u)|PP(u)) | |
363 | // | |
0d969553 Y |
364 | // N(u) normal to the curve by u. |
365 | // ( | ) designation of the scalar product. | |
7fd59977 | 366 | //============================================================================= |
367 | void Bisector_BisecPC::Values(const Standard_Real U, | |
368 | const Standard_Integer N, | |
369 | gp_Pnt2d& P, | |
370 | gp_Vec2d& V1, | |
371 | gp_Vec2d& V2, | |
372 | gp_Vec2d& V3 ) const | |
373 | { | |
374 | if ( U < startIntervals.Value(bisInterval)) { | |
375 | Extension(U,P,V1,V2,V3); | |
376 | return; | |
377 | } | |
378 | else if ( U > endIntervals.Value(bisInterval)) { | |
379 | Extension(U,P,V1,V2,V3); | |
380 | return; | |
381 | } | |
382 | Standard_Real UOnCurve = LinkBisCurve(U); | |
383 | ||
384 | gp_Vec2d Tu,Tuu,T3u; | |
385 | gp_Pnt2d PC; | |
386 | ||
387 | switch (N) { | |
388 | case 0 : {curve->D1(UOnCurve,PC,Tu) ;break;} | |
389 | case 1 : {curve->D2(UOnCurve,PC,Tu,Tuu) ;break;} | |
390 | case 2 : {curve->D3(UOnCurve,PC,Tu,Tuu,T3u);break;} | |
391 | } | |
392 | ||
393 | gp_Vec2d PPC(PC.X() - point.X(), PC.Y() - point.Y()); | |
394 | gp_Vec2d Nor( - Tu.Y(), Tu.X()); | |
395 | ||
396 | Standard_Real SquarePPC = PPC.SquareMagnitude(); | |
397 | Standard_Real NorPPC = Nor.Dot(PPC); | |
398 | Standard_Real A1; | |
399 | ||
400 | if (Abs(NorPPC) > gp::Resolution() && (NorPPC*sign) < 0.) { | |
401 | A1 = 0.5*SquarePPC/NorPPC; | |
402 | P.SetCoord(PC.X() - Nor.X()*A1, PC.Y() - Nor.Y()*A1); | |
403 | } | |
404 | else {return; } | |
405 | ||
0d969553 | 406 | if (N == 0) return; // End Calculation Point; |
7fd59977 | 407 | |
0d969553 | 408 | gp_Vec2d Nu ( - Tuu.Y() , Tuu.X()); // derivative of the normal by U. |
7fd59977 | 409 | Standard_Real NuPPC = Nu .Dot(PPC); |
410 | Standard_Real TuPPC = Tu .Dot(PPC); | |
411 | Standard_Real NorPPCE2 = NorPPC*NorPPC; | |
412 | Standard_Real A2 = TuPPC/NorPPC - 0.5*NuPPC*SquarePPC/NorPPCE2; | |
413 | ||
414 | //-------------------------- | |
415 | V1 = Tu - A1*Nu - A2*Nor; | |
416 | //-------------------------- | |
0d969553 | 417 | if (N == 1) return; // End calculation D1. |
7fd59977 | 418 | |
419 | gp_Vec2d Nuu ( - T3u.Y() , T3u.X()); | |
420 | ||
421 | Standard_Real NorPPCE4 = NorPPCE2*NorPPCE2; | |
422 | Standard_Real NuuPPC = Nuu.Dot(PPC); | |
423 | Standard_Real TuuPPC = Tuu.Dot(PPC); | |
424 | ||
425 | Standard_Real A21 = TuuPPC/NorPPC - TuPPC*NuPPC/NorPPCE2; | |
426 | Standard_Real A22 = (0.5*NuuPPC*SquarePPC + NuPPC*TuPPC)/NorPPCE2 - | |
427 | NuPPC*SquarePPC*NorPPC*NuPPC/NorPPCE4; | |
428 | Standard_Real A2u = A21 - A22; | |
429 | //---------------------------------------- | |
430 | V2 = Tuu - 2*A2*Nu - A1*Nuu - A2u*Nor; | |
431 | //---------------------------------------- | |
432 | } | |
433 | ||
434 | //============================================================================= | |
435 | //function : Curvature | |
436 | //purpose : | |
437 | //============================================================================= | |
438 | // Unused : | |
439 | #ifdef DEB | |
440 | static Standard_Real Curvature (const Handle(Geom2d_Curve)& C, | |
441 | Standard_Real U, | |
442 | Standard_Real Tol) | |
443 | { | |
444 | Standard_Real K1; | |
445 | gp_Vec2d D1,D2; | |
446 | gp_Pnt2d P; | |
447 | C->D2(U,P,D1,D2); | |
448 | Standard_Real Norm2 = D1.SquareMagnitude();; | |
449 | if (Norm2 < Tol) { | |
450 | K1 = 0.0; | |
451 | } | |
452 | else { | |
453 | K1 = (D1^D2)/(Norm2*sqrt(Norm2)); | |
454 | } | |
455 | return K1; | |
456 | } | |
457 | #endif | |
458 | ||
459 | //============================================================================= | |
460 | //function : Distance | |
0d969553 | 461 | //purpose : distance at the square of the point of parameter U to the curve and at point: |
7fd59977 | 462 | // |
463 | // 2 ||PP(u)||**4 2 | |
464 | // d = 1/4* ------------------- ||Nor|| | |
465 | // (Nor(u)/PP(u))**2 | |
466 | // | |
0d969553 | 467 | // where Nor is the normal to the curve by U. |
7fd59977 | 468 | //============================================================================= |
469 | Standard_Real Bisector_BisecPC::Distance (const Standard_Real U) const | |
470 | { | |
471 | gp_Vec2d Tan; | |
472 | gp_Pnt2d PC; | |
473 | ||
474 | Standard_Real UOnCurve = LinkBisCurve(U); | |
475 | ||
476 | curve->D1(UOnCurve,PC,Tan); | |
477 | gp_Vec2d PPC(PC.X() - point.X(), PC.Y() - point.Y()); | |
478 | gp_Vec2d Nor( - Tan.Y(), Tan.X()); | |
479 | ||
480 | Standard_Real NorNor = Nor.SquareMagnitude(); | |
481 | Standard_Real SquareMagPPC = PPC.SquareMagnitude(); | |
482 | Standard_Real Prosca = Nor.Dot(PPC); | |
483 | ||
484 | if (point.IsEqual(PC,Precision::Confusion())) { | |
485 | if (isConvex) { return 0.;} | |
486 | //---------------------------------------------------- | |
0d969553 Y |
487 | // the point is on a concave curve. |
488 | // The required point is not the common point. | |
489 | // This can avoid the discontinuity of the bisectrice. | |
7fd59977 | 490 | //---------------------------------------------------- |
491 | else { return Precision::Infinite();} | |
492 | } | |
493 | ||
494 | if (Abs(Prosca) < Precision::Confusion() || (Prosca*sign) > 0. ) { | |
495 | return Precision::Infinite(); | |
496 | } | |
497 | else { | |
498 | Standard_Real A = 0.5*SquareMagPPC/Prosca; | |
499 | Standard_Real Dist = A*A*NorNor; | |
500 | //---------------------------------------- | |
0d969553 | 501 | // Test Curvature if the curve is concave. |
7fd59977 | 502 | //---------------------------------------- |
503 | // if (!isConvex){ | |
504 | // Standard_Real K = Curvature(curve,UOnCurve,Precision::Confusion()); | |
505 | // if (K != 0.) { | |
506 | // if (Dist > 1/(K*K)) { Dist = Precision::Infinite();} | |
507 | // } | |
508 | // } | |
509 | return Dist; | |
510 | } | |
511 | } | |
512 | ||
513 | ||
514 | ||
515 | //============================================================================= | |
516 | //function : D0 | |
517 | // purpose : | |
518 | //============================================================================= | |
519 | void Bisector_BisecPC::D0(const Standard_Real U, | |
520 | gp_Pnt2d& P) const | |
521 | { | |
522 | P = point; | |
523 | gp_Vec2d V1,V2,V3; | |
524 | Values(U,0,P,V1,V2,V3); | |
525 | } | |
526 | ||
527 | ||
528 | //============================================================================= | |
529 | //function : D1 | |
530 | // purpose : | |
531 | //============================================================================= | |
532 | void Bisector_BisecPC::D1(const Standard_Real U, | |
533 | gp_Pnt2d& P, | |
534 | gp_Vec2d& V ) const | |
535 | { | |
536 | P = point; | |
537 | V.SetCoord(0.,0.); | |
538 | gp_Vec2d V2,V3; | |
539 | Values(U,1,P,V,V2,V3); | |
540 | } | |
541 | ||
542 | ||
543 | //============================================================================= | |
544 | //function : D2 | |
545 | // purpose : | |
546 | //============================================================================= | |
547 | void Bisector_BisecPC::D2(const Standard_Real U, | |
548 | gp_Pnt2d& P, | |
549 | gp_Vec2d& V1, | |
550 | gp_Vec2d& V2) const | |
551 | { | |
552 | P = point; | |
553 | V1.SetCoord(0.,0.); | |
554 | V2.SetCoord(0.,0.); | |
555 | gp_Vec2d V3; | |
556 | Values(U,2,P,V1,V2,V3); | |
557 | } | |
558 | ||
559 | //============================================================================= | |
560 | //function : D3 | |
561 | // purpose : | |
562 | //============================================================================= | |
563 | void Bisector_BisecPC::D3(const Standard_Real U, | |
564 | gp_Pnt2d& P, | |
565 | gp_Vec2d& V1, | |
566 | gp_Vec2d& V2, | |
567 | gp_Vec2d& V3) const | |
568 | { | |
569 | P = point; | |
570 | V1.SetCoord(0.,0.); | |
571 | V2.SetCoord(0.,0.); | |
572 | V3.SetCoord(0.,0.); | |
573 | Values(U,3,P,V1,V2,V3); | |
574 | } | |
575 | ||
576 | ||
577 | //============================================================================= | |
578 | //function : DN | |
579 | // purpose : | |
580 | //============================================================================= | |
581 | gp_Vec2d Bisector_BisecPC::DN (const Standard_Real U, | |
582 | const Standard_Integer N) const | |
583 | { | |
584 | gp_Pnt2d P = point; | |
585 | gp_Vec2d V1(0.,0.); | |
586 | gp_Vec2d V2(0.,0.); | |
587 | gp_Vec2d V3(0.,0.); | |
588 | Values (U,N,P,V1,V2,V3); | |
589 | switch (N) { | |
590 | case 1 : return V1; | |
591 | case 2 : return V2; | |
592 | case 3 : return V3; | |
593 | default: { | |
594 | Standard_NotImplemented::Raise(); | |
595 | } | |
596 | } | |
597 | return V1; | |
598 | } | |
599 | ||
600 | //============================================================================= | |
601 | //function : SearchBound | |
602 | // purpose : | |
603 | //============================================================================= | |
604 | Standard_Real Bisector_BisecPC::SearchBound (const Standard_Real U1, | |
605 | const Standard_Real U2) const | |
606 | { | |
607 | Standard_Real Dist1,Dist2,DistMid,U11,U22; | |
608 | #ifndef DEB | |
609 | Standard_Real UMid = 0.; | |
610 | #else | |
611 | Standard_Real UMid; | |
612 | #endif | |
613 | Standard_Real Tol = Precision::PConfusion(); | |
614 | Standard_Real DistMax2 = distMax*distMax; | |
615 | U11 = U1; U22 = U2; | |
616 | Dist1 = Distance(U11); | |
617 | Dist2 = Distance(U22); | |
618 | ||
619 | while ((U22 - U11) > Tol) { | |
620 | UMid = 0.5*( U22 + U11); | |
621 | DistMid = Distance(UMid); | |
622 | if ((Dist1 > DistMax2) == (DistMid > DistMax2)) { | |
623 | U11 = UMid; | |
624 | Dist1 = DistMid; | |
625 | } | |
626 | else { | |
627 | U22 = UMid; | |
628 | Dist2 = DistMid; | |
629 | } | |
630 | } | |
631 | return UMid; | |
632 | } | |
633 | ||
634 | //============================================================================= | |
635 | //function : CuspFilter | |
636 | // purpose : | |
637 | //============================================================================= | |
638 | void Bisector_BisecPC::CuspFilter() | |
639 | { | |
640 | Standard_NotImplemented::Raise(); | |
641 | } | |
642 | ||
643 | //============================================================================= | |
644 | //function : ComputeIntervals | |
645 | // purpose : | |
646 | //============================================================================= | |
647 | void Bisector_BisecPC::ComputeIntervals () | |
648 | { | |
649 | #ifndef DEB | |
650 | Standard_Real U1 =0.,U2 =0.,UProj =0.; | |
651 | #else | |
652 | Standard_Real U1,U2,UProj; | |
653 | #endif | |
654 | Standard_Real UStart,UEnd; | |
655 | Standard_Real Dist1,Dist2,DistProj; | |
656 | isEmpty = Standard_False; | |
657 | shiftParameter = 0.; | |
658 | Standard_Boolean YaProj = Standard_False; | |
659 | Standard_Real DistMax2 = distMax*distMax; | |
660 | ||
661 | U1 = curve->FirstParameter(); | |
662 | U2 = curve->LastParameter(); | |
663 | Dist1 = Distance(U1); | |
664 | Dist2 = Distance(U2); | |
665 | DistProj = Precision::Infinite(); | |
666 | ||
667 | Geom2dAPI_ProjectPointOnCurve Proj(point,curve,U1,U2); | |
668 | if (Proj.NbPoints() > 0) { | |
669 | UProj = Proj.LowerDistanceParameter(); | |
670 | DistProj = Distance(UProj); | |
671 | YaProj = Standard_True; | |
672 | } | |
673 | ||
674 | if (Dist1 < DistMax2 && Dist2 < DistMax2) { | |
675 | if (DistProj > DistMax2 && YaProj) { | |
676 | isEmpty = Standard_True; | |
677 | } | |
678 | else { | |
679 | startIntervals.Append(U1); | |
680 | endIntervals .Append(U2); | |
681 | } | |
682 | return; | |
683 | } | |
684 | else if (Dist1 > DistMax2 && Dist2 > DistMax2) { | |
685 | if (DistProj < DistMax2) { | |
686 | UStart = SearchBound(U1,UProj); | |
687 | UEnd = SearchBound(UProj,U2); | |
688 | } | |
689 | else { | |
690 | isEmpty = Standard_True; | |
691 | return; | |
692 | } | |
693 | } | |
694 | else if (Dist1 < DistMax2) { | |
695 | UStart = U1; | |
696 | UEnd = SearchBound(U1,U2); | |
697 | } | |
698 | else if (Dist2 < DistMax2) { | |
699 | UEnd = U2; | |
700 | UStart = SearchBound(U1,U2); | |
701 | } | |
702 | startIntervals.Append(UStart); | |
703 | endIntervals .Append(UEnd); | |
704 | ||
705 | //------------------------------------------------------------------------ | |
0d969553 Y |
706 | // Eventual offset of the parameter on the curve correspondingly to the one |
707 | // on the curve. The offset can be done if the curve is periodical and the | |
708 | // point of initial parameter is less then the interval of continuity. | |
7fd59977 | 709 | //------------------------------------------------------------------------ |
710 | if (curve->IsPeriodic()) { | |
711 | if (startIntervals.Length() > 1) { // Plusieurs intervals. | |
712 | if (endIntervals .Last() == curve->LastParameter() && | |
713 | startIntervals.First() == curve->FirstParameter() ) { | |
714 | //--------------------------------------------------------------- | |
0d969553 Y |
715 | // the bissectrice is defined at the origin. |
716 | // => Fusion of the first and the last interval. | |
717 | // => 0 on the bisectrice becomes the start of the first interval | |
718 | // => offset of parameter on all limits of intervals. | |
7fd59977 | 719 | //--------------------------------------------------------------- |
720 | startIntervals.Remove(1); | |
721 | endIntervals .Remove(endIntervals.Length()); | |
722 | ||
723 | shiftParameter = Period() - startIntervals.First() ; | |
724 | for (Standard_Integer k = 1; k <= startIntervals.Length(); k++) { | |
725 | endIntervals .ChangeValue(k) += shiftParameter; | |
726 | startIntervals.ChangeValue(k) += shiftParameter; | |
727 | } | |
728 | startIntervals.ChangeValue(1) = 0.; | |
729 | } | |
730 | } | |
731 | } | |
732 | } | |
733 | ||
734 | //============================================================================= | |
735 | //function : LinkBisCurve | |
736 | //purpose : | |
737 | //============================================================================= | |
738 | Standard_Real Bisector_BisecPC::LinkBisCurve(const Standard_Real U) const | |
739 | { | |
740 | return (U - shiftParameter); | |
741 | } | |
742 | ||
743 | //============================================================================= | |
744 | //function : LinkCurveBis | |
745 | //purpose : | |
746 | //============================================================================= | |
747 | Standard_Real Bisector_BisecPC::LinkCurveBis(const Standard_Real U) const | |
748 | { | |
749 | return (U + shiftParameter); | |
750 | } | |
751 | ||
752 | //============================================================================= | |
753 | //function : IsEmpty | |
754 | //purpose : | |
755 | //============================================================================= | |
756 | Standard_Boolean Bisector_BisecPC::IsEmpty() const | |
757 | { | |
758 | return isEmpty; | |
759 | } | |
760 | ||
761 | //========================================================================== | |
762 | //function : Parameter | |
763 | //purpose : | |
764 | //========================================================================== | |
765 | Standard_Real Bisector_BisecPC::Parameter(const gp_Pnt2d& P) const | |
766 | { | |
767 | Standard_Real Tol = Precision::Confusion(); | |
768 | ||
769 | if (P.IsEqual(pointStartBis,Tol)) {return startIntervals.Value(bisInterval);} | |
770 | if (P.IsEqual(pointEndBis ,Tol)) {return endIntervals .Value(bisInterval);} | |
771 | ||
772 | if (extensionStart) { | |
773 | gp_Ax2d Axe(pointStartBis,gp_Dir2d(pointStartBis.X() - P.X(), | |
774 | pointStartBis.Y() - P.Y())); | |
775 | Standard_Real U = ElCLib::LineParameter(Axe,P); | |
776 | gp_Pnt2d Proj = ElCLib::LineValue(U,Axe); | |
777 | if (Proj.IsEqual(P,Tol) && U < 0.) { | |
778 | return U + startIntervals.Value(bisInterval); | |
779 | } | |
780 | } | |
781 | if (extensionEnd) { | |
782 | gp_Ax2d Axe(pointEndBis,gp_Dir2d(P.X() - pointEndBis.X(), | |
783 | P.Y() - pointEndBis.Y())); | |
784 | Standard_Real U = ElCLib::LineParameter(Axe,P); | |
785 | gp_Pnt2d Proj = ElCLib::LineValue(U,Axe); | |
786 | if (Proj.IsEqual(P,Tol) && U > 0.) { | |
787 | return U + endIntervals.Value(bisInterval); | |
788 | } | |
789 | } | |
790 | #ifndef DEB | |
791 | Standard_Real UOnCurve = 0.; | |
792 | #else | |
793 | Standard_Real UOnCurve; | |
794 | #endif | |
795 | Geom2dAPI_ProjectPointOnCurve Proj(P,curve, | |
796 | curve->FirstParameter(),curve->LastParameter()); | |
797 | if (Proj.NbPoints() > 0) { | |
798 | UOnCurve = Proj.LowerDistanceParameter(); | |
799 | } | |
800 | return LinkCurveBis(UOnCurve); | |
801 | } | |
802 | ||
803 | ||
804 | //============================================================================= | |
805 | //function : Indent | |
806 | // purpose : | |
807 | //============================================================================= | |
808 | static void Indent(const Standard_Integer Offset) { | |
809 | if (Offset > 0) { | |
810 | for (Standard_Integer i = 0; i < Offset; i++) {cout << " ";} | |
811 | } | |
812 | } | |
813 | ||
814 | //============================================================================= | |
815 | //function : Init | |
816 | // purpose : | |
817 | //============================================================================= | |
818 | void Bisector_BisecPC::Init (const Handle_Geom2d_Curve& Curve, | |
819 | const gp_Pnt2d& Point, | |
820 | const Standard_Real Sign, | |
821 | const TColStd_SequenceOfReal& StartIntervals, | |
822 | const TColStd_SequenceOfReal& EndIntervals, | |
823 | const Standard_Integer BisInterval, | |
824 | const Standard_Integer CurrentInterval, | |
825 | const Standard_Real ShiftParameter, | |
826 | const Standard_Real DistMax, | |
827 | const Standard_Boolean IsEmpty, | |
828 | const Standard_Boolean IsConvex, | |
829 | const Standard_Boolean ExtensionStart, | |
830 | const Standard_Boolean ExtensionEnd, | |
831 | const gp_Pnt2d& PointStartBis, | |
832 | const gp_Pnt2d& PointEndBis) | |
833 | { | |
834 | curve = Curve; | |
835 | point = Point; | |
836 | sign = Sign ; | |
837 | startIntervals = StartIntervals; | |
838 | endIntervals = EndIntervals; | |
839 | bisInterval = BisInterval; | |
840 | currentInterval = CurrentInterval; | |
841 | shiftParameter = ShiftParameter; | |
842 | distMax = DistMax; | |
843 | isEmpty = IsEmpty; | |
844 | isConvex = IsConvex; | |
845 | extensionStart = ExtensionStart; | |
846 | extensionEnd = ExtensionEnd; | |
847 | pointStartBis = PointStartBis; | |
848 | pointEndBis = PointEndBis; | |
849 | } | |
850 | ||
851 | //============================================================================= | |
852 | //function : Dump | |
853 | // purpose : | |
854 | //============================================================================= | |
855 | //void Bisector_BisecPC::Dump(const Standard_Integer Deep, | |
856 | void Bisector_BisecPC::Dump(const Standard_Integer , | |
857 | const Standard_Integer Offset) const | |
858 | { | |
859 | Indent (Offset); | |
860 | cout <<"Bisector_BisecPC :"<<endl; | |
861 | Indent (Offset); | |
862 | cout <<"Point :"<<endl; | |
863 | cout <<" X = "<<point.X()<<endl; | |
864 | cout <<" Y = "<<point.Y()<<endl; | |
865 | cout <<"Sign :"<<sign<<endl; | |
866 | cout <<"Number Of Intervals :"<<startIntervals.Length()<<endl; | |
867 | for (Standard_Integer i = 1; i <= startIntervals.Length(); i++) { | |
868 | cout <<"Interval number :"<<i<<"Start :"<<startIntervals.Value(i) | |
869 | <<" end :"<< endIntervals.Value(i)<<endl ; | |
870 | } | |
871 | cout <<"Index Current Interval :"<<currentInterval<<endl; | |
872 | } | |
873 | ||
874 | ||
875 | ||
876 | ||
877 | ||
878 |