OpenCascade BSpline Curve

5179 단어
//=======================================================================
//function : LocalValue
//purpose  : 
//=======================================================================

gp_Pnt Geom_BSplineCurve::LocalValue
  (const Standard_Real    U,
   const Standard_Integer FromK1,
   const Standard_Integer ToK2)   const
{
  gp_Pnt P;
  LocalD0(U,FromK1,ToK2,P);
  return P;
}

//=======================================================================
//function : LocalD0
//purpose  : 
//=======================================================================

void  Geom_BSplineCurve::LocalD0
  (const Standard_Real    U,
   const Standard_Integer FromK1,
   const Standard_Integer ToK2,
   gp_Pnt& P)   const
{
  Standard_DomainError_Raise_if (FromK1 == ToK2,
				 "Geom_BSplineCurve::LocalValue");

  Standard_Real u = U;
  Standard_Integer index = 0;
  BSplCLib::LocateParameter(deg, FKNOTS, U, periodic,FromK1,ToK2, index,u);
  index = BSplCLib::FlatIndex(deg,index,mults->Array1(),periodic);
  if (rational) {
    BSplCLib::D0(u,index,deg,periodic,POLES,
		 weights->Array1(),
		 FKNOTS,FMULTS,P);
  }
  else {
    BSplCLib::D0(u,index,deg,periodic,POLES,
		 *((TColStd_Array1OfReal*) NULL),
		 FKNOTS,FMULTS,P);
  }
}

 
//=======================================================================
//function : LocateParameter
//purpose  : Pour des noeuds plats
//   pmn  28-01-97 -> On a bel est bien besoin du degree pour calculer
//   la periode eventuelle
//=======================================================================

void BSplCLib::LocateParameter
(const Standard_Integer          Degree,
 const Array1OfReal&    Knots,
 const Standard_Real             U,
 const Standard_Boolean          IsPeriodic,
 const Standard_Integer          FromK1,
 const Standard_Integer          ToK2,
 Standard_Integer&               KnotIndex,
 Standard_Real&                  NewU)
{ 
  if (IsPeriodic)
    BSplCLib::LocateParameter(Knots, U, IsPeriodic, FromK1, ToK2,
			      KnotIndex, NewU,
			      Knots(Knots.Lower() + Degree),
			      Knots(Knots.Upper() - Degree));
  else 
    BSplCLib::LocateParameter(Knots, U, IsPeriodic, FromK1, ToK2,
			      KnotIndex, NewU,
			      0.,
			      1.);
}

 
//=======================================================================
//function : LocateParameter
//purpose  : Claculs effectifs
// pmn 28-01-97 : Ajoute les bornes de la periode en argument d'entree, car il est 
//                car il est imposible de les inventer a ce niveaux.
//=======================================================================

void BSplCLib::LocateParameter 
(const TColStd_Array1OfReal& Knots,
 const Standard_Real         U,
 const Standard_Boolean      IsPeriodic,
 const Standard_Integer      FromK1,
 const Standard_Integer      ToK2,
 Standard_Integer&           KnotIndex,
 Standard_Real&              NewU,
 const Standard_Real         UFirst,
 const Standard_Real         ULast)
{
  Standard_Integer First,Last;
  if (FromK1 < ToK2) {
    First = FromK1;
    Last  = ToK2;
  }
  else {
    First = ToK2;
    Last  = FromK1;
  }
  Standard_Integer Last1 = Last - 1;
  NewU = U;
  if (IsPeriodic) {
    Standard_Real Period = ULast - UFirst;

    while (NewU > ULast )
      NewU  -= Period;

    while (NewU < UFirst)
      NewU  += Period;
  }
  
  BSplCLib::Hunt (Knots, NewU, KnotIndex);
  
  Standard_Real Eps = Epsilon(U);
  Standard_Real val;
  if (Eps < 0) Eps = - Eps;
  Standard_Integer KLower = Knots.Lower();
  const Standard_Real *knots = &Knots(KLower);
  knots -= KLower;
  if ( KnotIndex < Knots.Upper()) {
    val = NewU - knots[KnotIndex + 1];
    if (val < 0) val = - val;
    // <= pour etre coherant avec les Segment ou Eps correspond a un bit d'erreur.
    if (val <= Eps) KnotIndex++; 
  }
  if (KnotIndex < First) KnotIndex = First;
  if (KnotIndex > Last1) KnotIndex = Last1;
  
  if (KnotIndex != Last1) {
    Standard_Real K1 = knots[KnotIndex];
    Standard_Real K2 = knots[KnotIndex + 1];
    val = K2 - K1;
    if (val < 0) val = - val;

    while (val <= Eps) {
      KnotIndex++;
      K1 = K2;
      K2 = knots[KnotIndex + 1];
      val = K2 - K1;
      if (val < 0) val = - val;
    }
  }
}

 
//=======================================================================
//function : Hunt
//purpose  : 
//=======================================================================

void BSplCLib::Hunt (const Array1OfReal& XX, 
		     const Standard_Real X,
		     Standard_Integer&   Ilc)
{
  // replaced by simple dichotomy (RLE)
  Ilc = XX.Lower();
  const Standard_Real *px = &XX(Ilc);
  px -= Ilc;

  if (X < px[Ilc]) {
    Ilc--;
    return;
  }
  Standard_Integer Ihi = XX.Upper();
  if (X > px[Ihi]) {
    Ilc = Ihi + 1;
    return;
  }
  Standard_Integer Im;

  while (Ihi - Ilc != 1) {
    Im = (Ihi + Ilc) >> 1;
    if (X > px[Im]) Ilc = Im;
    else            Ihi = Im;
  }
}

 
 

좋은 웹페이지 즐겨찾기