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] );