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