mirror of
https://github.com/processing/processing4.git
synced 2026-01-29 19:31:16 +01:00
updating CircleCollision to follow PVector syntax
This commit is contained in:
@@ -1,16 +1,131 @@
|
||||
class Ball{
|
||||
float x, y, r, m;
|
||||
class Ball {
|
||||
PVector position;
|
||||
PVector velocity;
|
||||
|
||||
// default constructor
|
||||
Ball() {
|
||||
float r, m;
|
||||
|
||||
Ball(float x, float y, float r_) {
|
||||
position = new PVector(x, y);
|
||||
velocity = PVector.random2D();
|
||||
velocity.mult(3);
|
||||
r = r_;
|
||||
m = r*.1;
|
||||
}
|
||||
|
||||
Ball(float x, float y, float r) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.r = r;
|
||||
m = r*.1;
|
||||
void update() {
|
||||
position.add(velocity);
|
||||
}
|
||||
|
||||
void checkBoundaryCollision() {
|
||||
if (position.x > width-r) {
|
||||
position.x = width-r;
|
||||
velocity.x *= -1;
|
||||
}
|
||||
else if (position.x < r) {
|
||||
position.x = r;
|
||||
velocity.x *= -1;
|
||||
}
|
||||
else if (position.y > height-r) {
|
||||
position.y = height-r;
|
||||
velocity.y *= -1;
|
||||
}
|
||||
else if (position.y < r) {
|
||||
position.y = r;
|
||||
velocity.y *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
void checkCollision(Ball other) {
|
||||
|
||||
// get distances between the balls components
|
||||
PVector bVect = PVector.sub(other.position, position);
|
||||
|
||||
// calculate magnitude of the vector separating the balls
|
||||
float bVectMag = bVect.mag();
|
||||
|
||||
if (bVectMag < r + other.r) {
|
||||
// get angle of bVect
|
||||
float theta = bVect.heading();
|
||||
// precalculate trig values
|
||||
float sine = sin(theta);
|
||||
float cosine = cos(theta);
|
||||
|
||||
/* bTemp will hold rotated ball positions. You
|
||||
just need to worry about bTemp[1] position*/
|
||||
PVector[] bTemp = {
|
||||
new PVector(), new PVector()
|
||||
};
|
||||
|
||||
/* this ball's position is relative to the other
|
||||
so you can use the vector between them (bVect) as the
|
||||
reference point in the rotation expressions.
|
||||
bTemp[0].position.x and bTemp[0].position.y will initialize
|
||||
automatically to 0.0, which is what you want
|
||||
since b[1] will rotate around b[0] */
|
||||
bTemp[1].x = cosine * bVect.x + sine * bVect.y;
|
||||
bTemp[1].y = cosine * bVect.y - sine * bVect.x;
|
||||
|
||||
// rotate Temporary velocities
|
||||
PVector[] vTemp = {
|
||||
new PVector(), new PVector()
|
||||
};
|
||||
|
||||
vTemp[0].x = cosine * velocity.x + sine * velocity.y;
|
||||
vTemp[0].y = cosine * velocity.y - sine * velocity.x;
|
||||
vTemp[1].x = cosine * other.velocity.x + sine * other.velocity.y;
|
||||
vTemp[1].y = cosine * other.velocity.y - sine * other.velocity.x;
|
||||
|
||||
/* Now that velocities are rotated, you can use 1D
|
||||
conservation of momentum equations to calculate
|
||||
the final velocity along the x-axis. */
|
||||
PVector[] vFinal = {
|
||||
new PVector(), new PVector()
|
||||
};
|
||||
|
||||
// final rotated velocity for b[0]
|
||||
vFinal[0].x = ((m - other.m) * vTemp[0].x + 2 * other.m * vTemp[1].x) / (m + other.m);
|
||||
vFinal[0].y = vTemp[0].y;
|
||||
|
||||
// final rotated velocity for b[0]
|
||||
vFinal[1].x = ((other.m - m) * vTemp[1].x + 2 * m * vTemp[0].x) / (m + other.m);
|
||||
vFinal[1].y = vTemp[1].y;
|
||||
|
||||
// hack to avoid clumping
|
||||
bTemp[0].x += vFinal[0].x;
|
||||
bTemp[1].x += vFinal[1].x;
|
||||
|
||||
/* Rotate ball positions and velocities back
|
||||
Reverse signs in trig expressions to rotate
|
||||
in the opposite direction */
|
||||
// rotate balls
|
||||
PVector[] bFinal = {
|
||||
new PVector(), new PVector()
|
||||
};
|
||||
|
||||
bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
|
||||
bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
|
||||
bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
|
||||
bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
|
||||
|
||||
// update balls to screen position
|
||||
other.position.x = position.x + bFinal[1].x;
|
||||
other.position.y = position.y + bFinal[1].y;
|
||||
|
||||
position.add(bFinal[0]);
|
||||
|
||||
// update velocities
|
||||
velocity.x = cosine * vFinal[0].x - sine * vFinal[0].y;
|
||||
velocity.y = cosine * vFinal[0].y + sine * vFinal[0].x;
|
||||
other.velocity.x = cosine * vFinal[1].x - sine * vFinal[1].y;
|
||||
other.velocity.y = cosine * vFinal[1].y + sine * vFinal[1].x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void display() {
|
||||
noStroke();
|
||||
fill(204);
|
||||
ellipse(position.x, position.y, r*2, r*2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -6,135 +6,27 @@
|
||||
* Foundation Actionscript Animation: Making Things Move!
|
||||
*/
|
||||
|
||||
|
||||
Ball[] balls = {
|
||||
new Ball(100, 400, 20),
|
||||
new Ball(700, 400, 80)
|
||||
};
|
||||
|
||||
PVector[] vels = {
|
||||
new PVector(2.15, -1.35),
|
||||
new PVector(-1.65, .42)
|
||||
};
|
||||
|
||||
void setup() {
|
||||
size(640, 360);
|
||||
noStroke();
|
||||
}
|
||||
|
||||
void draw() {
|
||||
background(51);
|
||||
fill(204);
|
||||
for (int i = 0; i < 2; i++){
|
||||
balls[i].x += vels[i].x;
|
||||
balls[i].y += vels[i].y;
|
||||
ellipse(balls[i].x, balls[i].y, balls[i].r*2, balls[i].r*2);
|
||||
checkBoundaryCollision(balls[i], vels[i]);
|
||||
|
||||
for (Ball b : balls) {
|
||||
b.update();
|
||||
b.display();
|
||||
b.checkBoundaryCollision();
|
||||
}
|
||||
checkObjectCollision(balls, vels);
|
||||
|
||||
balls[0].checkCollision(balls[1]);
|
||||
}
|
||||
|
||||
void checkObjectCollision(Ball[] b, PVector[] v){
|
||||
|
||||
// get distances between the balls components
|
||||
PVector bVect = new PVector();
|
||||
bVect.x = b[1].x - b[0].x;
|
||||
bVect.y = b[1].y - b[0].y;
|
||||
|
||||
// calculate magnitude of the vector separating the balls
|
||||
float bVectMag = sqrt(bVect.x * bVect.x + bVect.y * bVect.y);
|
||||
if (bVectMag < b[0].r + b[1].r){
|
||||
// get angle of bVect
|
||||
float theta = atan2(bVect.y, bVect.x);
|
||||
// precalculate trig values
|
||||
float sine = sin(theta);
|
||||
float cosine = cos(theta);
|
||||
|
||||
/* bTemp will hold rotated ball positions. You
|
||||
just need to worry about bTemp[1] position*/
|
||||
Ball[] bTemp = {
|
||||
new Ball(), new Ball()
|
||||
};
|
||||
|
||||
/* b[1]'s position is relative to b[0]'s
|
||||
so you can use the vector between them (bVect) as the
|
||||
reference point in the rotation expressions.
|
||||
bTemp[0].x and bTemp[0].y will initialize
|
||||
automatically to 0.0, which is what you want
|
||||
since b[1] will rotate around b[0] */
|
||||
bTemp[1].x = cosine * bVect.x + sine * bVect.y;
|
||||
bTemp[1].y = cosine * bVect.y - sine * bVect.x;
|
||||
|
||||
// rotate Temporary velocities
|
||||
PVector[] vTemp = {
|
||||
new PVector(), new PVector()
|
||||
};
|
||||
vTemp[0].x = cosine * v[0].x + sine * v[0].y;
|
||||
vTemp[0].y = cosine * v[0].y - sine * v[0].x;
|
||||
vTemp[1].x = cosine * v[1].x + sine * v[1].y;
|
||||
vTemp[1].y = cosine * v[1].y - sine * v[1].x;
|
||||
|
||||
/* Now that velocities are rotated, you can use 1D
|
||||
conservation of momentum equations to calculate
|
||||
the final velocity along the x-axis. */
|
||||
PVector[] vFinal = {
|
||||
new PVector(), new PVector()
|
||||
};
|
||||
// final rotated velocity for b[0]
|
||||
vFinal[0].x = ((b[0].m - b[1].m) * vTemp[0].x + 2 * b[1].m *
|
||||
vTemp[1].x) / (b[0].m + b[1].m);
|
||||
vFinal[0].y = vTemp[0].y;
|
||||
// final rotated velocity for b[0]
|
||||
vFinal[1].x = ((b[1].m - b[0].m) * vTemp[1].x + 2 * b[0].m *
|
||||
vTemp[0].x) / (b[0].m + b[1].m);
|
||||
vFinal[1].y = vTemp[1].y;
|
||||
|
||||
// hack to avoid clumping
|
||||
bTemp[0].x += vFinal[0].x;
|
||||
bTemp[1].x += vFinal[1].x;
|
||||
|
||||
/* Rotate ball positions and velocities back
|
||||
Reverse signs in trig expressions to rotate
|
||||
in the opposite direction */
|
||||
// rotate balls
|
||||
Ball[] bFinal = {
|
||||
new Ball(), new Ball()
|
||||
};
|
||||
bFinal[0].x = cosine * bTemp[0].x - sine * bTemp[0].y;
|
||||
bFinal[0].y = cosine * bTemp[0].y + sine * bTemp[0].x;
|
||||
bFinal[1].x = cosine * bTemp[1].x - sine * bTemp[1].y;
|
||||
bFinal[1].y = cosine * bTemp[1].y + sine * bTemp[1].x;
|
||||
|
||||
// update balls to screen position
|
||||
b[1].x = b[0].x + bFinal[1].x;
|
||||
b[1].y = b[0].y + bFinal[1].y;
|
||||
b[0].x = b[0].x + bFinal[0].x;
|
||||
b[0].y = b[0].y + bFinal[0].y;
|
||||
|
||||
// update velocities
|
||||
v[0].x = cosine * vFinal[0].x - sine * vFinal[0].y;
|
||||
v[0].y = cosine * vFinal[0].y + sine * vFinal[0].x;
|
||||
v[1].x = cosine * vFinal[1].x - sine * vFinal[1].y;
|
||||
v[1].y = cosine * vFinal[1].y + sine * vFinal[1].x;
|
||||
}
|
||||
}
|
||||
|
||||
void checkBoundaryCollision(Ball ball, PVector vel) {
|
||||
if (ball.x > width-ball.r) {
|
||||
ball.x = width-ball.r;
|
||||
vel.x *= -1;
|
||||
}
|
||||
else if (ball.x < ball.r) {
|
||||
ball.x = ball.r;
|
||||
vel.x *= -1;
|
||||
}
|
||||
else if (ball.y > height-ball.r) {
|
||||
ball.y = height-ball.r;
|
||||
vel.y *= -1;
|
||||
}
|
||||
else if (ball.y < ball.r) {
|
||||
ball.y = ball.r;
|
||||
vel.y *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user