-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathShape.h
160 lines (147 loc) · 3.42 KB
/
Shape.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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
* Shape.h
*
* (c) 2013 Sofian Audry -- info(@)sofianaudry(.)com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SHAPE_H_
#define SHAPE_H_
#include <vector>
#include <tr1/memory>
#include <iostream>
/**
* Point (or vertex) on the 2-D canvas.
*/
struct Point
{
double x;
double y;
Point(double x_, double y_) : x(x_), y(y_) {}
};
/**
* Series of vertices. (points)
*/
class Shape
{
public:
typedef std::tr1::shared_ptr<Shape> ptr;
std::vector<Point> vertices;
Shape() {}
Shape(std::vector<Point> vertices_) :
vertices(vertices_)
{}
virtual ~Shape() {}
virtual void build() {}
int nVertices() const { return vertices.size(); }
const Point& getVertex(int i)
{
return vertices[i];
}
void setVertex(int i, Point v)
{
vertices[i] = v;
}
void setVertex(int i, double x, double y)
{
vertices[i].x = x;
vertices[i].y = y;
}
/** Return true if Shape includes point (x,y), false otherwise
* Algorithm should work for all polygons, including non-convex
* Found at http://www.cs.tufts.edu/comp/163/notes05/point_inclusion_handout.pdf
*/
bool includesPoint(int x, int y)
{
Point *prev = NULL, *cur;
int left = 0, right = 0, maxy, miny;
for (std::vector<Point>::iterator it = vertices.begin() ; it !=
vertices.end(); it++)
{
if (!prev) {
prev = &vertices.back();
}
cur = &(*it);
miny = std::min(cur->y, prev->y);
maxy = std::max(cur->y, prev->y);
if (y > miny && y < maxy) {
if (prev->x == cur->x)
{
if (x < cur->x)
right++;
else left++;
}
else
{
double slope = (cur->y - prev->y) / (cur->x - prev->x);
double offset = cur->y - slope * cur->x;
int xintersect = int((y - offset ) / slope);
if (x < xintersect)
right++;
else left++;
}
}
prev = &(*it);
}
if (right % 2 && left % 2)
return true;
return false;
}
/* Translate all vertices of shape by the vector (x,y) */
void translate(int x, int y)
{
for (std::vector<Point>::iterator it = vertices.begin() ; it !=
vertices.end(); ++it)
{
it->x += x;
it->y += y;
}
}
int nVertices()
{
return vertices.size();
}
};
/**
* Four-vertex shape.
*/
class Quad : public Shape
{
public:
Quad() {}
Quad(Point p1, Point p2, Point p3, Point p4)
{
vertices.push_back(p1);
vertices.push_back(p2);
vertices.push_back(p3);
vertices.push_back(p4);
}
virtual ~Quad() {}
};
/**
* Triangle shape.
*/
class Triangle : public Shape
{
public:
Triangle() {}
Triangle(Point p1, Point p2, Point p3)
{
vertices.push_back(p1);
vertices.push_back(p2);
vertices.push_back(p3);
}
virtual ~Triangle() {}
};
#endif /* SHAPE_H_ */