ON_3dVector ON_Ellipse::CurvatureAt( double t // parameter ) const { ON_3dVector T, K; ON_EvCurvature(DerivativeAt( 1, t ),DerivativeAt( 2, t ),T,K); return K; }
bool ON_Surface::GetNextDiscontinuity( int dir, ON::continuity c, double t0, double t1, double* t, int* hint, int* dtype, double cos_angle_tolerance, double curvature_tolerance ) const { // 28 Jan 2005 - untested code // this function must be overridden by surface objects that // can have parametric discontinuities on the interior of the curve. bool rc = false; // using tmp_dtype means I don't have to keep checking for a null dtype; int tmp_dtype = 0; if ( !dtype ) dtype = &tmp_dtype; *dtype = 0; if ( t0 != t1 ) { bool bTestC0 = false; bool bTestD1 = false; bool bTestD2 = false; bool bTestT = false; bool bTestK = false; switch(c) { case ON::C0_locus_continuous: bTestC0 = true; break; case ON::C1_locus_continuous: bTestC0 = true; bTestD1 = true; break; case ON::C2_locus_continuous: bTestC0 = true; bTestD1 = true; bTestD2 = true; break; case ON::G1_locus_continuous: bTestC0 = true; bTestT = true; break; case ON::G2_locus_continuous: bTestC0 = true; bTestT = true; bTestK = true; break; default: // other values ignored on purpose. break; } if ( bTestC0 ) { // 20 March 2003 Dale Lear: // Have to look for locus discontinuities at ends. // Must test both ends becuase t0 > t1 is valid input. // In particular, for ON_CurveProxy::GetNextDiscontinuity() // to work correctly on reversed "real" curves, the // t0 > t1 must work right. int hinta[2], hintb[2], span_index, j; ON_Interval domain = Domain(dir); ON_Interval span_domain; ON_2dPoint st0, st1; ON_3dVector Da[6], Db[6]; ON_3dVector& D1a = Da[1+dir]; ON_3dVector& D1b = Db[1+dir]; ON_3dVector& D2a = Da[3+2*dir]; ON_3dVector& D2b = Db[3+2*dir]; if ( t0 < domain[1] && t1 >= domain[1] ) t1 = domain[1]; else if ( t0 > domain[0] && t1 <= domain[0] ) t1 = domain[0]; if ( (t0 < domain[1] && t1 >= domain[1]) || (t0 > domain[0] && t1 <= domain[0]) ) { if ( IsClosed(dir) ) { int span_count = SpanCount(1-dir); double* span_vector = (span_count>0) ? ((double*)onmalloc((span_count+1)*sizeof(*span_vector))) : 0; if (!GetSpanVector(1-dir,span_vector)) span_count = 0; st0[dir] = domain[0]; st1[dir] = domain[1]; for ( span_index = 0; span_index < span_count && 1 != *dtype; span_index++ ) { span_domain.Set(span_vector[span_index],span_vector[span_index+1]); for ( j = (span_index?1:0); j <= 2 && 1 != *dtype; j++ ) { st0[1-dir] = span_domain.ParameterAt(0.5*j); st1[1-dir] = st0[1-dir]; if ( bTestD1 || bTestT ) { // need to check locus continuity at start/end of closed surface. if ( Evaluate(st0.x,st0.y,2,3,&Da[0].x,1,hinta) && Evaluate(st1.x,st1.y,2,3,&Db[0].x,2,hintb) ) { if ( bTestD1 ) { if ( !(D1a-D1b).IsTiny(D1b.MaximumCoordinate()*ON_SQRT_EPSILON ) ) { if ( dtype ) *dtype = 1; *t = t1; rc = true; } else if ( bTestD2 && !(D2a-D2b).IsTiny(D2b.MaximumCoordinate()*ON_SQRT_EPSILON) ) { if ( dtype ) *dtype = 2; *t = t1; rc = true; } } else if ( bTestT ) { ON_3dVector Ta, Tb, Ka, Kb; ON_EvCurvature( D1a, D2a, Ta, Ka ); ON_EvCurvature( D1b, D2b, Tb, Kb ); if ( Ta*Tb < cos_angle_tolerance ) { if ( dtype ) *dtype = 1; *t = t1; rc = true; } else if ( bTestK && (Ka-Kb).Length() > curvature_tolerance ) { if ( dtype ) *dtype = 2; *t = t1; rc = true; } } } } } } if ( span_vector) { onfree(span_vector); } } else { // open curves are not locus continuous at ends. *dtype = 0; // locus C0 discontinuity *t = t1; rc = true; } } } } return rc; }