ON_3dVector ON_Polyline::SegmentDirection( int segment_index ) const { ON_3dVector v; if ( segment_index >= 0 && segment_index < m_count-1 ) { v = m_a[segment_index+1] - m_a[segment_index]; } else { v.Zero(); } return v; }
ON_BOOL32 ON_Surface::EvNormal( // returns false if unable to evaluate double s, double t, // evaluation parameters (s,t) ON_3dPoint& point, // returns value of surface ON_3dVector& ds, // first partial derivatives (Ds) ON_3dVector& dt, // (Dt) ON_3dVector& normal, // unit normal int side, // optional - determines which side to evaluate from // 0 = default // 1 from NE quadrant // 2 from NW quadrant // 3 from SW quadrant // 4 from SE quadrant int* hint // optional - evaluation hint (int[2]) used to speed // repeated evaluations ) const { // simple cross product normal - override to support singular surfaces ON_BOOL32 rc = Ev1Der( s, t, point, ds, dt, side, hint ); if ( rc ) { const double len_ds = ds.Length(); const double len_dt = dt.Length(); // do not reduce the tolerance used here - there is a retry in the code // below. if ( len_ds > ON_SQRT_EPSILON*len_dt && len_dt > ON_SQRT_EPSILON*len_ds ) { ON_3dVector a = ds/len_ds; ON_3dVector b = dt/len_dt; normal = ON_CrossProduct( a, b ); rc = normal.Unitize(); } else { // see if we have a singular point double v[6][3]; int normal_side = side; ON_BOOL32 bOnSide = false; ON_Interval sdom = Domain(0); ON_Interval tdom = Domain(1); if (s == sdom.Min()) { normal_side = (normal_side >= 3) ? 4 : 1; bOnSide = true; } else if (s == sdom.Max()) { normal_side = (normal_side >= 3) ? 3 : 2; bOnSide = true; } if (t == tdom.Min()) { normal_side = (normal_side == 2 || normal_side == 3) ? 2 : 1; bOnSide = true; } else if (t == tdom.Max()) { normal_side = (normal_side == 2 || normal_side == 3) ? 3 : 4; bOnSide = true; } if ( !bOnSide ) { // 2004 November 11 Dale Lear // Added a retry again with a more generous tolerance if ( len_ds > ON_EPSILON*len_dt && len_dt > ON_EPSILON*len_ds ) { ON_3dVector a = ds/len_ds; ON_3dVector b = dt/len_dt; normal = ON_CrossProduct( a, b ); rc = normal.Unitize(); } else { rc = false; } } else { rc = Evaluate( s, t, 2, 3, &v[0][0], normal_side, hint ); if ( rc ) { rc = ON_EvNormal( normal_side, v[1], v[2], v[3], v[4], v[5], normal); } } } } if ( !rc ) { normal.Zero(); } return rc; }