1/**
2 * Copyright (c) 2006-2023 LOVE Development Team
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 *
8 * Permission is granted to anyone to use this software for any purpose,
9 * including commercial applications, and to alter it and redistribute it
10 * freely, subject to the following restrictions:
11 *
12 * 1. The origin of this software must not be misrepresented; you must not
13 * claim that you wrote the original software. If you use this software
14 * in a product, an acknowledgment in the product documentation would be
15 * appreciated but is not required.
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 * 3. This notice may not be removed or altered from any source distribution.
19 **/
20
21#ifndef LOVE_MATH_BEZIER_CURVE_H
22#define LOVE_MATH_BEZIER_CURVE_H
23
24// LOVE
25#include "common/Object.h"
26#include "common/Vector.h"
27#include <vector>
28
29namespace love
30{
31namespace math
32{
33
34class BezierCurve : public Object
35{
36public:
37
38 static love::Type type;
39
40 /**
41 * @param controlPoints Control polygon of the curve.
42 **/
43 BezierCurve(const std::vector<Vector2> &controlPoints);
44
45 /**
46 * @returns Degree of the curve
47 **/
48 size_t getDegree() const
49 {
50 return controlPoints.size() - 1;
51 }
52
53 /**
54 * @returns First derivative of the curve.
55 */
56 BezierCurve getDerivative() const;
57
58 /**
59 * @returns i'th control point.
60 **/
61 const Vector2 &getControlPoint(int i) const;
62
63 /**
64 * Sets the i'th control point.
65 * @param i Control point to change.
66 * @param point New control point.
67 **/
68 void setControlPoint(int i, const Vector2 &point);
69
70 /**
71 * Insert a new control point before the i'th control point.
72 * If i < 0, Lua string indexing rules apply.
73 * @param point Control point to insert.
74 * @param pos Position to insert.
75 **/
76 void insertControlPoint(const Vector2 &point, int pos = -1);
77
78 /**
79 * Remove the i'th control point from the curve.
80 * @param i Control point to remove
81 **/
82 void removeControlPoint(int i);
83
84 /**
85 * @returns Number of control points.
86 **/
87 size_t getControlPointCount() const
88 {
89 return controlPoints.size();
90 }
91
92 /**
93 * Move the curve.
94 * @param t Translation vector.
95 */
96 void translate(const Vector2 &t);
97
98 /**
99 * Rotate the curve.
100 * @param phi Rotation angle (radians).
101 * @param center Rotation center.
102 */
103 void rotate(double phi, const Vector2 &center);
104
105 /**
106 * Scale the curve.
107 * @param phi Scale factor.
108 * @param center Scale center.
109 */
110 void scale(double phi, const Vector2 &center);
111
112 /**
113 * Evaluates the curve at time t.
114 * @param t Curve parameter, must satisfy 0 <= t <= 1.
115 **/
116 Vector2 evaluate(double t) const;
117
118 /**
119 * Get curve segment starting at t1 and ending at t2.
120 * The new curve will be parametrized from 0 <= t <= 1.
121 * @param t1 Start of the segment.
122 * @param t2 End of the segment.
123 * @returns Bezier curve covering the segment.
124 */
125 BezierCurve* getSegment(double t1, double t2) const;
126
127 /**
128 * Renders the curve by subdivision.
129 * @param accuracy The 'fineness' of the curve.
130 * @returns A polygon chain that approximates the bezier curve.
131 **/
132 std::vector<Vector2> render(int accuracy = 4) const;
133
134 /**
135 * Renders a segment of the curve by subdivision.
136 * @param start The starting point (between 0 and 1) on the curve.
137 * @param end The ending point on the curve.
138 * @param accuracy The 'fineness' of the curve.
139 * @returns A polygon chain that approximates the segment along the curve
140 **/
141 std::vector<Vector2> renderSegment(double start, double end, int accuracy = 4) const;
142
143private:
144 std::vector<Vector2> controlPoints;
145};
146
147}
148}
149
150#endif
151