-
-
Notifications
You must be signed in to change notification settings - Fork 412
/
edge-segments.h
146 lines (116 loc) · 5.23 KB
/
edge-segments.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#pragma once
#include "Vector2.hpp"
#include "SignedDistance.hpp"
#include "EdgeColor.h"
namespace msdfgen {
// Parameters for iterative search of closest point on a cubic Bezier curve. Increase for higher precision.
#define MSDFGEN_CUBIC_SEARCH_STARTS 4
#define MSDFGEN_CUBIC_SEARCH_STEPS 4
/// An abstract edge segment.
class EdgeSegment {
public:
EdgeColor color;
static EdgeSegment *create(Point2 p0, Point2 p1, EdgeColor edgeColor = WHITE);
static EdgeSegment *create(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor = WHITE);
static EdgeSegment *create(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor = WHITE);
EdgeSegment(EdgeColor edgeColor = WHITE) : color(edgeColor) { }
virtual ~EdgeSegment() { }
/// Creates a copy of the edge segment.
virtual EdgeSegment *clone() const = 0;
/// Returns the numeric code of the edge segment's type.
virtual int type() const = 0;
/// Returns the array of control points.
virtual const Point2 *controlPoints() const = 0;
/// Returns the point on the edge specified by the parameter (between 0 and 1).
virtual Point2 point(double param) const = 0;
/// Returns the direction the edge has at the point specified by the parameter.
virtual Vector2 direction(double param) const = 0;
/// Returns the change of direction (second derivative) at the point specified by the parameter.
virtual Vector2 directionChange(double param) const = 0;
/// Returns the minimum signed distance between origin and the edge.
virtual SignedDistance signedDistance(Point2 origin, double ¶m) const = 0;
/// Converts a previously retrieved signed distance from origin to perpendicular distance.
virtual void distanceToPerpendicularDistance(SignedDistance &distance, Point2 origin, double param) const;
/// Outputs a list of (at most three) intersections (their X coordinates) with an infinite horizontal scanline at y and returns how many there are.
virtual int scanlineIntersections(double x[3], int dy[3], double y) const = 0;
/// Adjusts the bounding box to fit the edge segment.
virtual void bound(double &l, double &b, double &r, double &t) const = 0;
/// Reverses the edge (swaps its start point and end point).
virtual void reverse() = 0;
/// Moves the start point of the edge segment.
virtual void moveStartPoint(Point2 to) = 0;
/// Moves the end point of the edge segment.
virtual void moveEndPoint(Point2 to) = 0;
/// Splits the edge segments into thirds which together represent the original edge.
virtual void splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const = 0;
};
/// A line segment.
class LinearSegment : public EdgeSegment {
public:
enum EdgeType {
EDGE_TYPE = 1
};
Point2 p[2];
LinearSegment(Point2 p0, Point2 p1, EdgeColor edgeColor = WHITE);
LinearSegment *clone() const;
int type() const;
const Point2 *controlPoints() const;
Point2 point(double param) const;
Vector2 direction(double param) const;
Vector2 directionChange(double param) const;
double length() const;
SignedDistance signedDistance(Point2 origin, double ¶m) const;
int scanlineIntersections(double x[3], int dy[3], double y) const;
void bound(double &l, double &b, double &r, double &t) const;
void reverse();
void moveStartPoint(Point2 to);
void moveEndPoint(Point2 to);
void splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const;
};
/// A quadratic Bezier curve.
class QuadraticSegment : public EdgeSegment {
public:
enum EdgeType {
EDGE_TYPE = 2
};
Point2 p[3];
QuadraticSegment(Point2 p0, Point2 p1, Point2 p2, EdgeColor edgeColor = WHITE);
QuadraticSegment *clone() const;
int type() const;
const Point2 *controlPoints() const;
Point2 point(double param) const;
Vector2 direction(double param) const;
Vector2 directionChange(double param) const;
double length() const;
SignedDistance signedDistance(Point2 origin, double ¶m) const;
int scanlineIntersections(double x[3], int dy[3], double y) const;
void bound(double &l, double &b, double &r, double &t) const;
void reverse();
void moveStartPoint(Point2 to);
void moveEndPoint(Point2 to);
void splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const;
EdgeSegment *convertToCubic() const;
};
/// A cubic Bezier curve.
class CubicSegment : public EdgeSegment {
public:
enum EdgeType {
EDGE_TYPE = 3
};
Point2 p[4];
CubicSegment(Point2 p0, Point2 p1, Point2 p2, Point2 p3, EdgeColor edgeColor = WHITE);
CubicSegment *clone() const;
int type() const;
const Point2 *controlPoints() const;
Point2 point(double param) const;
Vector2 direction(double param) const;
Vector2 directionChange(double param) const;
SignedDistance signedDistance(Point2 origin, double ¶m) const;
int scanlineIntersections(double x[3], int dy[3], double y) const;
void bound(double &l, double &b, double &r, double &t) const;
void reverse();
void moveStartPoint(Point2 to);
void moveEndPoint(Point2 to);
void splitInThirds(EdgeSegment *&part0, EdgeSegment *&part1, EdgeSegment *&part2) const;
};
}