Cornell Cocos
Cornell Extensions to Cocos2d
All Classes Functions Variables Enumerations Enumerator Friends
CUCubicSpline.h
1 //
2 // CUCubicSpline.h
3 // Cornell Extensions to Cocos2D
4 //
5 // This module provides a class that represents a spline of cubic beziers. A
6 // bezier spline is just a sequence of beziers joined together, so that the end
7 // of one is the beginning of the other. Cubic beziers have four control points,
8 // two for the vertex anchors and two for their tangents.
9 //
10 // Cocos2d does have a lot of spline support. In addition to cubic beziers, it
11 // also has quadratic beziers, cardinal splines, and Catmull-Rom splines. However,
12 // in true Cocos2d fashion, these are all tightly coupled with drawing code. We do
13 // not want splines embedded with drawing code. We want a mathematics object that
14 // we can adjust and compute with. Hence the purpose of this class. We chose
15 // cubic splines because they are the most natural for editting (as seen in
16 // Adobe Illustrator).
17 //
18 // If you want to draw a CubicSpline, use the allocPath() method to allocate a Poly2
19 // value for the spline. We have to turn shapes into polygons to draw them anyway,
20 // and this allows us to do all of the cool things we can already do with paths,
21 // like extrude them or create wireframes.
22 //
23 // Math data types are much lighter-weight than other objects, and are intended to
24 // be copied. That is why we do not use reference counting for these objects.
25 //
26 // Author: Walker White
27 // Version: 11/24/15
28 //
29 #ifndef __CU_CUBIC_SPLINE_H__
30 #define __CU_CUBIC_SPLINE_H__
31 
32 #include "CUPoly2.h"
33 
34 NS_CC_BEGIN
35 
36 class Polynomial;
37 
39 #define DEFAULT_TOLERANCE 0.25
40 
41 #pragma mark -
42 #pragma mark CubicSpline
43 
78 class CC_DLL CubicSpline {
79 protected:
80 
82  int _size;
83 
91  vector<Vec2> _points;
92 
94  vector<bool> _smooth;
95 
97  bool _closed;
98 
99 
100 public:
109  enum Criterion {
117 
125 
131  SPACING
132  };
133 
134 
135 #pragma mark Constructors
136 
142  CubicSpline() : CubicSpline(Vec2::ZERO,Vec2::ZERO) { }
143 
153  CubicSpline(const Vec2& point) : CubicSpline(point,point) { }
154 
168  CubicSpline(const Vec2& start, const Vec2& end);
169 
187  CubicSpline(const float* points, int size, int offset=0);
188 
204  CubicSpline(const vector<float>& points);
205 
221  CubicSpline(const vector<Vec2>& points);
222 
228  CubicSpline(const CubicSpline& spline);
229 
238 
239 
240 #pragma mark Attribute Accessors
241 
249  int getSize() const { return _size; }
250 
265  bool getClosed() const { return _closed; }
266 
281  void setClosed(bool flag);
282 
296  Vec2 getPoint(float tp) const { return getPoint((int)tp,tp-(int)tp); }
297 
315  void setPoint(float tp, const Vec2& point);
316 
328  Vec2 getAnchor(int index) const;
329 
346  void setAnchor(int index, const Vec2& point);
347 
364  bool getSmooth(int index) const;
365 
388  void setSmooth(int index, bool flag);
389 
408  Vec2 getTangent(int index) const;
409 
436  void setTangent(int index, const Vec2& tang, bool symmetric=false);
437 
452  Polynomial getPolynomialX(int segment) const;
453 
468  Polynomial getPolynomialY(int segment) const;
469 
484  const vector<Vec2> getControlPoints() const { return _points; }
485 
486 
487 #pragma mark Anchor Editting Methods
488 
503  int addAnchor(const Vec2& point) { return addAnchor(point,point); }
504 
520  int addAnchor(const Vec2& point, const Vec2& tang);
521 
536  void deleteAnchor(int index);
537 
557  void insertAnchor(float param) { insertAnchor((int)param,param-(int)param); }
558 
559 
560 #pragma mark Nearest Point Methods
561 
578  Vec2 nearestPoint(const Vec2& point) const { return getPoint(nearestParameter(point)); }
579 
593  float nearestParameter(const Vec2& point) const;
594 
606  int nearestAnchor(const Vec2& point, float threshold) const;
607 
619  int nearestTangent(const Vec2& point, float threshold) const;
620 
621 
622 #pragma mark Polygon Approximation
623 
638  vector<Vec2> approximate(float tolerance=DEFAULT_TOLERANCE,
639  Criterion criterion=Criterion::DISTANCE) const;
640 
661  vector<float> approximateParameters(float tolerance=DEFAULT_TOLERANCE,
662  Criterion criterion=Criterion::DISTANCE) const;
663 
684  vector<Vec2> approximateTangents(float tolerance=DEFAULT_TOLERANCE,
685  Criterion criterion=Criterion::DISTANCE) const;
686 
707  vector<Vec2> approximateNormals(float tolerance=DEFAULT_TOLERANCE,
708  Criterion criterion=Criterion::DISTANCE) const;
709 
723  CubicSpline refine(float tolerance=DEFAULT_TOLERANCE,
724  Criterion criterion=Criterion::DISTANCE) const;
725 
726 #pragma mark Rendering Data
727 
752  Poly2* allocPath(float tolerance=DEFAULT_TOLERANCE,
753  Criterion criterion=Criterion::DISTANCE) const;
754 
773  Poly2* allocTangents() const;
774 
795  Poly2* allocAnchors(float radius, int segments=4) const;
796 
817  Poly2* allocHandles(float radius, int segments=4) const;
818 
819 
820 #pragma mark Internal Helpers
821 protected:
835  Vec2 getPoint(int segment, float tp) const;
836 
856  void insertAnchor(int segment, float param);
857 
870  void subdivide(int segment, float tp, vector<Vec2>& left, vector<Vec2>& rght) const {
871  subdivide(_points,6*segment,tp,left,rght);
872  }
873 
891  static void subdivide(const vector<Vec2>& src, int soff, float tp,
892  vector<Vec2>& left, vector<Vec2>& rght);
893 
894 
909  Polynomial getProjectionPolynomial(const Vec2& point, int segment) const;
910 
932  Vec2 getProjectionSlow(const Vec2& point, int segment) const;
933 
960  Vec2 getProjectionFast(const Vec2& point, int segment) const;
961 
962 
963 
964 #pragma mark Recursive Data Generation
965 private:
967  enum Buffer {
968  /* No data, just count amounts */
969  EMPTY,
970  /* Put curve points into the list */
971  POINTS,
972  /* Put curve parameters into the list */
973  PARAMETERS,
974  /* Put tangent points into the list */
975  TANGENTS,
976  /* Put normals vectors into the list */
977  NORMALS,
978  /* Put all control points into the list */
979  ALL
980  };
981 
1006  static int generate_data(const vector<Vec2>& src, int soff, float tp,
1007  float tolerance, Criterion criterion,
1008  void* buffer, Buffer bufferType, int depth);
1009 
1010 };
1011 
1012 NS_CC_END
1013 #endif /* defined(__CU_CUBIC_SPLINE_H__) */
Vec2 nearestPoint(const Vec2 &point) const
Definition: CUCubicSpline.h:578
CubicSpline(const Vec2 &point)
Definition: CUCubicSpline.h:153
int _size
Definition: CUCubicSpline.h:82
Definition: CUPolynomial.h:50
bool getClosed() const
Definition: CUCubicSpline.h:265
vector< Vec2 > _points
Definition: CUCubicSpline.h:91
CubicSpline()
Definition: CUCubicSpline.h:142
~CubicSpline()
Definition: CUCubicSpline.h:237
Criterion
Definition: CUCubicSpline.h:109
const vector< Vec2 > getControlPoints() const
Definition: CUCubicSpline.h:484
int addAnchor(const Vec2 &point)
Definition: CUCubicSpline.h:503
Definition: CUPoly2.h:53
void insertAnchor(float param)
Definition: CUCubicSpline.h:557
int getSize() const
Definition: CUCubicSpline.h:249
Definition: CUCubicSpline.h:124
bool _closed
Definition: CUCubicSpline.h:97
void subdivide(int segment, float tp, vector< Vec2 > &left, vector< Vec2 > &rght) const
Definition: CUCubicSpline.h:870
Vec2 getPoint(float tp) const
Definition: CUCubicSpline.h:296
vector< bool > _smooth
Definition: CUCubicSpline.h:94
Definition: CUCubicSpline.h:78
Definition: CUCubicSpline.h:116