bool CRhGetPolylineSegment::CalculatePolylineSegment( const ON_3dPoint& pt, int& index0, int& index1 )
{
    if( 0 == m_curve )
        return false;

    index0 = index1 = -1;

    double t = 0.0;
    if( m_curve->GetClosestPoint(pt, &t) )
    {
        int count = m_curve->m_t.Count();
        index0 = ON_SearchMonotoneArray( m_curve->m_t, count, t );
        if( index0 >= 0 && index0 <= count - 1 )
        {
            if( index0 == count - 1 )
            {
                if( m_curve->IsClosed() )
                    index1 = 0;
                else
                {
                    index0 = count - 2;
                    index1 = count - 1;
                }
            }
            else
                index1 = m_index0 + 1;
            return true;
        }
    }

    return false;
}
Example #2
0
int ON_NurbsSpanIndex(
          int order,          // (>=2)
          int cv_count,
          const double* knot, // knot[] array or length ON_KnotCount(order,cv_count)
          double t,           // evaluation parameter
          int side,           // side 0 = default, -1 = from below, +1 = from above
          int hint            // hint (or 0 if no hint available)
          )
{
  int j, len;
  
  // shift knot so that domain is knot[0] to knot[len]
  knot += (order-2);
  len = cv_count-order+2;
  
  // see if hint helps 
  if (hint > 0 && hint < len-1) {
    while(hint > 0 && knot[hint-1] == knot[hint]) hint--;
    if (hint > 0) {
      // have knot[hint-1] < knot[hint]
      if (t < knot[hint]) {
        len = hint+1;
        hint = 0;
      }
      else {
        if (side < 0 && t == knot[hint]) 
          hint--;
        knot += hint;
        len -= hint;
      }
    }
  }
  else
    hint = 0;
  
  j = ON_SearchMonotoneArray(knot,len,t);
  if (j < 0)
    j = 0;
  else if (j >= len-1)
    j = len-2;
  else if (side < 0) {
    // if user wants limit from below and t = an internal knot,
    // back up to prevous span
    while(j > 0 && t == knot[j]) 
      j--;
  }
  return (j + hint);
}
ON_BOOL32
ON_LocalZero1::BracketSpan( double s0, double f0, double s1, double f1 )
{
  int i0, i1, i;
  double fm, fp;
  ON_BOOL32 rc = true;
  if ( m_k && m_k_count >= 3 ) {
    i0 = ON_SearchMonotoneArray(m_k,m_k_count,s0);
    if ( i0 < 0 )
      i0 = 0;
    i1 = ON_SearchMonotoneArray(m_k,m_k_count,s1);
    if ( i1 >= m_k_count )
      i1 = m_k_count-1;
    while ( i1 >= 0 && s1 == m_k[i1] ) {
      i1--;
    }
    i0++;
    while ( i0 < m_k_count-1 && m_k[i0] == m_k[i0+1] )
      i0++;
    if ( i0 <= i1 ) {
      // we have s0 < m_k[i0] <= ... <= m_k[i1] < s1
      Evaluate( m_k[i0], &fm, NULL,-1 ); // gaurd against C0 discontinuities
      Evaluate( m_k[i0], &fp, NULL, 1 );
      if ( (f0 <= 0.0 && fm >= 0.0) || (f0 >= 0.0 && fm <= 0.0) ) {
        m_s1 = m_k[i0];
        m_f1 = fm;
      }
      else if ( (f1 <= 0.0 && fp >= 0.0) || (f1 >= 0.0 && fp <= 0.0) ) {
        m_s0 = m_k[i0];
        m_f0 = fp;
        if ( i0 < i1 ) {
          Evaluate( m_k[i1], &fm, NULL, -1 );
          Evaluate( m_k[i1], &fp, NULL,  1 );
          if ( (f1 <= 0.0 && fp >= 0.0) || (f1 >= 0.0 && fp <= 0.0) ) {
            m_s0 = m_k[i1];
            m_f0 = fp;
          }
          else if ( (f0 <= 0.0 && fm >= 0.0) || (f0 >= 0.0 && fm <= 0.0) ) {
            m_s1 = m_k[i1];
            m_f1 = fm;
            // we have s0 = m_k[i0] < m_k[i1] = s1 and a bonafide sign change
            while (i0+1 < i1) {
              // bisect m_k[i0],...,m_k[i1] until we get a sign change between
              // m_k[i],m_k[i+1].  We need to do this in order to make sure
              // we are passing a C2 function to the repeated zero finders.
              i = (i0+i1)>>1;
              Evaluate( m_k[i], &fm, NULL, -1 );
              Evaluate( m_k[i], &fp, NULL,  1 );
              if ( (f0 <= 0.0 && fm >= 0.0) || (f0 >= 0.0 && fm <= 0.0) ) {
                m_s1 = m_k[i];
                m_f1 = fm;
                i1 = i;
                while ( i1>0 && m_k[i1-1]==m_k[i1])
                  i1--;
              }
              else if ( (f1 <= 0.0 && fp >= 0.0) || (f1 >= 0.0 && fp <= 0.0) ) {
                m_s0 = m_k[i];
                m_f0 = fp;
                i0 = i;
                while ( i0 < m_k_count-2 && m_k[i0] == m_k[i0+1] )
                  i0++;
              }
              else {
                // discontinuous sign change across m_k[i]
                rc = false;
                break;
              }
            }
          }