forked from Chlumsky/msdfgen
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Contour.cpp
58 lines (48 loc) · 1.57 KB
/
Contour.cpp
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
#include "Contour.h"
#include "arithmetics.hpp"
namespace msdfgen {
static double shoelace(const Point2 &a, const Point2 &b) {
return (b.x-a.x)*(a.y+b.y);
}
void Contour::addEdge(const EdgeHolder &edge) {
edges.push_back(edge);
}
#ifdef MSDFGEN_USE_CPP11
void Contour::addEdge(EdgeHolder &&edge) {
edges.push_back((EdgeHolder &&) edge);
}
#endif
EdgeHolder & Contour::addEdge() {
edges.resize(edges.size()+1);
return edges[edges.size()-1];
}
void Contour::bounds(double &l, double &b, double &r, double &t) const {
for (std::vector<EdgeHolder>::const_iterator edge = edges.begin(); edge != edges.end(); ++edge)
(*edge)->bounds(l, b, r, t);
}
int Contour::winding() const {
if (edges.empty())
return 0;
double total = 0;
if (edges.size() == 1) {
Point2 a = edges[0]->point(0), b = edges[0]->point(1/3.), c = edges[0]->point(2/3.);
total += shoelace(a, b);
total += shoelace(b, c);
total += shoelace(c, a);
} else if (edges.size() == 2) {
Point2 a = edges[0]->point(0), b = edges[0]->point(.5), c = edges[1]->point(0), d = edges[1]->point(.5);
total += shoelace(a, b);
total += shoelace(b, c);
total += shoelace(c, d);
total += shoelace(d, a);
} else {
Point2 prev = edges[edges.size()-1]->point(0);
for (std::vector<EdgeHolder>::const_iterator edge = edges.begin(); edge != edges.end(); ++edge) {
Point2 cur = (*edge)->point(0);
total += shoelace(prev, cur);
prev = cur;
}
}
return sign(total);
}
}