0024530: TKMesh - remove unused package IntPoly
[occt.git] / src / GeomAPI / GeomAPI_ExtremaCurveCurve.cxx
CommitLineData
b311480e 1// Created on: 1994-03-18
2// Created by: Bruno DUMORTIER
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 <GeomAPI_ExtremaCurveCurve.ixx>
18
19#include <GeomAdaptor_Curve.hxx>
20//#include <Extrema_POnCurv.hxx>
21
22#include <Precision.hxx>
23#include <GeomAPI_ProjectPointOnCurve.hxx>
24
25//=======================================================================
26//function : GeomAPI_ExtremaCurveCurve
27//purpose :
28//=======================================================================
29
30GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve()
31{
32 myIsDone = Standard_False;
33 myTotalExt = Standard_False;
34}
35
36
37//=======================================================================
38//function : GeomAPI_ExtremaCurveCurve
39//purpose :
40//=======================================================================
41
42GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve
43 (const Handle(Geom_Curve)& C1,
44 const Handle(Geom_Curve)& C2)
45{
46 Init(C1,C2);
47}
48
49
50//=======================================================================
51//function : GeomAPI_ExtremaCurveCurve
52//purpose :
53//=======================================================================
54
55GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve
56 (const Handle(Geom_Curve)& C1,
57 const Handle(Geom_Curve)& C2,
58 const Standard_Real U1min,
59 const Standard_Real U1max,
60 const Standard_Real U2min,
61 const Standard_Real U2max)
62{
63 Init(C1,C2,U1min,U1max,U2min,U2max);
64}
65
66
67//=======================================================================
68//function : Init
69//purpose :
70//=======================================================================
71
72void GeomAPI_ExtremaCurveCurve::Init
73 (const Handle(Geom_Curve)& C1,
74 const Handle(Geom_Curve)& C2)
75{
76
77 myTotalExt = Standard_False;
78
79 Standard_Real Tol = Precision::PConfusion();
80 myC1.Load(C1);
81 myC2.Load(C2);
82 Extrema_ExtCC theExtCC(myC1, myC2, Tol,Tol);
83 myExtCC = theExtCC;
84
85 myIsDone = myExtCC.IsDone() && ( myExtCC.NbExt() > 0);
86
87 if ( myIsDone) {
88
89 // evaluate the lower distance and its index;
90
91 Standard_Real Dist2, Dist2Min = myExtCC.SquareDistance(1);
92 myIndex = 1;
93
94 for ( Standard_Integer i = 2; i <= myExtCC.NbExt(); i++) {
95 Dist2 = myExtCC.SquareDistance(i);
96 if ( Dist2 < Dist2Min) {
97 Dist2Min = Dist2;
98 myIndex = i;
99 }
100 }
101 }
102}
103
104
105//=======================================================================
106//function : Init
107//purpose :
108//=======================================================================
109
110void GeomAPI_ExtremaCurveCurve::Init
111 (const Handle(Geom_Curve)& C1,
112 const Handle(Geom_Curve)& C2,
113 const Standard_Real U1min,
114 const Standard_Real U1max,
115 const Standard_Real U2min,
116 const Standard_Real U2max)
117{
118
119 myTotalExt = Standard_False;
120
121 Standard_Real Tol = Precision::PConfusion();
122 myC1.Load(C1);
123 myC2.Load(C2);
124 Extrema_ExtCC theExtCC(myC1,myC2,U1min,U1max,U2min,U2max,Tol,Tol);
125 myExtCC = theExtCC;
126
127 myIsDone = myExtCC.IsDone() && ( myExtCC.NbExt() > 0 );
128
129 if ( myIsDone) {
130
131 // evaluate the lower distance and its index;
132
133 Standard_Real Dist2, Dist2Min = myExtCC.SquareDistance(1);
134 myIndex = 1;
135
136 for ( Standard_Integer i = 2; i <= myExtCC.NbExt(); i++) {
137 Dist2 = myExtCC.SquareDistance(i);
138 if ( Dist2 < Dist2Min) {
139 Dist2Min = Dist2;
140 myIndex = i;
141 }
142 }
143 }
144}
145
146
147//=======================================================================
148//function : NbExtrema
149//purpose :
150//=======================================================================
151
152Standard_Integer GeomAPI_ExtremaCurveCurve::NbExtrema() const
153{
154 if ( myIsDone)
155 return myExtCC.NbExt();
156 else
157 return 0;
158}
159
160
161//=======================================================================
162//function : Points
163//purpose :
164//=======================================================================
165
166void GeomAPI_ExtremaCurveCurve::Points
167 (const Standard_Integer Index,
168 gp_Pnt& P1,
169 gp_Pnt& P2) const
170{
171 Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
172 "GeomAPI_ExtremaCurveCurve::Points");
173
174 Extrema_POnCurv PC1, PC2;
175 myExtCC.Points(Index,PC1,PC2);
176
177 P1 = PC1.Value();
178 P2 = PC2.Value();
179}
180
181
182//=======================================================================
183//function : Parameters
184//purpose :
185//=======================================================================
186
187void GeomAPI_ExtremaCurveCurve::Parameters
188 (const Standard_Integer Index,
189 Standard_Real& U1,
190 Standard_Real& U2) const
191{
192 Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
193 "GeomAPI_ExtremaCurveCurve::Parameters");
194
195 Extrema_POnCurv PC1, PC2;
196 myExtCC.Points(Index,PC1,PC2);
197
198 U1 = PC1.Parameter();
199 U2 = PC2.Parameter();
200}
201
202
203//=======================================================================
204//function : Distance
205//purpose :
206//=======================================================================
207
208Standard_Real GeomAPI_ExtremaCurveCurve::Distance
209 (const Standard_Integer Index) const
210{
211 Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
212 "GeomAPI_ExtremaCurveCurve::Distance");
213
214 return sqrt (myExtCC.SquareDistance(Index));
215}
216
217
218//=======================================================================
219//function : NearestPoints
220//purpose :
221//=======================================================================
222
223void GeomAPI_ExtremaCurveCurve::NearestPoints(gp_Pnt& P1, gp_Pnt& P2) const
224{
225 StdFail_NotDone_Raise_if
226 (!myIsDone, "GeomAPI_ExtremaCurveCurve::NearestPoints");
227
228 Points(myIndex,P1,P2);
229}
230
231
232//=======================================================================
233//function : LowerDistanceParameters
234//purpose :
235//=======================================================================
236
237void GeomAPI_ExtremaCurveCurve::LowerDistanceParameters
238 (Standard_Real& U1,
239 Standard_Real& U2) const
240{
241 StdFail_NotDone_Raise_if
242 (!myIsDone, "GeomAPI_ExtremaCurveCurve::LowerDistanceParameters");
243
244 Parameters(myIndex,U1,U2);
245}
246
247
248//=======================================================================
249//function : LowerDistance
250//purpose :
251//=======================================================================
252
253Standard_Real GeomAPI_ExtremaCurveCurve::LowerDistance() const
254{
255 StdFail_NotDone_Raise_if
256 (!myIsDone, "GeomAPI_ExtremaCurveCurve::LowerDistance");
257
258 return sqrt (myExtCC.SquareDistance(myIndex));
259}
260
261
262//=======================================================================
263//function : Standard_Real
264//purpose :
265//=======================================================================
266
267GeomAPI_ExtremaCurveCurve::operator Standard_Real() const
268{
269 return LowerDistance();
270}
271
272
273//=======================================================================
274//function : Standard_Integer
275//purpose :
276//=======================================================================
277
278GeomAPI_ExtremaCurveCurve::operator Standard_Integer() const
279{
280 return myExtCC.NbExt();
281}
282
283
284Standard_Boolean GeomAPI_ExtremaCurveCurve::TotalNearestPoints(gp_Pnt& P1,gp_Pnt& P2)
285{
286
287 if(!myTotalExt) {
288
289 TotalPerform();
290 myTotalExt = Standard_True;
291
292 }
293
294 if(myIsInfinite) return Standard_False;
295
296 P1 = myTotalPoints[0];
297 P2 = myTotalPoints[1];
298
299 return Standard_True;
300
301}
302
303Standard_Boolean GeomAPI_ExtremaCurveCurve::TotalLowerDistanceParameters(Quantity_Parameter& U1,
304 Quantity_Parameter& U2)
305{
306 if(!myTotalExt) {
307
308 TotalPerform();
309 myTotalExt = Standard_True;
310
311 }
312
313 if(myIsInfinite) return Standard_False;
314
315 U1 = myTotalPars[0];
316 U2 = myTotalPars[1];
317
318 return Standard_True;
319
320}
321
322Quantity_Length GeomAPI_ExtremaCurveCurve::TotalLowerDistance()
323{
324 if(!myTotalExt) {
325
326 TotalPerform();
327 myTotalExt = Standard_True;
328
329 }
330
331 return myTotalDist;
332
333}
334
335
336void GeomAPI_ExtremaCurveCurve::TotalPerform()
337
338{
339// StdFail_NotDone_Raise_if
340// (!myExtCC.IsDone(), "GeomAPI_ExtremaCurveCurve::TotalPerform");
341
342 Standard_Real u11 = myC1.FirstParameter();
343 Standard_Real u12 = myC1.LastParameter();
344 Standard_Real u21 = myC2.FirstParameter();
345 Standard_Real u22 = myC2.LastParameter();
346
347 Standard_Boolean infinite = Precision::IsInfinite(u11) &&
348 Precision::IsInfinite(u12) &&
349 Precision::IsInfinite(u21) &&
350 Precision::IsInfinite(u22);
351
352 myIsInfinite = Standard_False;
353
354 if(infinite && myExtCC.IsParallel()) {
355
356 myIsInfinite = Standard_True;
357
358 //calculate distance between any suitable point on C1 and C2
359
360 gp_Pnt PonC1 = myC1.Value(0.);
361 GeomAPI_ProjectPointOnCurve proj(PonC1, myC2.Curve());
362 myTotalDist = proj.LowerDistance();
363
364 return;
365
366 }
367
368 myTotalDist = RealLast();
369
370 if(myIsDone && !myExtCC.IsParallel()) {
371
372 Points(myIndex, myTotalPoints[0], myTotalPoints[1]);
373 Parameters(myIndex, myTotalPars[0], myTotalPars[1]);
374 myTotalDist = sqrt (myExtCC.SquareDistance(myIndex));
375
376 if(myTotalDist <= Precision::Confusion()) return;
377
378 }
379
380 gp_Pnt P11, P12, P21, P22;
381 Standard_Real d11, d12, d21, d22;
382 myExtCC.TrimmedSquareDistances(d11, d12, d21, d22, P11, P12, P21, P22);
383
384 Standard_Real aTotalDist2 = myTotalDist * myTotalDist;
385 if(aTotalDist2 > d11) {
386 myTotalDist = sqrt (d11);
387 myTotalPoints[0] = P11;
388 myTotalPoints[1] = P21;
389 myTotalPars[0] = u11;
390 myTotalPars[1] = u21;
391
392 if(myTotalDist <= Precision::Confusion()) return;
393
394 }
395
396 if(aTotalDist2 > d12) {
397 myTotalDist = sqrt (d12);
398 myTotalPoints[0] = P11;
399 myTotalPoints[1] = P22;
400 myTotalPars[0] = u11;
401 myTotalPars[1] = u22;
402
403 if(myTotalDist <= Precision::Confusion()) return;
404
405 }
406
407 if(aTotalDist2 > d21) {
408 myTotalDist = sqrt (d21);
409 myTotalPoints[0] = P12;
410 myTotalPoints[1] = P21;
411 myTotalPars[0] = u12;
412 myTotalPars[1] = u21;
413
414 if(myTotalDist <= Precision::Confusion()) return;
415
416 }
417
418 if(aTotalDist2 > d22) {
419 myTotalDist = sqrt (d22);
420 myTotalPoints[0] = P12;
421 myTotalPoints[1] = P22;
422 myTotalPars[0] = u12;
423 myTotalPars[1] = u22;
424
425 if(myTotalDist <= Precision::Confusion()) return;
426
427 }
428
429 // calculate distances between extremities one curve and other curve
430
431 if(!Precision::IsInfinite(u11)) {
432 GeomAPI_ProjectPointOnCurve proj(P11, myC2.Curve(), u21, u22);
433
434 if(proj.NbPoints() > 0) {
435
436 Standard_Real dmin = proj.LowerDistance();
437 if(myTotalDist > dmin) {
438 myTotalDist = dmin;
439 myTotalPoints[0] = P11;
440 myTotalPars[0] = u11;
441 myTotalPoints[1] = proj.NearestPoint();
442 myTotalPars[1] = proj.LowerDistanceParameter();
443
444 if(myTotalDist <= Precision::Confusion()) return;
445
446 }
447 }
448 }
449
450 if(!Precision::IsInfinite(u12)) {
451 GeomAPI_ProjectPointOnCurve proj(P12, myC2.Curve(), u21, u22);
452
453 if(proj.NbPoints() > 0) {
454
455 Standard_Real dmin = proj.LowerDistance();
456 if(myTotalDist > dmin) {
457 myTotalDist = dmin;
458 myTotalPoints[0] = P12;
459 myTotalPars[0] = u12;
460 myTotalPoints[1] = proj.NearestPoint();
461 myTotalPars[1] = proj.LowerDistanceParameter();
462
463 if(myTotalDist <= Precision::Confusion()) return;
464
465 }
466 }
467 }
468
469 if(!Precision::IsInfinite(u21)) {
470 GeomAPI_ProjectPointOnCurve proj(P21, myC1.Curve(), u11, u12);
471
472 if(proj.NbPoints() > 0) {
473
474 Standard_Real dmin = proj.LowerDistance();
475 if(myTotalDist > dmin) {
476 myTotalDist = dmin;
477 myTotalPoints[0] = proj.NearestPoint();
478 myTotalPars[0] = proj.LowerDistanceParameter();
479 myTotalPoints[1] = P21;
480 myTotalPars[1] = u21;
481
482 if(myTotalDist <= Precision::Confusion()) return;
483
484 }
485 }
486 }
487
488 if(!Precision::IsInfinite(u22)) {
489 GeomAPI_ProjectPointOnCurve proj(P22, myC1.Curve(), u11, u12);
490
491 if(proj.NbPoints() > 0) {
492
493 Standard_Real dmin = proj.LowerDistance();
494 if(myTotalDist > dmin) {
495 myTotalDist = dmin;
496 myTotalPoints[0] = proj.NearestPoint();
497 myTotalPars[0] = proj.LowerDistanceParameter();
498 myTotalPoints[1] = P22;
499 myTotalPars[1] = u22;
500
501 }
502 }
503 }
504
505
506}