119 template<
typename ContainerT>
128 template<
typename ContainerT,
typename TransformFunc>
129 PointCurve(
const ContainerT& container, TransformFunc func );
135 void reserve(
size_t capacity );
155 template<
typename T2>
156 void add(
const T2& point );
207 agx::UInt maxNumIterations = 100ul )
const;
226 template<
typename ContainerT>
229 m_points.resize( container.size() );
230 for (
agx::UInt i = 0; i < m_points.size(); ++i )
235 template<
typename ContainerT,
typename TransformFunc>
238 m_points.resize( container.size() );
239 std::transform( container.begin(), container.end(), m_points.begin(), func );
245 m_points.reserve( capacity );
255 template<
typename T2>
258 if ( !m_time.empty() )
267 if ( m_points.size() < 2 ) {
272 if ( m_points.size() != m_time.size() ) {
278 auto index = findIndex( time );
280 if ( index + 1 == m_points.size() ) {
286 segment.begin = m_points[ index ];
287 segment.end = m_points[ index + 1 ];
289 segment.localTime = ( time - m_time[ index ] ) / ( m_time[ index + 1 ] - m_time[ index ] );
299 for (
agx::UInt i = 1; i < m_points.size(); ++i )
308 m_time.resize( m_points.size(),
agx::Real( 0 ) );
310 const auto totalLength = calculateLength();
315 m_time.front() = accumulatedTime;
316 for (
agx::UInt i = 1; i < m_points.size(); ++i ) {
317 accumulatedTime += ((
agx::Vec3)m_points[ i - 1 ]).distance( (
agx::Vec3)m_points[ i ] ) / totalLength;
318 m_time[ i ] = accumulatedTime;
322 return m_time.size() > 1;
328 for (
agx::UInt i = 0; i < m_points.size(); ++i )
329 callback( m_points[ i ] );
337 for (
agx::UInt i = 1; i < m_points.size(); ++i )
338 callback( Segment{ m_points[ i - 1 ], m_points[ i ] },
341 i + 1 == m_points.size() ?
351 const auto totalLength = calculateLength();
355 const agx::Real dt = segmentLength / totalLength;
358 auto prev = evaluate( prevT );
362 auto curr = evaluate( currT );
363 agx::Real prevToCurrDist = prev.point.distance( curr.point );
364 while ( !
agx::equivalent( prevToCurrDist, segmentLength, tolerance ) ) {
365 const agx::Real overshoot = prevToCurrDist - segmentLength;
366 currT -= overshoot / totalLength;
367 curr = evaluate( currT );
368 prevToCurrDist = prev.point.distance( curr.point );
374 curr.point.distance( (
agx::Vec3)m_points.back() ) <
agx::Real( 0.5 ) * segmentLength );
379 callback( prev, curr, type );
398 if ( numSegments < 1 )
401 const auto totalLength = calculateLength();
410 const auto& self = *
this;
420 ePrev += errorFunction( self, p1, p2, type );
425 eCurr += errorFunction( self, p1, p2, type );
430 eNext += errorFunction( self, p1, p2, type );
433 if ( eCurr < bestResult.
error ) {
435 bestResult.
error = eCurr;
449 result.
error += errorFunction( self, p1, p2, type );
452 done = std::abs( result.
error ) <= maxError;
464 return std::max( m_points.size(), (
typename container_type::size_type)1 ) - 1;
466 auto it = std::lower_bound( m_time.begin(), m_time.end(), time );
470 return it - m_time.begin() - 1;
Utility class curve defined by a set of points.
std::function< void(value_type &)> TransformCallback
std::function< void(const SegmentPoint &, const SegmentPoint &, SegmentType)> SegmentPointCallback
void reserve(size_t capacity)
Reserves containers to given capacity.
agx::Bool finalize()
When all points has been added this method has to be called to collect curve data for efficient manip...
std::function< void(const Segment &, SegmentType)> SegmentCallback
SegmentPoint evaluate(agx::Real time) const
Evaluate at given time.
void add(const T2 &point)
Add new point to this curve.
void transform(TransformCallback callback)
Transform points in this curve.
std::function< agx::Real(const PointCurve &, const SegmentPoint &, const SegmentPoint &, SegmentType)> SegmentationErrorCallback
void traverse(SegmentCallback callback) const
Traverse all segments.
PointCurve()
Default constructor.
const container_type & getPoints() const
void traverse(SegmentPointCallback callback, agx::Real segmentLength, agx::Real tolerance=agx::Real(1.0E-6)) const
Traverses this curve and invokes callback with a segment of a given segment length.
agx::Real calculateLength() const
SegmentationResult findSegmentLength(agx::UInt numSegments, SegmentationErrorCallback errorFunction, agx::Real maxError, agx::Real segmentLengthTolerance=agx::Real(1.0E-6), agx::UInt maxNumIterations=100ul) const
Uses Newton Raphson to minimize the error while dividing this curve into segments.
The agxUtil namespace contain classes and methods for utility functionality.
The agx namespace contains the dynamics/math part of the AGX Dynamics API.
Vec3T< Real > Vec3
The object holding 3 dimensional vectors and providing basic arithmetic.
bool geq(double a, double b, double eps=(double) AGX_EQUIVALENT_EPSILON)
AGXCORE_EXPORT const Real REAL_SQRT_EPSILON
AGXCORE_EXPORT const Real RealEpsilon
bool leq(double a, double b, double eps=(double) AGX_EQUIVALENT_EPSILON)
AGXPHYSICS_EXPORT agx::Bool equivalent(const agx::AddedMassInteraction::Matrix6x6 &lhs, const agx::AddedMassInteraction::Matrix6x6 &rhs, agx::Real eps=agx::RealEpsilon)
Segment point with current curve segment and a point on that segment with local and global time.
agx::Real localTime
The point's local time on the curve.
agx::Bool isValid() const
agx::Real time
The point's global time on the curve.
agx::Vec3 point
Point on segment.
Segment data with begin and end point.
Result data of segmentation, PointCurve::findSegmentLength.
SegmentationResult(agx::UInt numSegments)