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