I’m using the processing java library to simulate a ball bouncing between two walls using Newtonian physics; horizontal velocity is a constant, as there is no acceleration. I got the simulation to work, however I would like to specify the height of the floor. However in my equations when I attempt to change direction when the ball is 10 pixels from the bottom of the screen, after every bounce, the ball gets lower and lower below the “floor”. If I raise the floor to >20 pixels, the ball does not come to a halt and instead indefinitely bounces. Here is the pertinent code:
Note that processing’s coordinate system begins at the top and runs down and right. Thanks for the help in advance.
public class Testing extends PApplet {
boolean inFloor=false;
float xPosition=500;
float yPosition=200;
float xVelocity=25;
float yVelocity=-80.0f;
float yAccelleration=+10.0f;
float elasticity=0.80f;
public void setup (){
size(displayWidth,displayHeight);
noStroke();
ellipseMode(RADIUS);
frameRate(35);
}
public boolean sketchFullScreen() {
return true;
}
public void draw(){
background(0);
//Changes direction of motion when hitting a wall
if(xPosition>=displayWidth||xPosition<0){
xVelocity=-xVelocity;
}
//supposed to change direction of motion when the ball hits the floor
if(yPosition>=displayHeight-20){
yPosition=(displayHeight-20);
yVelocity=-(yVelocity)*elasticity;
if(yVelocity>=-1 && yVelocity<=0){
xVelocity=xVelocity*elasticity;
yVelocity=0;
yAccelleration=0;
}
}
else{
yVelocity=yVelocity+yAccelleration;
}
yPosition=yVelocity+yPosition;
xPosition=xPosition+xVelocity;
ellipse(xPosition,yPosition,10,10);
}
Edit: Could this possibly be a timing issue?
Edit: Thank you for all the responses. Unfortunately I can’t upvote any of them, (only 6 rep). I combined a mixture of @tobius_k’s answer, @Roberto_Mereghetti’s answer and some sample code from OpenProcessing.org and that solved it. In the solution provided below, because the canvas is measured in pixels (integer values), the use of floats to specify co-ordinates was causing graphical glitches in processing. So I implemented a system where float values were rounded, with decimal values being added to an accumulator (“xRounder” and “yRounder”) which when were great than -1 or 1 were rounded and added to the Ball’s current position. This gave me a floor!
Final Code:
import processing.core.*;
//import processing.xml.*;
import java.applet.*;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.MouseEvent;
import java.awt.event.KeyEvent;
import java.awt.event.FocusEvent;
import java.awt.Image;
import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;
import java.util.zip.*;
import java.util.regex.*;
public class Testing extends PApplet {
int xPosition=500;
int yPosition=200;
float xRounder=0;
float yRounder=0;
float xVelocity=25;
float yVelocity=-80.0f;
float yAccelleration=+10.0f;
float elasticity=0.80f;
public void setup (){
size(displayWidth,displayHeight);
noStroke();
ellipseMode(RADIUS);
frameRate(15);
}
public boolean sketchFullScreen() {
return true;
}
/* (non-Javadoc)
* @see processing.core.PApplet#draw()
*/
public void draw(){
background(0);
yPosition=round(yVelocity)+yPosition;
yRounder+=(yVelocity-round(yVelocity));
xPosition=round(xVelocity)+xPosition;
xRounder+=(xVelocity-round(xVelocity));
if(xRounder>=1||xRounder<=-1){
xPosition=xPosition+round(xRounder);
xRounder=xRounder-round(xRounder);
}
if(yRounder>=1||yRounder<=-1){
yPosition+=round(yRounder);
yRounder=yRounder-round(yRounder);
}
if(yPosition>displayHeight-50 && yVelocity>0){
yPosition=displayHeight-50;
yVelocity=-(yVelocity)*elasticity;
xVelocity=xVelocity*elasticity;
}
if(xPosition>=displayWidth||xPosition<0){
xVelocity=-xVelocity;
}
yVelocity=yVelocity+yAccelleration;
ellipse(xPosition,yPosition,10,10);
}
static public void main(String args[]) {
PApplet.main(new String[] { "--bgcolor=#ECE9D8", "Testing" });
// new Testing().setVisible(true);
}
}
I am not 100% sure, but I think that by resetting the ball to the bottom line when it actually arrives a few pixels below the bottom line you exactly compensate the elasticity factor, so that the ball bounces on indefinitely.
Try removing the line
yPosition=(displayHeight-20);, then it should work better.This way, the ball will eventually come to a rest, but this is still not correct, as the time the ball falls through the ground is not counted at all.
Update Okay, I think now I’ve got it. Here are the relevant bits:
So the main changes w.r.t. your code are:
And here how it looks like (floor being at 500). Not perfect, but close.
Update 2: Just found this Processing example, which is actually very close to your original code, with the difference that they always apply acceleration, and that they do so before the collision-checks. Seems like this alone does the trick.