1 // Created on: 1994-03-18
2 // Created by: Bruno DUMORTIER
3 // Copyright (c) 1994-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
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
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Extrema_ExtCC.hxx>
19 #include <Geom_Curve.hxx>
20 #include <GeomAdaptor_Curve.hxx>
21 #include <GeomAPI_ExtremaCurveCurve.hxx>
22 #include <GeomAPI_ProjectPointOnCurve.hxx>
24 #include <Precision.hxx>
25 #include <Standard_OutOfRange.hxx>
26 #include <StdFail_NotDone.hxx>
28 //#include <Extrema_POnCurv.hxx>
29 //=======================================================================
30 //function : GeomAPI_ExtremaCurveCurve
32 //=======================================================================
33 GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve()
35 myIsDone = Standard_False;
36 myTotalExt = Standard_False;
40 //=======================================================================
41 //function : GeomAPI_ExtremaCurveCurve
43 //=======================================================================
45 GeomAPI_ExtremaCurveCurve::GeomAPI_ExtremaCurveCurve
46 (const Handle(Geom_Curve)& C1,
47 const Handle(Geom_Curve)& C2)
53 //=======================================================================
54 //function : GeomAPI_ExtremaCurveCurve
56 //=======================================================================
58 GeomAPI_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)
66 Init(C1,C2,U1min,U1max,U2min,U2max);
70 //=======================================================================
73 //=======================================================================
75 void GeomAPI_ExtremaCurveCurve::Init
76 (const Handle(Geom_Curve)& C1,
77 const Handle(Geom_Curve)& C2)
80 myTotalExt = Standard_False;
82 Standard_Real Tol = Precision::PConfusion();
85 Extrema_ExtCC theExtCC(myC1, myC2, Tol,Tol);
88 myIsDone = myExtCC.IsDone() && ( myExtCC.NbExt() > 0);
92 // evaluate the lower distance and its index;
94 Standard_Real Dist2, Dist2Min = myExtCC.SquareDistance(1);
97 for ( Standard_Integer i = 2; i <= myExtCC.NbExt(); i++) {
98 Dist2 = myExtCC.SquareDistance(i);
99 if ( Dist2 < Dist2Min) {
108 //=======================================================================
111 //=======================================================================
113 void 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)
122 myTotalExt = Standard_False;
124 Standard_Real Tol = Precision::PConfusion();
127 Extrema_ExtCC theExtCC(myC1,myC2,U1min,U1max,U2min,U2max,Tol,Tol);
130 myIsDone = myExtCC.IsDone() && ( myExtCC.NbExt() > 0 );
134 // evaluate the lower distance and its index;
136 Standard_Real Dist2, Dist2Min = myExtCC.SquareDistance(1);
139 for ( Standard_Integer i = 2; i <= myExtCC.NbExt(); i++) {
140 Dist2 = myExtCC.SquareDistance(i);
141 if ( Dist2 < Dist2Min) {
150 //=======================================================================
151 //function : NbExtrema
153 //=======================================================================
155 Standard_Integer GeomAPI_ExtremaCurveCurve::NbExtrema() const
158 return myExtCC.NbExt();
164 //=======================================================================
167 //=======================================================================
169 void GeomAPI_ExtremaCurveCurve::Points
170 (const Standard_Integer Index,
174 Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
175 "GeomAPI_ExtremaCurveCurve::Points");
177 Extrema_POnCurv PC1, PC2;
178 myExtCC.Points(Index,PC1,PC2);
185 //=======================================================================
186 //function : Parameters
188 //=======================================================================
190 void GeomAPI_ExtremaCurveCurve::Parameters
191 (const Standard_Integer Index,
193 Standard_Real& U2) const
195 Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
196 "GeomAPI_ExtremaCurveCurve::Parameters");
198 Extrema_POnCurv PC1, PC2;
199 myExtCC.Points(Index,PC1,PC2);
201 U1 = PC1.Parameter();
202 U2 = PC2.Parameter();
206 //=======================================================================
207 //function : Distance
209 //=======================================================================
211 Standard_Real GeomAPI_ExtremaCurveCurve::Distance
212 (const Standard_Integer Index) const
214 Standard_OutOfRange_Raise_if( Index < 1 || Index > NbExtrema(),
215 "GeomAPI_ExtremaCurveCurve::Distance");
217 return sqrt (myExtCC.SquareDistance(Index));
221 //=======================================================================
222 //function : NearestPoints
224 //=======================================================================
226 void GeomAPI_ExtremaCurveCurve::NearestPoints(gp_Pnt& P1, gp_Pnt& P2) const
228 StdFail_NotDone_Raise_if
229 (!myIsDone, "GeomAPI_ExtremaCurveCurve::NearestPoints");
231 Points(myIndex,P1,P2);
235 //=======================================================================
236 //function : LowerDistanceParameters
238 //=======================================================================
240 void GeomAPI_ExtremaCurveCurve::LowerDistanceParameters
242 Standard_Real& U2) const
244 StdFail_NotDone_Raise_if
245 (!myIsDone, "GeomAPI_ExtremaCurveCurve::LowerDistanceParameters");
247 Parameters(myIndex,U1,U2);
251 //=======================================================================
252 //function : LowerDistance
254 //=======================================================================
256 Standard_Real GeomAPI_ExtremaCurveCurve::LowerDistance() const
258 StdFail_NotDone_Raise_if
259 (!myIsDone, "GeomAPI_ExtremaCurveCurve::LowerDistance");
261 return sqrt (myExtCC.SquareDistance(myIndex));
265 //=======================================================================
266 //function : Standard_Real
268 //=======================================================================
270 GeomAPI_ExtremaCurveCurve::operator Standard_Real() const
272 return LowerDistance();
276 //=======================================================================
277 //function : Standard_Integer
279 //=======================================================================
281 GeomAPI_ExtremaCurveCurve::operator Standard_Integer() const
283 return myExtCC.NbExt();
287 Standard_Boolean GeomAPI_ExtremaCurveCurve::TotalNearestPoints(gp_Pnt& P1,gp_Pnt& P2)
293 myTotalExt = Standard_True;
297 if(myIsInfinite) return Standard_False;
299 P1 = myTotalPoints[0];
300 P2 = myTotalPoints[1];
302 return Standard_True;
306 Standard_Boolean GeomAPI_ExtremaCurveCurve::TotalLowerDistanceParameters(Quantity_Parameter& U1,
307 Quantity_Parameter& U2)
312 myTotalExt = Standard_True;
316 if(myIsInfinite) return Standard_False;
321 return Standard_True;
325 Quantity_Length GeomAPI_ExtremaCurveCurve::TotalLowerDistance()
330 myTotalExt = Standard_True;
339 void GeomAPI_ExtremaCurveCurve::TotalPerform()
342 // StdFail_NotDone_Raise_if
343 // (!myExtCC.IsDone(), "GeomAPI_ExtremaCurveCurve::TotalPerform");
345 Standard_Real u11 = myC1.FirstParameter();
346 Standard_Real u12 = myC1.LastParameter();
347 Standard_Real u21 = myC2.FirstParameter();
348 Standard_Real u22 = myC2.LastParameter();
350 Standard_Boolean infinite = Precision::IsInfinite(u11) &&
351 Precision::IsInfinite(u12) &&
352 Precision::IsInfinite(u21) &&
353 Precision::IsInfinite(u22);
355 myIsInfinite = Standard_False;
357 if(infinite && myExtCC.IsParallel()) {
359 myIsInfinite = Standard_True;
361 //calculate distance between any suitable point on C1 and C2
363 gp_Pnt PonC1 = myC1.Value(0.);
364 GeomAPI_ProjectPointOnCurve proj(PonC1, myC2.Curve());
365 myTotalDist = proj.LowerDistance();
371 myTotalDist = RealLast();
373 if(myIsDone && !myExtCC.IsParallel()) {
375 Points(myIndex, myTotalPoints[0], myTotalPoints[1]);
376 Parameters(myIndex, myTotalPars[0], myTotalPars[1]);
377 myTotalDist = sqrt (myExtCC.SquareDistance(myIndex));
379 if(myTotalDist <= Precision::Confusion()) return;
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);
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;
395 if(myTotalDist <= Precision::Confusion()) return;
399 if(aTotalDist2 > d12) {
400 myTotalDist = sqrt (d12);
401 myTotalPoints[0] = P11;
402 myTotalPoints[1] = P22;
403 myTotalPars[0] = u11;
404 myTotalPars[1] = u22;
406 if(myTotalDist <= Precision::Confusion()) return;
410 if(aTotalDist2 > d21) {
411 myTotalDist = sqrt (d21);
412 myTotalPoints[0] = P12;
413 myTotalPoints[1] = P21;
414 myTotalPars[0] = u12;
415 myTotalPars[1] = u21;
417 if(myTotalDist <= Precision::Confusion()) return;
421 if(aTotalDist2 > d22) {
422 myTotalDist = sqrt (d22);
423 myTotalPoints[0] = P12;
424 myTotalPoints[1] = P22;
425 myTotalPars[0] = u12;
426 myTotalPars[1] = u22;
428 if(myTotalDist <= Precision::Confusion()) return;
432 // calculate distances between extremities one curve and other curve
434 if(!Precision::IsInfinite(u11)) {
435 GeomAPI_ProjectPointOnCurve proj(P11, myC2.Curve(), u21, u22);
437 if(proj.NbPoints() > 0) {
439 Standard_Real dmin = proj.LowerDistance();
440 if(myTotalDist > dmin) {
442 myTotalPoints[0] = P11;
443 myTotalPars[0] = u11;
444 myTotalPoints[1] = proj.NearestPoint();
445 myTotalPars[1] = proj.LowerDistanceParameter();
447 if(myTotalDist <= Precision::Confusion()) return;
453 if(!Precision::IsInfinite(u12)) {
454 GeomAPI_ProjectPointOnCurve proj(P12, myC2.Curve(), u21, u22);
456 if(proj.NbPoints() > 0) {
458 Standard_Real dmin = proj.LowerDistance();
459 if(myTotalDist > dmin) {
461 myTotalPoints[0] = P12;
462 myTotalPars[0] = u12;
463 myTotalPoints[1] = proj.NearestPoint();
464 myTotalPars[1] = proj.LowerDistanceParameter();
466 if(myTotalDist <= Precision::Confusion()) return;
472 if(!Precision::IsInfinite(u21)) {
473 GeomAPI_ProjectPointOnCurve proj(P21, myC1.Curve(), u11, u12);
475 if(proj.NbPoints() > 0) {
477 Standard_Real dmin = proj.LowerDistance();
478 if(myTotalDist > dmin) {
480 myTotalPoints[0] = proj.NearestPoint();
481 myTotalPars[0] = proj.LowerDistanceParameter();
482 myTotalPoints[1] = P21;
483 myTotalPars[1] = u21;
485 if(myTotalDist <= Precision::Confusion()) return;
491 if(!Precision::IsInfinite(u22)) {
492 GeomAPI_ProjectPointOnCurve proj(P22, myC1.Curve(), u11, u12);
494 if(proj.NbPoints() > 0) {
496 Standard_Real dmin = proj.LowerDistance();
497 if(myTotalDist > dmin) {
499 myTotalPoints[0] = proj.NearestPoint();
500 myTotalPars[0] = proj.LowerDistanceParameter();
501 myTotalPoints[1] = P22;
502 myTotalPars[1] = u22;