114 template<
typename ContainerT>
123 template<
typename ContainerT,
typename TransformFunc>
124 PointCurve(
const ContainerT& container, TransformFunc func );
139 template<
typename T2>
140 void add(
const T2& point );
191 agx::UInt maxNumIterations = 100ul )
const;
210 template<
typename ContainerT>
213 m_points.resize( container.size() );
214 for (
agx::UInt i = 0; i < m_points.size(); ++i )
219 template<
typename ContainerT,
typename TransformFunc>
222 m_points.resize( container.size() );
223 std::transform( container.begin(), container.end(), m_points.begin(), func );
227 template<
typename T2>
230 if ( !m_time.empty() )
239 if ( m_points.size() < 2 ) {
244 if ( m_points.size() != m_time.size() ) {
250 auto index = findIndex( time );
252 if ( index + 1 == m_points.size() ) {
258 segment.begin = m_points[ index ];
259 segment.end = m_points[ index + 1 ];
261 segment.localTime = ( time - m_time[ index ] ) / ( m_time[ index + 1 ] - m_time[ index ] );
271 for (
agx::UInt i = 1; i < m_points.size(); ++i )
280 m_time.resize( m_points.size(),
agx::Real( 0 ) );
282 const auto totalLength = calculateLength();
287 m_time.front() = accumulatedTime;
288 for (
agx::UInt i = 1; i < m_points.size(); ++i ) {
289 accumulatedTime += ((
agx::Vec3)m_points[ i - 1 ]).distance( (
agx::Vec3)m_points[ i ] ) / totalLength;
290 m_time[ i ] = accumulatedTime;
294 return m_time.size() > 1;
300 for (
agx::UInt i = 0; i < m_points.size(); ++i )
301 callback( m_points[ i ] );
309 for (
agx::UInt i = 1; i < m_points.size(); ++i )
310 callback( Segment{ m_points[ i - 1 ], m_points[ i ] },
313 i + 1 == m_points.size() ?
323 const auto totalLength = calculateLength();
327 const agx::Real dt = segmentLength / totalLength;
330 auto prev = evaluate( prevT );
334 auto curr = evaluate( currT );
335 agx::Real prevToCurrDist = prev.point.distance( curr.point );
336 while ( !
agx::equivalent( prevToCurrDist, segmentLength, tolerance ) ) {
337 const agx::Real overshoot = prevToCurrDist - segmentLength;
338 currT -= overshoot / totalLength;
339 curr = evaluate( currT );
340 prevToCurrDist = prev.point.distance( curr.point );
346 curr.point.distance( (
agx::Vec3)m_points.back() ) <
agx::Real( 0.5 ) * segmentLength );
351 callback( prev, curr, type );
370 if ( numSegments < 1 )
373 const auto totalLength = calculateLength();
382 const auto& self = *
this;
392 ePrev += errorFunction( self, p1, p2, type );
397 eCurr += errorFunction( self, p1, p2, type );
402 eNext += errorFunction( self, p1, p2, type );
405 if ( eCurr < bestResult.
error ) {
407 bestResult.
error = eCurr;
421 result.
error += errorFunction( self, p1, p2, type );
424 done = std::abs( result.
error ) <= maxError;
436 return std::max( m_points.size(), (
typename container_type::size_type)1 ) - 1;
438 auto it = std::lower_bound( m_time.begin(), m_time.end(), time );
442 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
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.
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)