Particle.java
9.02 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
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
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/******************************************************************************
* Compilation: javac Particle.java
* Execution: none
* Dependencies: StdDraw.java
*
* A particle moving in the unit box with a given position, velocity,
* radius, and mass.
*
******************************************************************************/
package edu.princeton.cs.algs4;
import java.awt.Color;
/**
* The {@code Particle} class represents a particle moving in the unit box,
* with a given position, velocity, radius, and mass. Methods are provided
* for moving the particle and for predicting and resolvling elastic
* collisions with vertical walls, horizontal walls, and other particles.
* This data type is mutable because the position and velocity change.
* <p>
* For additional documentation,
* see <a href="http://algs4.cs.princeton.edu/61event">Section 6.1</a> of
* <i>Algorithms, 4th Edition</i> by Robert Sedgewick and Kevin Wayne.
*
* @author Robert Sedgewick
* @author Kevin Wayne
*/
public class Particle {
private static final double INFINITY = Double.POSITIVE_INFINITY;
private double rx, ry; // position
private double vx, vy; // velocity
private int count; // number of collisions so far
private final double radius; // radius
private final double mass; // mass
private final Color color; // color
/**
* Initializes a particle with the specified position, velocity, radius, mass, and color.
*
* @param rx <em>x</em>-coordinate of position
* @param ry <em>y</em>-coordinate of position
* @param vx <em>x</em>-coordinate of velocity
* @param vy <em>y</em>-coordinate of velocity
* @param radius the radius
* @param mass the mass
* @param color the color
*/
public Particle(double rx, double ry, double vx, double vy, double radius, double mass, Color color) {
this.vx = vx;
this.vy = vy;
this.rx = rx;
this.ry = ry;
this.radius = radius;
this.mass = mass;
this.color = color;
}
/**
* Initializes a particle with a random position and velocity.
* The position is uniform in the unit box; the velocity in
* either direciton is chosen uniformly at random.
*/
public Particle() {
rx = StdRandom.uniform(0.0, 1.0);
ry = StdRandom.uniform(0.0, 1.0);
vx = StdRandom.uniform(-0.005, 0.005);
vy = StdRandom.uniform(-0.005, 0.005);
radius = 0.01;
mass = 0.5;
color = Color.BLACK;
}
/**
* Moves this particle in a straight line (based on its velocity)
* for the specified amount of time.
*
* @param dt the amount of time
*/
public void move(double dt) {
rx += vx * dt;
ry += vy * dt;
}
/**
* Draws this particle to standard draw.
*/
public void draw() {
StdDraw.setPenColor(color);
StdDraw.filledCircle(rx, ry, radius);
}
/**
* Returns the number of collisions involving this particle with
* vertical walls, horizontal walls, or other particles.
* This is equal to the number of calls to {@link #bounceOff},
* {@link #bounceOffVerticalWall}, and
* {@link #bounceOffHorizontalWall}.
*
* @return the number of collisions involving this particle with
* vertical walls, horizontal walls, or other particles
*/
public int count() {
return count;
}
/**
* Returns the amount of time for this particle to collide with the specified
* particle, assuming no interening collisions.
*
* @param that the other particle
* @return the amount of time for this particle to collide with the specified
* particle, assuming no interening collisions;
* {@code Double.POSITIVE_INFINITY} if the particles will not collide
*/
public double timeToHit(Particle that) {
if (this == that) return INFINITY;
double dx = that.rx - this.rx;
double dy = that.ry - this.ry;
double dvx = that.vx - this.vx;
double dvy = that.vy - this.vy;
double dvdr = dx*dvx + dy*dvy;
if (dvdr > 0) return INFINITY;
double dvdv = dvx*dvx + dvy*dvy;
double drdr = dx*dx + dy*dy;
double sigma = this.radius + that.radius;
double d = (dvdr*dvdr) - dvdv * (drdr - sigma*sigma);
// if (drdr < sigma*sigma) StdOut.println("overlapping particles");
if (d < 0) return INFINITY;
return -(dvdr + Math.sqrt(d)) / dvdv;
}
/**
* Returns the amount of time for this particle to collide with a vertical
* wall, assuming no interening collisions.
*
* @return the amount of time for this particle to collide with a vertical wall,
* assuming no interening collisions;
* {@code Double.POSITIVE_INFINITY} if the particle will not collide
* with a vertical wall
*/
public double timeToHitVerticalWall() {
if (vx > 0) return (1.0 - rx - radius) / vx;
else if (vx < 0) return (radius - rx) / vx;
else return INFINITY;
}
/**
* Returns the amount of time for this particle to collide with a horizontal
* wall, assuming no interening collisions.
*
* @return the amount of time for this particle to collide with a horizontal wall,
* assuming no interening collisions;
* {@code Double.POSITIVE_INFINITY} if the particle will not collide
* with a horizontal wall
*/
public double timeToHitHorizontalWall() {
if (vy > 0) return (1.0 - ry - radius) / vy;
else if (vy < 0) return (radius - ry) / vy;
else return INFINITY;
}
/**
* Updates the velocities of this particle and the specified particle according
* to the laws of elastic collision. Assumes that the particles are colliding
* at this instant.
*
* @param that the other particle
*/
public void bounceOff(Particle that) {
double dx = that.rx - this.rx;
double dy = that.ry - this.ry;
double dvx = that.vx - this.vx;
double dvy = that.vy - this.vy;
double dvdr = dx*dvx + dy*dvy; // dv dot dr
double dist = this.radius + that.radius; // distance between particle centers at collison
// magnitude of normal force
double magnitude = 2 * this.mass * that.mass * dvdr / ((this.mass + that.mass) * dist);
// normal force, and in x and y directions
double fx = magnitude * dx / dist;
double fy = magnitude * dy / dist;
// update velocities according to normal force
this.vx += fx / this.mass;
this.vy += fy / this.mass;
that.vx -= fx / that.mass;
that.vy -= fy / that.mass;
// update collision counts
this.count++;
that.count++;
}
/**
* Updates the velocity of this particle upon collision with a vertical
* wall (by reflecting the velocity in the <em>x</em>-direction).
* Assumes that the particle is colliding with a vertical wall at this instant.
*/
public void bounceOffVerticalWall() {
vx = -vx;
count++;
}
/**
* Updates the velocity of this particle upon collision with a horizontal
* wall (by reflecting the velocity in the <em>y</em>-direction).
* Assumes that the particle is colliding with a horizontal wall at this instant.
*/
public void bounceOffHorizontalWall() {
vy = -vy;
count++;
}
/**
* Returns the kinetic energy of this particle.
* The kinetic energy is given by the formula 1/2 <em>m</em> <em>v</em><sup>2</sup>,
* where <em>m</em> is the mass of this particle and <em>v</em> is its velocity.
*
* @return the kinetic energy of this particle
*/
public double kineticEnergy() {
return 0.5 * mass * (vx*vx + vy*vy);
}
}
/******************************************************************************
* Copyright 2002-2016, Robert Sedgewick and Kevin Wayne.
*
* This file is part of algs4.jar, which accompanies the textbook
*
* Algorithms, 4th edition by Robert Sedgewick and Kevin Wayne,
* Addison-Wesley Professional, 2011, ISBN 0-321-57351-X.
* http://algs4.cs.princeton.edu
*
*
* algs4.jar 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.
*
* algs4.jar 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 algs4.jar. If not, see http://www.gnu.org/licenses.
******************************************************************************/