Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-17 09:20:16

0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014 
0015 #ifndef _Extrema_GCurveLocator_HeaderFile
0016 #define _Extrema_GCurveLocator_HeaderFile
0017 
0018 #include <Standard.hxx>
0019 #include <Standard_Real.hxx>
0020 #include <Standard_DefineAlloc.hxx>
0021 #include <Standard_OutOfRange.hxx>
0022 
0023 #include <cmath>
0024 
0025 //! Template class for locating the closest point on a curve to a given point.
0026 //! Among a set of sampled points on the curve, finds the one closest to the target.
0027 //!
0028 //! @tparam TheCurve the curve type
0029 //! @tparam TheCurveTool the curve tool providing curve operations
0030 //! @tparam ThePOnC the point-on-curve type
0031 //! @tparam ThePoint the point type (gp_Pnt or gp_Pnt2d)
0032 template <typename TheCurve, typename TheCurveTool, typename ThePOnC, typename ThePoint>
0033 class Extrema_GCurveLocator
0034 {
0035 public:
0036   DEFINE_STANDARD_ALLOC
0037 
0038   //! Among a set of points {C(ui), i=1,NbU}, locate the point
0039   //! P=C(uj) such that:
0040   //! distance(P,C) = Min{distance(P,C(ui))}
0041   //! @param theP the target point
0042   //! @param theC the curve to sample
0043   //! @param theNbU the number of sample points
0044   //! @param thePapp the result point on curve
0045   static void Locate(const ThePoint& theP, const TheCurve& theC, const int theNbU, ThePOnC& thePapp)
0046   {
0047     if (theNbU < 2)
0048     {
0049       throw Standard_OutOfRange();
0050     }
0051 
0052     double   aU        = TheCurveTool::FirstParameter(theC);
0053     double   aPasU     = (TheCurveTool::LastParameter(theC) - aU) / (theNbU - 1);
0054     double   aDist2Min = RealLast();
0055     double   aUMin     = 0;
0056     ThePoint aPntMin;
0057     double   aDist2;
0058     ThePoint aPt;
0059 
0060     for (int aNoSample = 1; aNoSample < theNbU; aNoSample++, aU += aPasU)
0061     {
0062       aPt    = TheCurveTool::Value(theC, aU);
0063       aDist2 = aPt.SquareDistance(theP);
0064       if (aDist2 < aDist2Min)
0065       {
0066         aDist2Min = aDist2;
0067         aUMin     = aU;
0068         aPntMin   = aPt;
0069       }
0070     }
0071     thePapp.SetValues(aUMin, aPntMin);
0072   }
0073 
0074   //! Among a set of points {C(ui), i=1,NbU}, locate the point
0075   //! P=C(uj) such that:
0076   //! distance(P,C) = Min{distance(P,C(ui))}
0077   //! The search is done between theUmin and theUsup.
0078   //! @param theP the target point
0079   //! @param theC the curve to sample
0080   //! @param theNbU the number of sample points
0081   //! @param theUmin the minimum parameter value
0082   //! @param theUsup the maximum parameter value
0083   //! @param thePapp the result point on curve
0084   static void Locate(const ThePoint& theP,
0085                      const TheCurve& theC,
0086                      const int       theNbU,
0087                      const double    theUmin,
0088                      const double    theUsup,
0089                      ThePOnC&        thePapp)
0090   {
0091     if (theNbU < 2)
0092     {
0093       throw Standard_OutOfRange();
0094     }
0095 
0096     double aUinf  = TheCurveTool::FirstParameter(theC);
0097     double aUlast = TheCurveTool::LastParameter(theC);
0098 
0099     double aU1  = std::min(aUinf, aUlast);
0100     double aU2  = std::max(aUinf, aUlast);
0101     double aU11 = std::min(theUmin, theUsup);
0102     double aU12 = std::max(theUmin, theUsup);
0103 
0104     if (aU11 < aU1 - RealEpsilon())
0105       aU11 = aU1;
0106     if (aU12 > aU2 + RealEpsilon())
0107       aU12 = aU2;
0108 
0109     double   aU        = aU11;
0110     double   aPasU     = (aU12 - aU) / (theNbU - 1);
0111     double   aDist2Min = RealLast();
0112     double   aUMin     = 0;
0113     ThePoint aPntMin;
0114     double   aDist2;
0115     ThePoint aPt;
0116 
0117     for (int aNoSample = 1; aNoSample < theNbU; aNoSample++, aU += aPasU)
0118     {
0119       aPt    = TheCurveTool::Value(theC, aU);
0120       aDist2 = aPt.SquareDistance(theP);
0121       if (aDist2 < aDist2Min)
0122       {
0123         aDist2Min = aDist2;
0124         aUMin     = aU;
0125         aPntMin   = aPt;
0126       }
0127     }
0128     thePapp.SetValues(aUMin, aPntMin);
0129   }
0130 };
0131 
0132 #endif // _Extrema_GCurveLocator_HeaderFile