Skip to content

Commit 159ed6a

Browse files
committed
Add quadratic bezier.
1 parent bf1d293 commit 159ed6a

8 files changed

Lines changed: 91 additions & 8 deletions

File tree

include/pyro/graphics.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,8 @@ namespace Pyro
178178
virtual void line(float /*x0*/, float /*y0*/, float /*x1*/, float /*y1*/) {};
179179
void curve(Vector p0, Vector p1, Vector p2, Vector p3);
180180
void curve(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
181+
void bezier(Vector p0, Vector p1, Vector p2);
182+
void bezier(float x0, float y0, float x1, float y1, float x2, float y2);
181183
void bezier(Vector p0, Vector p1, Vector p2, Vector p3);
182184
void bezier(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3);
183185
void bspline(std::vector<Vector> points, int degree = 3);

include/pyro/pyro.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ namespace Pyro
9797

9898
inline void curve(Vector p0, Vector p1, Vector p2, Vector p3) { pg->curve(p0, p1, p2, p3); };
9999
inline void curve(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) { pg->curve(x0, y0, x1, y1, x2, y2, x3, y3); };
100+
inline void bezier(Vector p0, Vector p1, Vector p2) { pg->bezier(p0, p1, p2); };
101+
inline void bezier(float x0, float y0, float x1, float y1, float x2, float y2) { pg->bezier(x0, y0, x1, y1, x2, y2); };
100102
inline void bezier(Vector p0, Vector p1, Vector p2, Vector p3) { pg->bezier(p0, p1, p2, p3); };
101103
inline void bezier(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) { pg->bezier(x0, y0, x1, y1, x2, y2, x3, y3); };
102104
inline void bspline(std::vector<Vector> points, int degree = 3) { pg->bspline(points, degree); };

include/pyro/shape.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ namespace Pyro
1515
const int QUADS{6};
1616
const int QUAD_STRIP{7};
1717

18+
template <typename T>
19+
T bezierpoint(T a, T b, T c, float t)
20+
{
21+
float t1 = 1.0f - t;
22+
return t1 * t1 * a + 2 * t1 * t * b + t * t * c;
23+
};
24+
1825
template <typename T>
1926
T bezierpoint(T a, T b, T c, T d, float t)
2027
{
@@ -47,7 +54,8 @@ namespace Pyro
4754
{
4855
VERTEX,
4956
CURVEVERTEX,
50-
BEZIERVERTEX
57+
BEZIERVERTEX_2,
58+
BEZIERVERTEX_3
5159
};
5260

5361
struct t_shapepoint
@@ -81,6 +89,8 @@ namespace Pyro
8189
void vertex(float x, float y) { this->vertex(Vector(x, y)); };
8290
void curvevertex(Vector p);
8391
void curvevertex(float x, float y) { this->curvevertex(Vector(x, y)); };
92+
void beziervertex(Vector p2, Vector p3);
93+
void beziervertex(float x2, float y2, float x3, float y3) { this->beziervertex(Vector(x2, y2), Vector(x3, y3)); };
8494
void beziervertex(Vector p2, Vector p3, Vector p4);
8595
void beziervertex(float x2, float y2, float x3, float y3, float x4, float y4) { this->beziervertex(Vector(x2, y2), Vector(x3, y3), Vector(x4, y4)); };
8696
std::vector<std::vector<Pyro::Vector>> getpoints() { return this->outpoints; };

screenshot-tests/test-curves.cpp

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ TEST_CASE("Test curvepoint", "[shapes]")
3434
CHECK_THAT(current_folder / filename, LooksLike(actual_folder / filename));
3535
}
3636

37-
TEST_CASE("Test bezierpoint", "[shapes]")
37+
TEST_CASE("Test cubic bezierpoint", "[shapes]")
3838
{
39-
std::filesystem::path filename = "curve_bezierpoint.png";
39+
std::filesystem::path filename = "curve_cubic_bezierpoint.png";
4040

4141
size(400, 400);
4242
nofill();
@@ -56,6 +56,28 @@ TEST_CASE("Test bezierpoint", "[shapes]")
5656
CHECK_THAT(current_folder / filename, LooksLike(actual_folder / filename));
5757
}
5858

59+
TEST_CASE("Test quadratic bezierpoint", "[shapes]")
60+
{
61+
std::filesystem::path filename = "curve_quadratic_bezierpoint.png";
62+
63+
size(400, 400);
64+
nofill();
65+
bezier(340, 80, 40, 40, 60, 320);
66+
fill(255);
67+
ellipsemode(CENTER);
68+
int steps = 10;
69+
for (int i = 0; i <= steps; i++)
70+
{
71+
float t = i / float(steps);
72+
float x = bezierpoint(340, 40, 60, t);
73+
float y = bezierpoint(80, 40, 320, t);
74+
ellipse(x, y, 10, 10);
75+
}
76+
save(current_folder / filename);
77+
78+
CHECK_THAT(current_folder / filename, LooksLike(actual_folder / filename));
79+
}
80+
5981
TEST_CASE("Test bspline", "[shapes]")
6082
{
6183
std::filesystem::path filename = "curve_bspline.png";
File renamed without changes.
Lines changed: 3 additions & 0 deletions
Loading

src/graphics.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,21 @@ namespace Pyro
244244
this->shape(s, 0, 0);
245245
}
246246

247+
void Graphics::bezier(float x0, float y0, float x1, float y1, float x2, float y2)
248+
{
249+
bezier(Vector(x0, y0), Vector(x1, y1), Vector(x2, y2));
250+
}
251+
252+
void Graphics::bezier(Vector p0, Vector p1, Vector p2)
253+
{
254+
Shape s{Shape()};
255+
s.begin();
256+
s.vertex(p0);
257+
s.beziervertex(p1, p2);
258+
s.end(OPEN);
259+
this->shape(s, 0, 0);
260+
}
261+
247262
void Graphics::bezier(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3)
248263
{
249264
bezier(Vector(x0, y0), Vector(x1, y1), Vector(x2, y2), Vector(x3, y3));
@@ -258,7 +273,6 @@ namespace Pyro
258273
s.end(OPEN);
259274
this->shape(s, 0, 0);
260275
}
261-
262276
void Graphics::bspline(std::vector<Vector> points, int degree)
263277
{
264278
Shape s{Shape()};

src/shape.cpp

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ namespace Pyro
227227
contour.push_back(curvepoint(p0.v, point.v, p2.v, p3.v, i * delta));
228228
}
229229
}
230-
else if (point.type == PointType::BEZIERVERTEX)
230+
else if (point.type == PointType::BEZIERVERTEX_3)
231231
{
232232
if (curveiterator < 1)
233233
{
@@ -251,6 +251,29 @@ namespace Pyro
251251
}
252252
curveiterator += 2;
253253
}
254+
else if (point.type == PointType::BEZIERVERTEX_2)
255+
{
256+
if (curveiterator < 1)
257+
{
258+
std::cerr << "Missing first vertex\n";
259+
continue;
260+
}
261+
262+
if ((curveiterator + 1) > points.size())
263+
{
264+
std::cerr << "Missing following vertices\n";
265+
continue;
266+
}
267+
268+
auto p0 = points[curveiterator - 1];
269+
auto p2 = points[curveiterator + 1];
270+
271+
for (unsigned int i = 1; i < curve_resolution + 1; i++)
272+
{
273+
contour.push_back(bezierpoint(p0.v, point.v, p2.v, i * delta));
274+
}
275+
curveiterator += 1;
276+
}
254277
else
255278
{
256279
contour.push_back(point.v);
@@ -284,12 +307,19 @@ namespace Pyro
284307
this->points.push_back({p, PointType::CURVEVERTEX});
285308
}
286309

310+
void Shape::beziervertex(Vector p2, Vector p3)
311+
{
312+
assert(this->points.size() > 0);
313+
this->points.push_back({p2, PointType::BEZIERVERTEX_2});
314+
this->points.push_back({p3, PointType::BEZIERVERTEX_2});
315+
}
316+
287317
void Shape::beziervertex(Vector p2, Vector p3, Vector p4)
288318
{
289319
assert(this->points.size() > 0);
290-
this->points.push_back({p2, PointType::BEZIERVERTEX});
291-
this->points.push_back({p3, PointType::BEZIERVERTEX});
292-
this->points.push_back({p4, PointType::BEZIERVERTEX});
320+
this->points.push_back({p2, PointType::BEZIERVERTEX_3});
321+
this->points.push_back({p3, PointType::BEZIERVERTEX_3});
322+
this->points.push_back({p4, PointType::BEZIERVERTEX_3});
293323
}
294324

295325
std::vector<int32_t> Shape::indices()

0 commit comments

Comments
 (0)