-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPoly.java
204 lines (174 loc) · 6.12 KB
/
Poly.java
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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
import java.util.*;
import java.util.stream.Stream;
import javax.swing.*;
import java.awt.*;
public class Poly {
private Tri[] tris;
private Line[] lines;
private Point[] points;
private Point midpoint;
private int surroundingMines = 0;
private Visibility visible = Visibility.NORMAL;
private double polySize;
public Poly(Tri[] tris, Line[] lines) {
for (Tri t : tris)
t.addPoly(this);
this.tris = tris;
this.lines = lines;
this.genPoints();
}
public boolean containsTri(Tri tri) {
return Stream.of(tris).anyMatch(tri::equals);
}
public int numPoints() {
return this.points.length;
}
public Point getPoint(int index) {
return this.points[index];
}
//Returns -1 if mine, -2 if activated mine, or number of surrounding mines
public int getDisplayState() {
return this.surroundingMines;
}
public void setMine() {
this.surroundingMines = -1;
}
public Point getMidpoint() {
return this.midpoint;
}
public void drawNum(Graphics2D g2) {
int midX = (int) (this.midpoint.getX() * MisalignGraphics.getXM());
int midY = (int) (this.midpoint.getY() * MisalignGraphics.getYM());
int numSize = (int)(polySize * Math.min(MisalignGraphics.getXM(), MisalignGraphics.getYM()));
// Set the font size to fit in the Poly
g2.setFont(g2.getFont().deriveFont((float) numSize));
midX -= numSize / 4; // about 1/2 as wide as tall
midY += numSize / 2;
g2.drawString(this.surroundingMines + "", midX, midY);
}
public void drawImageInPoly(Graphics2D g2, Image img) {
int midX = (int) (this.midpoint.getX() * MisalignGraphics.getXM());
int midY = (int) (this.midpoint.getY() * MisalignGraphics.getYM());
int imgSize = (int)(polySize * Math.min(MisalignGraphics.getXM(), MisalignGraphics.getYM()));
midX -= imgSize / 2;
midY -= imgSize / 2;
g2.drawImage(img, midX, midY, imgSize, imgSize, null);
}
// Finds the middle of the Poly for rendering things
public void calcMidpoint() {
Point centroid = calcCentroid(this.points);
Optional<Tri> bigTri = Optional.empty(); // keep track of biggest tri, if it uses it, for size purposes
if (Misalignsweeper.getClickedPoly(centroid.getX(), centroid.getY()) != this) {
bigTri = Stream.of(tris).max((t, t2) -> Double.compare(t.area(), t2.area()));
centroid = calcCentroid(bigTri.get().getPoints());
}
this.midpoint = centroid;
double midX = this.midpoint.getX();
double midY = this.midpoint.getY();
// Calculate poly's size
double polyHeight = 0;
double polyWidth = 0;
for (Line edge : this.lines) {
if (edge.spansX(midX))
polyHeight = Math.abs(polyHeight - edge.at(midX));
if (edge.spansY(midY))
polyWidth = Math.abs(polyWidth - (midY - edge.getB()) / edge.getM());
}
this.polySize = Math.min(polyHeight, polyWidth) * 2 / 3.0;
}
// Calculates the average of all the points
public static Point calcCentroid(Point[] ps) {
double x = 0, y = 0;
for (Point p : ps) {
x += p.getX() / ps.length;
y += p.getY() / ps.length;
}
return new Point(x, y);
}
// Generates and orders the points cyclically for awt Polygon purposes
private void genPoints() {
ArrayList<Point> points = new ArrayList<>();
Point p = lines[0].getP();
Point prevP = lines[0].getQ();
Point temp;
pointLoop:
do {
points.add(p);
for (Line l : lines) {
if (l.hasPoint(p) && !l.hasPoint(prevP)) {
prevP = p;
p = l.getOtherPoint(p);
continue pointLoop;
}
}
temp = p;
p = prevP;
prevP = temp;
} while (p != lines[0].getP());
this.points = points.toArray(new Point[0]);
}
public void reveal() {
if (this.visible == Visibility.NORMAL) {
if (Misalignsweeper.firstClick) {
Misalignsweeper.firstClick = false;
Misalignsweeper.generateMines(this);
}
this.visible = Visibility.PRESSED;
if (this.surroundingMines == -1) {
if (!MisalignGraphics.playingLossAnimation) {
this.surroundingMines = -2;
}
} else if (this.surroundingMines == 0)
for (Line l : lines)
for (Tri t : l.getTris())
if (t != null)
t.getPoly().reveal();
}
}
public void flag() {
if (this.visible == Visibility.FLAG) {
this.visible = Visibility.NORMAL;
Misalignsweeper.numFlags++;
} else if (Misalignsweeper.numFlags != 0 && this.visible == Visibility.NORMAL) {
this.visible = Visibility.FLAG;
Misalignsweeper.numFlags--;
}
MisalignGraphics.getMineCounter().setText(Misalignsweeper.numFlags + "");
}
//Updates surrounding mine (should be done once all mines are placed)
public void updateMines() {
if (this.surroundingMines < 0)
return;
HashSet<Poly> addedPolys = new HashSet<>();
for (Line l : lines) {
for (Tri t : l.getTris()) {
if (t != null) {
Poly poly = t.getPoly();
if (poly != null && !addedPolys.contains(poly) && poly != this) {
addedPolys.add(poly);
if (poly.getDisplayState() == -1)
this.surroundingMines++;
}
}
}
}
}
//Returns the number of intersections with line extending from point
public int raycast(double x, double y) {
return (int) Stream.of(lines).filter(l -> l.spansX(x) && l.at(x) > y).count();
}
public boolean isPressed() {
return this.visible == Visibility.PRESSED;
}
public boolean isFlagged() {
return this.visible == Visibility.FLAG;
}
public boolean isNormal() {
return this.visible == Visibility.NORMAL;
}
enum Visibility {
NORMAL,
PRESSED,
FLAG;
}
}