std::pair< T, T > intersection( const ray<T,2u>& ray, const circle<T>& circle )
    { 
      // check for no intersection
    
      const T a = dot( ray.direction(), ray.direction() );
      const T b = T(2.) * sum( ray.direction() * ( ray.source() - circle.center() ) );
      const T c =   dot( circle.center(), circle.center() ) 
                  + dot( ray.source(), ray.source() ) 
                  - T(2.) * dot( ray.source(), circle.center() )
                  - sqr( circle.radius() );

      return solve_quadratic_equation(a,b,c);
    }
Beispiel #2
0
   void draw_indicator(canvas& cnv, circle cp, float val, color c)
   {
      constexpr float w_factor = 0.05; // relative width of the indicator
      constexpr float h_factor = 0.2;  // relative height of the indicator
      using namespace radial_consts;

      auto state = cnv.new_state();
      auto center = cp.center();
      cnv.translate({ center.x, center.y });
      cnv.rotate(offset + (val * range));

      float r = cp.radius * 0.85;
      float ind_w = r * w_factor;
      float ind_h = r * h_factor;
      rect  ind_r = { -ind_w, -ind_h, ind_w, ind_h };
      ind_r = ind_r.move(0, r*0.6);

      draw_indicator(cnv, ind_r, c);
   }
Beispiel #3
0
   void draw_radial_marks(canvas& cnv, circle cp, float size, color c)
   {
      using namespace radial_consts;
      auto state = cnv.new_state();
      auto center = cp.center();
      constexpr auto num_divs = 50;
      float div = range / num_divs;
      auto const& theme = get_theme();

      cnv.translate({ center.x, center.y });
      cnv.stroke_style(theme.ticks_color);
      for (int i = 0; i != num_divs+1; ++i)
      {
         float from = cp.radius;
         if (i % (num_divs / 10))
         {
            // Minor ticks
            from -= size / 4;
            cnv.line_width(theme.minor_ticks_width);
            cnv.stroke_style(c.level(theme.minor_ticks_level));
         }
         else
         {
            // Major ticks
            cnv.line_width(theme.major_ticks_width);
            cnv.stroke_style(c.level(theme.major_ticks_level));
         }

         float angle = offset + (M_PI / 2) + (i * div);
         float sin_ = std::sin(angle);
         float cos_ = std::cos(angle);
         float to = cp.radius - (size / 2);

         cnv.move_to({ from * cos_, from * sin_ });
         cnv.line_to({ to * cos_, to * sin_ });
         cnv.stroke();
      }
   }
Beispiel #4
0
   void draw_radial_labels(
      canvas& cnv
    , circle cp
    , float size
    , float font_size
    , std::string const labels[]
    , std::size_t num_labels
   )
   {
      if (num_labels < 2)
         return; // Nothing to do

      using namespace radial_consts;
      auto state = cnv.new_state();
      auto center = cp.center();
      float div = range / (num_labels-1);
      auto const& theme = get_theme();

      cnv.translate({ center.x, center.y });
      cnv.text_align(cnv.middle | cnv.center);
      cnv.fill_style(theme.label_font_color);

      cnv.font(
         theme.label_font,
         theme.label_font_size * font_size,
         theme.label_style
      );

      for (int i = 0; i != num_labels; ++i)
      {
         float angle = offset + (M_PI / 2) + (i * div);
         float sin_ = std::sin(angle);
         float cos_ = std::cos(angle);

         cnv.fill_text({ cp.radius * cos_, cp.radius * sin_ }, labels[i].c_str());
      }
   }