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