-
Notifications
You must be signed in to change notification settings - Fork 0
/
Polygon.java
147 lines (119 loc) · 4.22 KB
/
Polygon.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
package asteroidymodyfikacja;
import java.awt.Color;
import java.awt.Graphics;
//martapalka
/**
*KLASA: Polygon
*OPIS: Wielokąt to zbiór punktów w przestrzeni zdefiniowana przez zestaw
*takich punkty, przesunięcie (offset) i rotację (obrót). Przesunięcie to
*odległość między punktem początkowym a środkiem wielokąta.
*Rotacja jest mierzona w skli 0-360.
*"Polygonami" są asteroidy oraz statki
*/
public class Polygon {
protected Point[] shape;
public Point position; // przesunięcie
public double rotation; //zero stopni oznacza skierowanie obiektu w prawo
public Polygon(Point[] inShape, Point inPosition, double inRotation) {
shape = inShape;
position = inPosition;
rotation = inRotation;
//Znajdowanie najbardziej wysuniętego na lewo punktu wielokąta
Point origin = shape[0].clone();
for (Point p : shape) {
if (p.x < origin.x) origin.x = p.x;
if (p.y < origin.y) origin.y = p.y;
}
// Wszystkie inne punkty są ustawiane względem odnalezionego powyżej punktu
for (Point p : shape) {
p.x -= origin.x;
p.y -= origin.y;
}
}
/**
* Metoda umożliwiająca ustawienie rotacji oraz pozyji wielokąta
* Zwraca wektor punktów potrzebny do implementacji powyższych zjawisk
*/
public Point[] getPoints() {
Point center = findCenter();
Point[] points = new Point[shape.length];
for (int i = 0; i < shape.length; i++) {
Point p = shape[i];
double x = ((p.x-center.x) * Math.cos(Math.toRadians(rotation)))
- ((p.y-center.y) * Math.sin(Math.toRadians(rotation)))
+ center.x/2 + position.x;
double y = ((p.x-center.x) * Math.sin(Math.toRadians(rotation)))
+ ((p.y-center.y) * Math.cos(Math.toRadians(rotation)))
+ center.y/2 + position.y;
points[i] = new Point(x,y);
}
return points;
}
public boolean contains(Point point) {
Point[] points = getPoints();
double crossingNumber = 0;
for (int i = 0, j = 1; i < shape.length; i++, j=(j+1)%shape.length) {
if ((((points[i].x < point.x) && (point.x <= points[j].x)) ||
((points[j].x < point.x) && (point.x <= points[i].x))) &&
(point.y > points[i].y + (points[j].y-points[i].y)/
(points[j].x - points[i].x) * (point.x - points[i].x))) {
crossingNumber++;
}
}
return crossingNumber%2 == 1;
}
public void rotate(int degrees) {rotation = (rotation+degrees)%360;}
private double findArea() {
double sum = 0;
for (int i = 0, j = 1; i < shape.length; i++, j=(j+1)%shape.length) {
sum += shape[i].x*shape[j].y-shape[j].x*shape[i].y;
}
return Math.abs(sum/2);
}
private Point findCenter() {
Point sum = new Point(0,0);
for (int i = 0, j = 1; i < shape.length; i++, j=(j+1)%shape.length) {
sum.x += (shape[i].x + shape[j].x)
* (shape[i].x * shape[j].y - shape[j].x * shape[i].y);
sum.y += (shape[i].y + shape[j].y)
* (shape[i].x * shape[j].y - shape[j].x * shape[i].y);
}
double area = findArea();
return new Point(Math.abs(sum.x/(6*area)),Math.abs(sum.y/(6*area)));
}
/**
* Metoda umożliwiająca narysowanie wielokąta
* @param brush
*/
public void paint(Graphics brush){
int[] xPoint = new int[shape.length];
int[] yPoint = new int[shape.length];
int segments = shape.length;
Point[] points = getPoints();
for(int i = 0; i < shape.length; i++){
xPoint[i] = (int) points[i].x;
yPoint[i] = (int) points[i].y;
}
brush.drawPolygon(xPoint,yPoint,segments);
}
/**
* Określa czy doszło do zderzenia dwóch wielokątów; metoda przydatna przy implementacji zderzeń w klasie Asteroids()
* @param other - drugi obiekt typu Polygon
* @return true jeśli dwa obiekty typu polygon miały ze sobą kontakt
*/
public boolean intersection(Polygon other){
Point[] array = other.getPoints();
int yes = 0;
//innocent until proven guilty
boolean output = false;
for(int i = 0; i < array.length; i++){
if(this.contains(array[i])){
yes++;
}
}
if(yes > 0){
output = true;
}
return output;
}
}