ON_BOOL32 ON_CurveProxy::GetNormalizedArcLengthPoints( int count, const double* s, double* t, double absolute_tolerance , double fractional_tolerance , const ON_Interval* sub_domain ) const { // 23 July 2004 Dale Lear: // Fixed a bug so this would work right when m_bReversed = true int i, j; if ( !m_real_curve ) return false; if( count<0) return false; ON_Interval scratch_domain = RealCurveInterval( sub_domain ); ON_SimpleArray<double> ss; if( m_bReversed) { ss.Reserve(count); ss.SetCount(count); for(i=0, j = count-1; i<count; i++, j--) { ss[i] = 1.0-s[j]; } s = ss.Array(); } ON_BOOL32 rc = m_real_curve->GetNormalizedArcLengthPoints(count, s, t , absolute_tolerance, fractional_tolerance, &scratch_domain); if( rc) { for(i=0;i<count; i++) { t[i] = ThisCurveParameter( t[i]); } if ( m_bReversed ) { double x; for (i = 0, j = count-1; i < j; i++, j-- ) { x = t[i]; t[i] = t[j]; t[j] = x; } } } return rc; }
ON_BOOL32 ON_CurveProxy::GetLength( double* length, // length returned here double fractional_tolerance, // default = 1.0e-8 const ON_Interval* sub_domain // default = NULL ) const { if ( length ) *length = 0; if ( !m_real_curve || m_real_curve == this ) return false; ON_Interval scratch_domain = RealCurveInterval( sub_domain ); return m_real_curve->GetLength( length, fractional_tolerance, &scratch_domain ); }
bool ON_CurveProxy::GetClosestPoint( const ON_3dPoint& test_point, double* t, // parameter of global closest point returned here double maximum_distance, const ON_Interval* sub_domain ) const { bool rc = false; if ( m_real_curve ) { ON_Interval scratch_domain = RealCurveInterval( sub_domain ); rc = m_real_curve->GetClosestPoint( test_point, t, maximum_distance, &scratch_domain ); if ( rc ) *t = ThisCurveParameter(*t); } return rc; }
ON_BOOL32 ON_CurveProxy::GetLocalClosestPoint( const ON_3dPoint& test_point, double seed_parameter, double* t, const ON_Interval* sub_domain ) const { ON_BOOL32 rc = false; if ( m_real_curve ) { ON_Interval scratch_domain = RealCurveInterval( sub_domain ); double sp = RealCurveParameter(seed_parameter); rc = m_real_curve->GetLocalClosestPoint( test_point, sp, t, &scratch_domain ); if ( rc && t ) *t = ThisCurveParameter(*t); } return rc; }
ON_BOOL32 ON_CurveProxy::Trim( const ON_Interval& domain ) { bool rc = false; if ( m_this_domain.IsIncreasing() && m_real_curve_domain.IsIncreasing() ) { ON_Interval trim_dom = m_this_domain; trim_dom.Intersection(domain); if ( trim_dom.IsIncreasing() ) { ON_Interval real_dom = RealCurveInterval( &trim_dom ); if ( real_dom.IsIncreasing() ) { m_real_curve_domain = real_dom; m_this_domain = trim_dom; rc = true; } } } return rc; }
ON_BOOL32 ON_CurveProxy::GetNormalizedArcLengthPoint( double s, double* t, double fractional_tolerance, const ON_Interval* sub_domain ) const { if ( !m_real_curve ) return false; if ( s<0.0 || s>1.0) return false; ON_Interval scratch_domain = RealCurveInterval( sub_domain ); if( m_bReversed) s = 1-s; ON_BOOL32 rc = m_real_curve->GetNormalizedArcLengthPoint(s, t , fractional_tolerance, &scratch_domain); if( rc){ *t = ThisCurveParameter( *t); } return rc; }
int ON_CurveProxy::GetNurbForm( // returns 0: unable to create NURBS representation // with desired accuracy. // 1: success - returned NURBS parameterization // matches the curve's to wthe desired accuracy // 2: success - returned NURBS point locus matches // the curve's to the desired accuracy but, on // the interior of the curve's domain, the // curve's parameterization and the NURBS // parameterization may not match to the // desired accuracy. ON_NurbsCurve& nurbs, double tolerance, // (>=0) const ON_Interval* sub_domain // OPTIONAL subdomain of ON::ProxyCurve::Domain() ) const { ON_BOOL32 rc = false; if ( m_real_curve ) { ON_Interval scratch_domain = RealCurveInterval( sub_domain ); rc = m_real_curve->GetNurbForm(nurbs,tolerance,&scratch_domain); if ( rc ) { if ( m_bReversed ) nurbs.Reverse(); ON_Interval d = m_this_domain; if ( sub_domain ) d.Intersection( *sub_domain ); nurbs.SetDomain( d[0], d[1] ); if ( nurbs.m_dim <= 3 && nurbs.m_dim >= 1 ) { double t0 = Domain()[0]; double t1 = Domain()[1]; if ( 0 != sub_domain ) { if ( t0 < sub_domain->Min() ) t0 = sub_domain->Min(); if ( sub_domain->Max() < t1 ) t1 = sub_domain->Max(); } // set ends of NURBS curve to be exactly on ends of proxy curve ON_3dPoint P0 = PointAt(t0); ON_3dPoint P1 = PointAt(t1); ON_3dPoint N0 = nurbs.PointAtStart(); ON_3dPoint N1 = nurbs.PointAtEnd(); // 22 September 2003, GBA. The end tuning code below should only be applied // to clamped nurbs curves. In particular it should not be used on // periodic nurbs curves. Fixes TRR#11502. ON_BOOL32 clamped = nurbs.IsClamped(2); if ( clamped && (P0 != N0 || P1 != N1) ) { if ( 0==nurbs.m_is_rat ) { nurbs.SetCV(0,P0); nurbs.SetCV(nurbs.m_cv_count-1,P1); } else { ON_4dPoint H0, H1; H0 = P0; H0.w = nurbs.Weight(0); H0.x *= H0.w; H0.y *= H0.w; H0.z *= H0.w; nurbs.SetCV(0,H0); H1 = P1; H1.w = nurbs.Weight(nurbs.m_cv_count-1); H1.x *= H1.w; H1.y *= H1.w; H1.z *= H1.w; nurbs.SetCV(nurbs.m_cv_count-1,H1); } } } } } return rc; }