Changeset 29:f15800b500ae in rrlib_geometry


Ignore:
Timestamp:
20.04.2012 10:57:29 (8 years ago)
Author:
Tobias Föhst <foehst@…>
Branch:
default
Children:
30:9ae11f8090aa, 37:3c5f9c26db92
Phase:
public
Message:

Added more general drawing methods for BezierCurves and SplineCurves, a cache for Spline-Segments and and interface for more general parameter-to-segment-calculation

Files:
9 edited

Legend:

Unmodified
Added
Removed
  • curves/tBezierCurve.h

    r24 r29  
    181181canvas::tCanvas2D &operator << (canvas::tCanvas2D &canvas, const tBezierCurve<2, TElement, 3> &bezier_curve); 
    182182 
     183template <typename TElement, unsigned int Tdegree> 
     184canvas::tCanvas2D &operator << (canvas::tCanvas2D &canvas, const tBezierCurve<2, TElement, Tdegree> &bezier_curve); 
     185 
    183186#endif 
    184187 
  • curves/tBezierCurve.hpp

    r25 r29  
    402402{ 
    403403  canvas.StartPath(bezier_curve.ControlPoints()[0]); 
    404   canvas.AppendQuadraticBezierCurve(bezier_curve.ControlPoints() + 1, bezier_curve.ControlPoints() + 3); 
     404  canvas.AppendQuadraticBezierCurve(bezier_curve.ControlPoints()[1], bezier_curve.ControlPoints()[2]); 
    405405 
    406406  return canvas; 
     
    415415} 
    416416 
     417template <typename TElement, unsigned int Tdegree> 
     418canvas::tCanvas2D &operator << (canvas::tCanvas2D &canvas, const tBezierCurve<2, TElement, Tdegree> &bezier_curve) 
     419{ 
     420  if (bezier_curve.GetTwist() < 1E-6) 
     421  { 
     422    canvas.DrawLineSegment(bezier_curve.ControlPoints()[0], bezier_curve.ControlPoints()[Tdegree - 1]); 
     423    return canvas; 
     424  } 
     425 
     426  typename tBezierCurve<2, TElement, Tdegree>::tSubdivision subdivision(bezier_curve.GetSubdivision()); 
     427  canvas << subdivision.first << subdivision.second; 
     428 
     429  return canvas; 
     430} 
     431 
    417432#endif 
    418433 
  • curves/tCardinalSplineCurve.h

    r24 r29  
    9090  void SetTension(double tension); 
    9191 
    92   virtual const typename tSplineCurve::tBezierCurve GetBezierCurveForSegment(unsigned int i) const; 
     92  virtual std::shared_ptr<const typename tSplineCurve::tBezierCurve> CreateBezierCurveForSegment(unsigned int i) const; 
    9393 
    9494//---------------------------------------------------------------------- 
     
    9898 
    9999  double tension; 
     100 
     101  virtual unsigned int GetSegmentForParameter(typename tSplineCurve::tParameter t); 
     102  virtual typename tSplineCurve::tParameter GetLocalParameter(typename tSplineCurve::tParameter t); 
    100103 
    101104}; 
  • curves/tCardinalSplineCurve.hpp

    r25 r29  
    8383 
    8484//---------------------------------------------------------------------- 
    85 // tCardinalSplineCurve GetBezierCurveForSegment 
     85// tCardinalSplineCurve GetSegmentForParameter 
    8686//---------------------------------------------------------------------- 
    8787template <size_t Tdimension, typename TElement> 
    88 const typename tSplineCurve<Tdimension, TElement, 3>::tBezierCurve tCardinalSplineCurve<Tdimension, TElement>::GetBezierCurveForSegment(unsigned int i) const 
     88unsigned int tCardinalSplineCurve<Tdimension, TElement>::GetSegmentForParameter(typename tSplineCurve::tParameter t) 
     89{ 
     90  assert((0 <= t) && (t <= this->NumberOfSegments())); 
     91  return static_cast<unsigned int>(t < this->NumberOfSegments() ? t : t - 1.0); 
     92} 
     93 
     94//---------------------------------------------------------------------- 
     95// tCardinalSplineCurve GetLocalParameter 
     96//---------------------------------------------------------------------- 
     97template <size_t Tdimension, typename TElement> 
     98typename tSplineCurve<Tdimension, TElement, 3>::tParameter tCardinalSplineCurve<Tdimension, TElement>::GetLocalParameter(typename tSplineCurve::tParameter t) 
     99{ 
     100  assert((0 <= t) && (t <= this->NumberOfSegments())); 
     101  return t < this->NumberOfSegments() ? t - std::trunc(t) : 1.0; 
     102} 
     103 
     104//---------------------------------------------------------------------- 
     105// tCardinalSplineCurve CreateBezierCurveForSegment 
     106//---------------------------------------------------------------------- 
     107template <size_t Tdimension, typename TElement> 
     108std::shared_ptr<const typename tSplineCurve<Tdimension, TElement, 3>::tBezierCurve> tCardinalSplineCurve<Tdimension, TElement>::CreateBezierCurveForSegment(unsigned int i) const 
    89109{ 
    90110  typename tShape::tPoint bezier_control_points[4]; 
     
    95115  bezier_control_points[3] = this->ControlPoints()[i + 2]; 
    96116 
    97   return typename tSplineCurve::tBezierCurve(bezier_control_points, bezier_control_points + 4); 
    98 }; 
     117  return std::shared_ptr<const typename tSplineCurve::tBezierCurve>(new typename tSplineCurve::tBezierCurve(bezier_control_points, bezier_control_points + 4)); 
     118} 
    99119 
    100120//---------------------------------------------------------------------- 
  • curves/tSplineCurve.h

    r24 r29  
    4141// External includes (system with <>, local with "") 
    4242//---------------------------------------------------------------------- 
     43#include <memory> 
     44 
    4345#ifdef _LIB_RRLIB_CANVAS_PRESENT_ 
    4446#include "rrlib/canvas/tCanvas2D.h" 
     
    119121  const typename tShape::tPoint operator()(tParameter t) const; 
    120122 
    121   const tBezierCurve GetBezierCurveForParameter(tParameter t) const; 
     123  std::shared_ptr<const tBezierCurve> GetBezierCurveForParameter(tParameter t) const; 
    122124 
    123   const tBezierCurve GetBezierCurveForParameter(tParameter t, tParameter &local_t) const; 
     125  std::shared_ptr<const tBezierCurve> GetBezierCurveForParameter(tParameter t, tParameter &local_t) const; 
    124126 
    125   virtual const tBezierCurve GetBezierCurveForSegment(unsigned int i) const = 0; 
     127  std::shared_ptr<const tBezierCurve> GetBezierCurveForSegment(unsigned int i) const; 
    126128 
    127129  template <unsigned int Tother_degree> 
     
    143145 
    144146//---------------------------------------------------------------------- 
     147// Protected methods 
     148//---------------------------------------------------------------------- 
     149protected: 
     150 
     151  void SetChanged(); 
     152 
     153//---------------------------------------------------------------------- 
    145154// Private fields and methods 
    146155//---------------------------------------------------------------------- 
     
    148157 
    149158  std::vector<typename tShape::tPoint> control_points; 
     159  mutable std::vector<std::shared_ptr<const tBezierCurve>> bezier_curve_cache; 
    150160 
    151161  virtual void UpdateBoundingBox(typename tShape::tBoundingBox &bounding_box) const; 
    152162  virtual void UpdateCenterOfGravity(typename tShape::tPoint &center_of_gravity) const; 
     163 
     164  virtual unsigned int GetSegmentForParameter(tParameter t) = 0; 
     165  virtual tParameter GetLocalParameter(tParameter t) = 0; 
     166  virtual std::shared_ptr<const tBezierCurve> CreateBezierCurveForSegment(unsigned int i) const = 0; 
    153167 
    154168}; 
  • curves/tSplineCurve.hpp

    r27 r29  
    7272  std::copy(begin, end, std::back_inserter(this->control_points)); 
    7373  assert(control_points.size() > Tdegree); 
     74  this->bezier_curve_cache.resize(this->NumberOfSegments()); 
    7475} 
    7576 
     
    9394  this->control_points.push_back(point); 
    9495  this->SetChanged(); 
     96  this->bezier_curve_cache.emplace_back(); 
    9597}; 
    9698 
     
    103105  this->control_points.insert(position, point); 
    104106  this->SetChanged(); 
     107  this->bezier_curve_cache.emplace_back(); 
    105108}; 
    106109 
     
    112115{ 
    113116  assert((0 <= t) && (t <= this->NumberOfSegments())); 
    114   const tBezierCurve bezier_curve(this->GetBezierCurveForParameter(t, t)); 
    115   return bezier_curve(t); 
     117  std::shared_ptr<const tBezierCurve> bezier_curve = this->GetBezierCurveForParameter(t, t); 
     118  return bezier_curve->operator()(t); 
    116119} 
    117120 
     
    120123//---------------------------------------------------------------------- 
    121124template <size_t Tdimension, typename TElement, unsigned int Tdegree> 
    122 const typename tSplineCurve<Tdimension, TElement, Tdegree>::tBezierCurve tSplineCurve<Tdimension, TElement, Tdegree>::GetBezierCurveForParameter(tParameter t) const 
    123 { 
    124   assert((0 <= t) && (t <= this->NumberOfSegments())); 
    125   return this->GetBezierCurveForSegment(static_cast<size_t>(t < this->NumberOfSegments() ? t : t - 1.0)); 
    126 } 
    127  
    128 template <size_t Tdimension, typename TElement, unsigned int Tdegree> 
    129 const typename tSplineCurve<Tdimension, TElement, Tdegree>::tBezierCurve tSplineCurve<Tdimension, TElement, Tdegree>::GetBezierCurveForParameter(tParameter t, tParameter &local_t) const 
    130 { 
    131   local_t = t < this->NumberOfSegments() ? t - std::trunc(t) : 1.0; 
     125std::shared_ptr<const typename tSplineCurve<Tdimension, TElement, Tdegree>::tBezierCurve> tSplineCurve<Tdimension, TElement, Tdegree>::GetBezierCurveForParameter(tParameter t) const 
     126{ 
     127  return this->GetBezierCurveForSegment(this->GetSegmentForParameter(t)); 
     128} 
     129 
     130template <size_t Tdimension, typename TElement, unsigned int Tdegree> 
     131std::shared_ptr<const typename tSplineCurve<Tdimension, TElement, Tdegree>::tBezierCurve> tSplineCurve<Tdimension, TElement, Tdegree>::GetBezierCurveForParameter(tParameter t, tParameter &local_t) const 
     132{ 
     133  local_t = this->GetLocalParameter(t); 
    132134  return this->GetBezierCurveForParameter(t); 
     135} 
     136 
     137//---------------------------------------------------------------------- 
     138// tSplineCurve GetBezierCurveForSegment 
     139//---------------------------------------------------------------------- 
     140template <size_t Tdimension, typename TElement, unsigned int Tdegree> 
     141std::shared_ptr<const typename tSplineCurve<Tdimension, TElement, Tdegree>::tBezierCurve> tSplineCurve<Tdimension, TElement, Tdegree>::GetBezierCurveForSegment(unsigned int i) const 
     142{ 
     143  assert(i < this->NumberOfSegments()); 
     144  assert(this->bezier_curve_cache.size() == this->NumberOfSegments()); 
     145  if (!this->bezier_curve_cache[i]) 
     146  { 
     147    this->bezier_curve_cache[i] = this->CreateBezierCurveForSegment(i); 
     148  } 
     149  return this->bezier_curve_cache[i]; 
    133150} 
    134151 
     
    144161  { 
    145162    size_t last_size = intersection_parameters.size(); 
    146     const tBezierCurve bezier_curve(this->GetBezierCurveForSegment(i)); 
     163    std::shared_ptr<const tBezierCurve> bezier_curve = this->GetBezierCurveForSegment(i); 
    147164    for (unsigned int k = 0; k < other_spline.NumberOfSegments(); ++k) 
    148165    { 
    149       bezier_curve.GetIntersections(intersection_points, intersection_parameters, other_spline.GetBezierCurveForSegment(k)); 
     166      bezier_curve->GetIntersections(intersection_points, intersection_parameters, *other_spline.GetBezierCurveForSegment(k)); 
    150167    } 
    151168    for (size_t k = last_size; k < intersection_parameters.size(); ++k) 
     
    188205  { 
    189206    size_t last_size = intersection_parameters.size(); 
    190     const tBezierCurve bezier_curve(this->GetBezierCurveForSegment(i)); 
    191     bezier_curve.GetIntersections(intersection_points, intersection_parameters, line); 
     207    std::shared_ptr<const tBezierCurve> bezier_curve = this->GetBezierCurveForSegment(i); 
     208    bezier_curve->GetIntersections(intersection_points, intersection_parameters, line); 
    192209    for (size_t k = last_size; k < intersection_parameters.size(); ++k) 
    193210    { 
     
    212229const typename tShape<Tdimension, TElement>::tPoint tSplineCurve<Tdimension, TElement, Tdegree>::GetClosestPoint(const typename tShape::tPoint &reference_point) const 
    213230{ 
    214   typename tShape::tPoint closest_point = this->GetBezierCurveForSegment(0).GetClosestPoint(reference_point); 
     231  typename tShape::tPoint closest_point = this->GetBezierCurveForSegment(0)->GetClosestPoint(reference_point); 
    215232  double min_distance = (closest_point - reference_point).Length(); 
    216233 
    217234  for (size_t i = 1; i < this->NumberOfSegments(); ++i) 
    218235  { 
    219     typename tShape::tPoint candidate = this->GetBezierCurveForSegment(i).GetClosestPoint(reference_point); 
     236    typename tShape::tPoint candidate = this->GetBezierCurveForSegment(i)->GetClosestPoint(reference_point); 
    220237    double distance = (candidate - reference_point).Length(); 
    221238 
     
    290307 
    291308//---------------------------------------------------------------------- 
     309// tSplineCurve SetChanged 
     310//---------------------------------------------------------------------- 
     311template <size_t Tdimension, typename TElement, unsigned int Tdegree> 
     312void tSplineCurve<Tdimension, TElement, Tdegree>::SetChanged() 
     313{ 
     314  tShape::SetChanged(); 
     315  for (auto it = this->bezier_curve_cache.begin(); it != this->bezier_curve_cache.end(); ++it) 
     316  { 
     317    *it = std::shared_ptr<tBezierCurve>(); 
     318  } 
     319} 
     320 
     321//---------------------------------------------------------------------- 
    292322// tSplineCurve UpdateBoundingBox 
    293323//---------------------------------------------------------------------- 
     
    297327  for (size_t i = 0; i < this->NumberOfSegments(); ++i) 
    298328  { 
    299     bounding_box.Add(this->GetBezierCurveForSegment(i).BoundingBox()); 
     329    bounding_box.Add(this->GetBezierCurveForSegment(i)->BoundingBox()); 
    300330  } 
    301331} 
     
    309339  for (size_t i = 0; i < this->NumberOfSegments(); ++i) 
    310340  { 
    311     center_of_gravity += this->GetBezierCurveForSegment(i).CenterOfGravity(); 
     341    center_of_gravity += this->GetBezierCurveForSegment(i)->CenterOfGravity(); 
    312342  } 
    313343  center_of_gravity /= this->NumberOfSegments(); 
     
    320350 
    321351template <typename TElement> 
    322 inline canvas::tCanvas2D &operator << (canvas::tCanvas2D &canvas, const tSplineCurve<2, TElement, 3> &spline) 
    323 { 
    324   unsigned int number_of_segments = spline.NumberOfSegments(); 
    325   typename tSplineCurve<2, TElement, 3>::tBezierCurve bezier_curve = spline.GetBezierCurveForSegment(0); 
    326   canvas.StartPath(bezier_curve.ControlPoints()[0]); 
     352inline canvas::tCanvas2D &operator << (canvas::tCanvas2D &canvas, const tSplineCurve<2, TElement, 2> &spline_curve) 
     353{ 
     354  unsigned int number_of_segments = spline_curve.NumberOfSegments(); 
     355  auto bezier_curve = spline_curve.GetBezierCurveForSegment(0); 
     356  canvas.StartPath(bezier_curve->ControlPoints()[0]); 
    327357  for (unsigned int i = 1; i < number_of_segments; ++i) 
    328358  { 
    329     canvas.AppendCubicBezierCurve(bezier_curve.ControlPoints()[1], bezier_curve.ControlPoints()[2], bezier_curve.ControlPoints()[3]); 
    330     bezier_curve = spline.GetBezierCurveForSegment(i); 
    331   } 
    332   canvas.AppendCubicBezierCurve(bezier_curve.ControlPoints()[1], bezier_curve.ControlPoints()[2], bezier_curve.ControlPoints()[3]); 
     359    canvas.AppendQuadraticBezierCurve(bezier_curve->ControlPoints()[1], bezier_curve->ControlPoints()[2]); 
     360    bezier_curve = spline_curve.GetBezierCurveForSegment(i); 
     361  } 
     362  canvas.AppendQuadraticBezierCurve(bezier_curve->ControlPoints()[1], bezier_curve->ControlPoints()[2]); 
    333363 
    334364  return canvas; 
    335365} 
    336366 
     367template <typename TElement> 
     368inline canvas::tCanvas2D &operator << (canvas::tCanvas2D &canvas, const tSplineCurve<2, TElement, 3> &spline_curve) 
     369{ 
     370  unsigned int number_of_segments = spline_curve.NumberOfSegments(); 
     371  auto bezier_curve = spline_curve.GetBezierCurveForSegment(0); 
     372  canvas.StartPath(bezier_curve->ControlPoints()[0]); 
     373  for (unsigned int i = 1; i < number_of_segments; ++i) 
     374  { 
     375    canvas.AppendCubicBezierCurve(bezier_curve->ControlPoints()[1], bezier_curve->ControlPoints()[2], bezier_curve->ControlPoints()[3]); 
     376    bezier_curve = spline_curve.GetBezierCurveForSegment(i); 
     377  } 
     378  canvas.AppendCubicBezierCurve(bezier_curve->ControlPoints()[1], bezier_curve->ControlPoints()[2], bezier_curve->ControlPoints()[3]); 
     379 
     380  return canvas; 
     381} 
     382 
     383template <typename TElement, unsigned int Tdegree> 
     384inline canvas::tCanvas2D &operator << (canvas::tCanvas2D &canvas, const tSplineCurve<2, TElement, Tdegree> &spline_curve) 
     385{ 
     386  unsigned int number_of_segments = spline_curve.NumberOfSegments(); 
     387  for (size_t i = 0; i < number_of_segments; ++i) 
     388  { 
     389    canvas << *spline_curve.GetBezierCurveForSegment(i); 
     390  } 
     391 
     392  return canvas; 
     393} 
     394 
    337395#endif 
    338396 
  • curves/tUniformBSplineCurve.h

    r26 r29  
    9090  void SetTension(double tension); 
    9191 
    92   virtual const typename tSplineCurve::tBezierCurve GetBezierCurveForSegment(unsigned int i) const; 
    93  
    9492//---------------------------------------------------------------------- 
    9593// Private fields and methods 
     
    9896 
    9997  double tension; 
     98 
     99  virtual unsigned int GetSegmentForParameter(typename tSplineCurve::tParameter t); 
     100  virtual typename tSplineCurve::tParameter GetLocalParameter(typename tSplineCurve::tParameter t); 
     101  virtual std::shared_ptr<const typename tSplineCurve::tBezierCurve> CreateBezierCurveForSegment(unsigned int i) const; 
    100102 
    101103}; 
  • curves/tUniformBSplineCurve.hpp

    r28 r29  
    8383 
    8484//---------------------------------------------------------------------- 
    85 // tUniformBSplineCurve GetBezierCurveForSegment 
     85// tUniformBSplineCurve GetSegmentForParameter 
    8686//---------------------------------------------------------------------- 
    8787template <size_t Tdimension, typename TElement> 
    88 const typename tSplineCurve<Tdimension, TElement, 3>::tBezierCurve tUniformBSplineCurve<Tdimension, TElement>::GetBezierCurveForSegment(unsigned int i) const 
     88unsigned int tUniformBSplineCurve<Tdimension, TElement>::GetSegmentForParameter(typename tSplineCurve::tParameter t) 
     89{ 
     90  assert((0 <= t) && (t <= this->NumberOfSegments())); 
     91  return static_cast<unsigned int>(t < this->NumberOfSegments() ? t : t - 1.0); 
     92} 
     93 
     94//---------------------------------------------------------------------- 
     95// tUniformBSplineCurve GetLocalParameter 
     96//---------------------------------------------------------------------- 
     97template <size_t Tdimension, typename TElement> 
     98typename tSplineCurve<Tdimension, TElement, 3>::tParameter tUniformBSplineCurve<Tdimension, TElement>::GetLocalParameter(typename tSplineCurve::tParameter t) 
     99{ 
     100  assert((0 <= t) && (t <= this->NumberOfSegments())); 
     101  return t < this->NumberOfSegments() ? t - std::trunc(t) : 1.0; 
     102} 
     103 
     104//---------------------------------------------------------------------- 
     105// tUniformBSplineCurve CreateBezierCurveForSegment 
     106//---------------------------------------------------------------------- 
     107template <size_t Tdimension, typename TElement> 
     108std::shared_ptr<const typename tSplineCurve<Tdimension, TElement, 3>::tBezierCurve> tUniformBSplineCurve<Tdimension, TElement>::CreateBezierCurveForSegment(unsigned int i) const 
    89109{ 
    90110  typename tShape::tPoint bezier_control_points[4]; 
     
    95115  bezier_control_points[3] = (1.0 - this->tension) / 6.0 * (this->ControlPoints()[i + 1] + this->ControlPoints()[i + 3]) + (2.0 + this->tension) / 3.0 * this->ControlPoints()[i + 2]; 
    96116 
    97   return typename tSplineCurve::tBezierCurve(bezier_control_points, bezier_control_points + 4); 
    98 }; 
     117  return std::shared_ptr<const typename tSplineCurve::tBezierCurve>(new typename tSplineCurve::tBezierCurve(bezier_control_points, bezier_control_points + 4)); 
     118} 
    99119 
    100120//---------------------------------------------------------------------- 
  • test/test_geometries.cpp

    r28 r29  
    155155  for (size_t i = 0; i < spline_curve.NumberOfSegments(); ++i) 
    156156  { 
    157     DrawBezierCurve(window, spline_curve.GetBezierCurveForSegment(i), epsilon); 
     157    DrawBezierCurve(window, *spline_curve.GetBezierCurveForSegment(i), epsilon); 
    158158  } 
    159159} 
Note: See TracChangeset for help on using the changeset viewer.