-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCollisonDetection.pde
163 lines (142 loc) · 4.24 KB
/
CollisonDetection.pde
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
void checkMousePressed() {
PVector mIn = new PVector(mouseX, mouseY);
if (mousePressed) {
if (!drawingRect) {
manageHits(mIn);
} else {
updateBox(mIn);
}
}
if (!mousePressed) {
if (drawingRect)
drawingRect = false;
if (movingRect)
stopBox();
if (previousHit != null) {
previousHit.setOff();
previousHit = null;
}
}
}
void startBox(PVector mIn) {
println("Draw box");
drawingRect = true;
box = new HighlightBox(mIn);
}
void updateBox(PVector mIn) {
println("Update box");
box.update(mIn);
for ( DataPoint d : items) {
if (checkBoxHit (d.p.x, d.p.y) ) {
box.addDataPoint(d);
} else {
box.removeDataPoint(d);
}
}
}
void moveBox(PVector mIn) {
println("Move box");
box.movePosition(mIn);
}
void stopBox() {
println("Move box");
movingRect = false;
box = null;
}
void manageHits(PVector mIn) {
DataPoint hit = null;
// Check previous hit for collision first, as it is most likely, avoids cycling through all items.
if (previousHit != null && checkPreviousCollision(mIn, previousHit)) {
hit = previousHit;
} else if (box != null && checkBoxHit (mIn.x, mIn.y) && !movingRect) {
// Move stuff
println("Start moving rect");
movingRect = true;
box.centerMode();
} else if (box != null && checkBoxHit (mIn.x, mIn.y) && movingRect) {
moveBox(mIn);
} else {
for ( DataPoint d : items) {
if (checkMouseCollision(mIn, d)) {
// Takes first hit and runs
hit = d;
break;
}
}
if (box != null && !checkBoxHit (mIn.x, mIn.y))
movingRect = false;
}
// problem here, does it all need to be nested?
if (!movingRect) {
if (hit != null) {
// Delete box as it is there but not pressed
if (box != null)
box = null;
if (hit != previousHit) {
if (previousHit != null)
previousHit.setOff();
previousHit = hit;
}
if (!hit.isPressed())
hit.setOn();
} else if (previousHit != null) {
previousHit.setOff();
previousHit = null;
} else {
if (box == null)
startBox(mIn);
}
}
}
boolean checkMouseCollision (PVector mouseIn, DataPoint dataIn ) {
return pointBall(mouseIn.x, mouseIn.y, dataIn.p.x, dataIn.p.y, pointSize);
}
// Much larger hit radius to account for movement,
boolean checkPreviousCollision (PVector mouseIn, DataPoint dataIn ) {
return pointBall(mouseIn.x, mouseIn.y, dataIn.p.x, dataIn.p.y, pointSize*6.0);
}
boolean checkBoxHit(float x, float y) {
return circleRect(x, y, pointSize, box.getStartX(), box.getStartY(), box.getWidth(), box.getHeight());
}
// Adapt form to statics or classes to be implemented by each type of interactable.
boolean pointBall(float px, float py, float bx, float by, float bSize) {
// find distance between the two objects
float xDist = px-bx; // distance horiz
float yDist = py-by; // distance vert
float distance = sqrt((xDist*xDist) + (yDist*yDist)); // diagonal distance
// test for collision
if (bSize > distance) { // Original: if (bSize/2 > distance) {
return true; // if a hit, return true
} else { // if not, return false
return false;
}
}
/*
RECT/BALL COLLISION FUNCTION
Jeff Thompson // v0.9 // November 2011 // www.jeffreythompson.org
Takes 7 arguments:
+ x,y position of the first ball - in this case "you"
+ width and height of rect
+ x,y position of the second ball
+ diameter of second ball
*/
// CIRCLE/RECTANGLE
boolean circleRect(float cx, float cy, float radius, float rx, float ry, float rw, float rh) {
// temporary variables to set edges for testing
float testX = cx;
float testY = cy;
// which edge is closest?
if (cx < rx) testX = rx; // compare to left edge
else if (cx > rx+rw) testX = rx+rw; // right edge
if (cy < ry) testY = ry; // top edge
else if (cy > ry+rh) testY = ry+rh; // bottom edge
// get distance from closest edges
float distX = cx-testX;
float distY = cy-testY;
float distance = sqrt( (distX*distX) + (distY*distY) );
// if the distance is less than the radius, collision!
if (distance <= radius) {
return true;
}
return false;
}