29 #include <boost/math/special_functions/cbrt.hpp>
30 #include <boost/math/constants/constants.hpp>
36 template<
typename C,
typename Traits>
48 template<
typename C,
typename Traits>
51 : m_position(p), m_input_direction(p), m_output_direction(p)
65 template<
typename C,
typename Traits>
69 : m_position(p), m_input_direction(input_direction),
70 m_output_direction(output_direction)
79 template<
typename C,
typename Traits>
91 template<
typename C,
typename Traits>
95 return m_input_direction;
103 template<
typename C,
typename Traits>
107 return m_output_direction;
121 template<
typename C,
typename Traits>
124 : m_position(position), m_section(s), m_date(t)
133 template<
typename C,
typename Traits>
145 template<
typename C,
typename Traits>
156 template<
typename C,
typename Traits>
174 template<
typename C,
typename Traits>
177 : m_origin(origin), m_end(end)
187 template<
typename C,
typename Traits>
191 if ( m_origin == m_end )
192 return m_origin->get_position();
196 ( t, traits_type::get_x(m_origin->get_position()),
197 traits_type::get_x(m_origin->get_output_direction()),
198 traits_type::get_x(m_end->get_input_direction()),
199 traits_type::get_x(m_end->get_position()) ) );
202 ( t, traits_type::get_y(m_origin->get_position()),
203 traits_type::get_y(m_origin->get_output_direction()),
204 traits_type::get_y(m_end->get_input_direction()),
205 traits_type::get_y(m_end->get_position()) ) );
207 return traits_type::make_coordinate( x, y );
215 template<
typename C,
typename Traits>
220 ( t, traits_type::get_x(m_origin->get_position()),
221 traits_type::get_x(m_origin->get_output_direction()),
222 traits_type::get_x(m_end->get_input_direction()),
223 traits_type::get_x(m_end->get_position()) );
226 ( t, traits_type::get_y(m_origin->get_position()),
227 traits_type::get_y(m_origin->get_output_direction()),
228 traits_type::get_y(m_end->get_input_direction()),
229 traits_type::get_y(m_end->get_position()) );
232 return traits_type::make_coordinate( 0, (dy < 0) ? -1 : 1 );
234 return traits_type::make_coordinate( 1, dy / dx );
244 template<
typename C,
typename Traits>
245 std::vector<typename claw::math::curve<C, Traits>::section::resolved_point>
249 std::vector<resolved_point> result;
254 const std::vector<double> roots
256 ( x, traits_type::get_x(m_origin->get_position()),
257 traits_type::get_x(m_origin->get_output_direction()),
258 traits_type::get_x(m_end->get_input_direction()),
259 traits_type::get_x(m_end->get_position() ) ) );
261 for ( std::size_t i=0; i!=roots.size(); ++i )
265 ensure_ends_in_points
267 (x == m_origin->get_position().x), (x == m_end->get_position().x) );
270 return extract_domain_points( result );
280 template<
typename C,
typename Traits>
291 template<
typename C,
typename Traits>
294 return m_origin == m_end;
311 template<
typename C,
typename Traits>
317 const double dt(1 - t);
319 return origin * dt * dt * dt
320 + 3 * output_direction * t * dt * dt
321 + 3 * input_direction * t * t * dt
339 template<
typename C,
typename Traits>
345 return - 3 * origin + 3 * output_direction
346 + (6 * origin - 12 * output_direction + 6 * input_direction) * t
347 + (-3 * origin + 9 * output_direction - 9 * input_direction + 3 * end)
365 template<
typename C,
typename Traits>
367 ( std::vector<resolved_point>& p,
bool ensure_origin,
bool ensure_end )
const
369 double min_distance_origin( std::numeric_limits<double>::max() );
370 double min_distance_end( std::numeric_limits<double>::max() );
371 std::size_t origin_index(p.size());
372 std::size_t end_index(p.size());
374 for ( std::size_t i=0; i!=p.size(); ++i )
376 const double distance_origin( std::abs( p[i].get_date() ) );
378 if ( distance_origin <= min_distance_origin )
380 min_distance_origin = distance_origin;
384 const double distance_end( std::abs( 1 - p[i].get_date() ) );
386 if ( distance_end <= min_distance_end )
388 min_distance_end = distance_end;
394 p[origin_index] = resolved_point( m_origin->get_position(), *
this, 0.0 );
397 p[end_index] = resolved_point( m_end->get_position(), *
this, 1.0 );
405 template<
typename C,
typename Traits>
406 std::vector<typename claw::math::curve<C, Traits>::section::resolved_point>
408 (
const std::vector<resolved_point>& p )
const
410 std::vector<resolved_point> clean_result;
412 for ( std::size_t i=0; i!=p.size(); ++i )
413 if ( (p[i].get_date() >= 0) && (p[i].get_date() <= 1) )
433 template<
typename C,
typename Traits>
440 (-origin + 3 * output_direction - 3 * input_direction + end );
441 const value_type b( 3 * origin - 6 * output_direction + 3 * input_direction );
442 const value_type c( -3 * origin + 3 * output_direction );
446 return get_roots_degree_2(b, c, d);
448 return get_roots_degree_3(a, b, c, d);
459 template<
typename C,
typename Traits>
466 std::vector<double> result;
469 result.push_back( - b / ( 2 * a ) );
470 else if ( delta > 0 )
472 result.push_back( (-b - std::sqrt(delta)) / (2 * a) );
473 result.push_back( (-b + std::sqrt(delta)) / (2 * a) );
488 template<
typename C,
typename Traits>
495 const value_type p( -(b * b) / (3.0 * a * a) + c / a );
498 * ( (2.0 * b * b) / (a * a)
502 const value_type delta( q * q + 4.0 * p * p * p / 27.0 );
504 std::vector<double> result;
512 result.push_back( 3.0 * q / p - b / (3.0 * a) );
513 result.push_back( - 3.0 * q / (2.0 * p) - b / (3.0 * a) );
516 else if ( delta > 0 )
520 ( (-q + std::sqrt(delta)) / 2.0 )
522 ( (-q - std::sqrt(delta)) / 2.0 ) - b / (3.0 * a));
525 for ( std::size_t i=0; i!=3; ++i )
527 ( 2.0 * std::sqrt( -p / 3.0 )
529 ( std::acos( std::sqrt(27.0 / (- p * p * p)) * - q / 2.0 ) / 3.0
530 + 2.0 * i * boost::math::constants::pi<double>() / 3.0 )
546 template<
typename C,
typename Traits>
549 m_points.push_back(p);
557 template<
typename C,
typename Traits>
560 m_points.push_front(p);
569 template<
typename C,
typename Traits>
573 m_points.insert( pos, p );
582 template<
typename C,
typename Traits>
604 template<
typename C,
typename Traits>
605 std::vector< typename claw::math::curve<C, Traits>::section::resolved_point >
609 typedef std::vector<typename section::resolved_point> result_type;
619 result.insert( result.end(), new_points.begin(), new_points.end() );
625 const result_type before( get_point_at_x_before_origin(x) );
626 result.insert( result.begin(), before.begin(), before.end() );
628 const result_type after( get_point_at_x_after_end(x) );
629 result.insert( result.end(), after.begin(), after.end() );
639 template<
typename C,
typename Traits>
643 return m_points.begin();
650 template<
typename C,
typename Traits>
654 return m_points.end();
661 template<
typename C,
typename Traits>
665 return m_points.begin();
672 template<
typename C,
typename Traits>
676 return m_points.end();
685 template<
typename C,
typename Traits>
686 std::vector< typename claw::math::curve<C, Traits>::section::resolved_point >
689 typedef std::vector<typename section::resolved_point> result_type;
698 for ( std::size_t i(0); i!=points.size(); ++i )
699 if ( points[i].get_date() < 0 )
700 result.push_back( points[i] );
712 template<
typename C,
typename Traits>
713 std::vector< typename claw::math::curve<C, Traits>::section::resolved_point >
716 typedef std::vector<typename section::resolved_point> result_type;
719 if ( m_points.size() < 2 )
723 std::advance(it, -2);
731 for ( std::size_t i(0); i!=points.size(); ++i )
732 if ( points[i].get_date() > 1 )
733 result.push_back( points[i] );
resolved_point(const coordinate_type &position, const section &s, const double t)
Constructor.
coordinate_type get_tangent_at(double t) const
Get the direction of the tangent at a given date.
section(const iterator_type &origin, const iterator_type &end)
Constructor.
The control_point class describes a control point of the curve, with the direction of the curve befor...
const section & get_section() const
Get the section on which the point has been found.
coordinate_type get_point_at(double t) const
Get the point of this section at a given date.
void push_front(const control_point &p)
Add a point at the beginning of the curve.
std::vector< resolved_point > get_point_at_x(value_type x, bool off_domain=false) const
Get the points having the given x-coordinate on this section.
const_iterator iterator_type
The type of the iterators on the ends of the section.
C coordinate_type
The type of the coordinates of the curve.
A section is a part of the curve between two control points.
C coordinate_type
The type of the coordinates of the curve.
iterator end()
Get an iterator past the last control point.
const coordinate_type & get_position() const
Get The position of the point.
const iterator_type & get_origin() const
Get an iterator on the control point at the origin of the section in the curve from which it was crea...
const coordinate_type & get_output_direction() const
Get the point in the direction of which the curve leaves this position.
const coordinate_type & get_position() const
Get the position of this control point.
std::vector< typename section::resolved_point > get_point_at_x(value_type x, bool off_domain=false) const
Get the points having the given x-coordinate on the curve.
bool empty() const
Tell if there is no points on this section.
traits_type::value_type value_type
The type of the components of the coordinates.
traits_type::value_type value_type
The type of the components of the coordinates.
section get_section(const const_iterator &pos) const
Get the section of the curve starting at a given control point.
C coordinate_type
The type of the coordinates of the curve.
void push_back(const control_point &p)
Add a point at the end of the curve.
const coordinate_type & get_input_direction() const
Get the point in the direction of which the curve enters this position.
void insert(const iterator &pos, const control_point &p)
Add a point before an other point of the curve.
control_point()
Constructor.
control_point_list::const_iterator const_iterator
The type of the iterator on the control points of the curve.
control_point_list::iterator iterator
The type of the iterator on the control points of the curve.
Implementation of the Bézier curve.
iterator begin()
Get an iterator on the first control point.
double get_date() const
Get the date of the point on the section.
The resolved point class is a point found on a section.