-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPhysics.java
More file actions
110 lines (88 loc) · 2.27 KB
/
Physics.java
File metadata and controls
110 lines (88 loc) · 2.27 KB
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
public class Physics
{
public static void collideWithWall(Sphere a, double restitution, double width, double height)
{
Vector pos = a.pos;
Vector vel = a.vel;
if(pos.x < a.radius)
{
pos.x = a.radius;
if(vel.x < 0.0)
{
vel.x *= -restitution;
}
}
if(pos.x > width - a.radius)
{
pos.x = width - a.radius;
if(vel.x > 0.0)
{
vel.x *= -restitution;
}
}
if(pos.y < a.radius)
{
pos.y = a.radius;
if(vel.y < 0.0)
{
vel.y *= -restitution;
}
}
if(pos.y > height - a.radius)
{
pos.y = height - a.radius;
if(vel.y > 0.0)
{
vel.y *= -restitution;
}
}
}
public static void collide(Sphere a, Sphere b, double restitution)
{
Vector d = new Vector();
Vector.sub(d, b.pos, a.pos);
// distance between circle centres, squared
double distance_squared = d.lengthquad();
// combined radius squared
double radius = b.radius + a.radius;
double radius_squared = radius * radius;
// circles too far apart
if(distance_squared <= radius_squared)
{
// distance between circle centres
double distance = Math.sqrt(distance_squared);
// normal of collision
Vector ncoll = new Vector();
Vector.div_num(ncoll, d, distance);
// penetration distance
double dcoll = (radius - distance);
// inverse masses (0 means, infinite mass, object is static).
double ima = (a.mass > 0.0) ? (1.0 / a.mass) : 0.0;
double imb = (b.mass > 0.0) ? (1.0 / b.mass) : 0.0;
// separation vector
Vector separation_vector = new Vector();
Vector.mul_num(separation_vector, ncoll, dcoll / (ima + imb));
// separate the circles
Vector.mulsub_num(a.pos, separation_vector, ima);
Vector.muladd_num(b.pos, separation_vector, imb);
// combines velocity
Vector vcoll = new Vector();
Vector.sub(vcoll, b.vel, a.vel);
// impact speed
double vn = Vector.dot(vcoll, ncoll);
// obejcts are moving away. dont reflect velocity
if(vn > 0.0)
{
return;
}
// collision impulse
double j = -(1.0 + restitution) * (vn) / (ima + imb);
// collision impusle vector
Vector impulse = new Vector();
Vector.mul_num(impulse, ncoll, j);
// change momentum of the circles
Vector.mulsub_num(a.vel, impulse, ima);
Vector.muladd_num(b.vel, impulse, imb);
}
}
}