Collision with Gravity

Hi all!
Im here again looking for help from you super genius :smiley:
Im building a mini (Ztupid) game so I can learn some physics object with PVector and Collision in 2D dimension.
The game is pretty simple, There is a Platform/Bar and a Ball upon it, the bar start with a random inclination (+1 pitch or -1 pitch) and the ball start rolling on the inclinated side. Using A & D you can rotate The Platform in order to keep the ball balanced upon the Platform or at least you try to dont drop it.
I cant figure out how build the collision and simulate the ball drop based on G-force and his mass.
If somebody can help me maybe just with the collission or the drop, would be super Awesome!
Here a screenshot of the basic concept:


Here the code:
Acrobat (Main class):

import java.text.DecimalFormat;

DecimalFormat df = new DecimalFormat("#.##");

int FPS = 20;//Initial frame rate
int howMuchFPS = 10;//FPS to increase every + key pressed
int attempts = 1;

//physics constants
final float GRAVITY = 0.9801;

//GLOBAL VARs
public static float pitchLeft = 0;
public static float pitchRight = 0;


Ball ball = new Ball();
Platform plat = new Platform();
float angle = 0.05;

void setup()
{
  //on startup
  size(1000, 700);
  frameRate(FPS);      
  rectMode(CENTER);
}

void draw()
{      
  background(40);
  fill(255);
  stroke(255);
  // line(0, 250, 250, 250);
  line(0, 500, 1000, 500); //Line(x1, y1, x2, y2)
  textSize(25);
  fill(0);    
  text("FPS: " + FPS, 480, 600); 
  textSize(35); 
  text("PitchL: " + df.format(pitchLeft), 100, 100);  
  text("PitchR: " + df.format(pitchRight), 700, 100);      

  // ball.move();
  ball.show();  

  plat.move();
  plat.show();
}

//---------------------------------------------------------------------------------------------------------------------------------------------------------  

void keyPressed()
{
  switch(key)
  {
    case 'a'://Go left //<>//
      plat.spin = -angle;
      break;
    case 'd'://Go right //<>//
       plat.spin = angle;
      break;
    case 'r':
      plat.rotation = 0;
      pitchLeft = 0;
      pitchRight = 0;
      break;
    //FRAMERATE SETUP
    case '+'://speed up frame rate
      FPS += howMuchFPS;
      frameRate(FPS);
      break;
    case '-'://slow down frame rate
      if (FPS > 10) //Check framerate > 10
      {
        FPS -= howMuchFPS;
        frameRate(FPS);
      }
      break;
    case 'p':
      FPS += 50;
      frameRate(FPS);    
      break;   
    case 'm':
      FPS -= 50;
      frameRate(FPS);    
      break;   
  }  
}

void keyReleased()
{
  switch(key)
  {
    case 'a'://Go left //<>//
      plat.spin = 0;
      break;
    case 'd'://Go right //<>//
       plat.spin = 0;
      break;
  }  
}

Platform Class

class Platform
{
  PVector position;
  PVector velocity;
  float spin; // Value of Spin
  float rotation; // The Bar current rotation
  int x, y;

  //Contsructors
  Platform()
  {
    position = new PVector();
    velocity = new PVector();    
    x = 0;
    y = 0;
    spin = 0;
    rotation = 0;

    //Get initial random inclination
    float rand = random(-1, 1);
    if(rand > 0)
      rotation += 0.05;
    else
      rotation -= 0.05;
  }

  //GET & SET-----------------------------------------------------------------------
  PVector getPosition()
  {return position;}
  void setPosition(PVector Position)
  {position = Position;}

  PVector getVelocity()
  {return velocity;}
  void setVelocity(PVector Velocity)
  {velocity = Velocity;}

  int getX()
  {return x;}
  void setX(int X)
  {x = X;}
  int getY()
  {return y;}
  void setY(int Y)
  {x = Y;}

  float getSpin()
  {return spin;}
  void setSpin(float Spin)
  {spin = Spin;}
  float getRotation()
  {return rotation;}
  void setRotation(float Rotation)
  {rotation = Rotation;}

//METHODS-----------------------------------------------------------------------------

  //Spin platform
  public void rotatePlatform()
  {
    rotation += spin;

    //SET TEXT INFOs
/*     if(spin > 0)
    {
      pitchLeft = rotation;
      pitchRight = -rotation;
    }
    else if(spin < 0)
    {
      pitchRight = rotation; 
      pitchLeft = -rotation;
    } */
  }

  public void move()
  {    
    rotatePlatform();
  }

  public void show()
  { 
    translate(width/2, height/2 + 150);
    rotate(rotation);   
    rect(0, 0, 500, 20, 5);       
  }
}

Ball Class

class Ball
{
  PVector position;
  PVector velocity;
  PVector acceleration;
  float mass;

  int x, y;

  Ball()
  {
    x = 0;
    y = 0;
    mass = 0.0;
    position = new PVector();    
    velocity = new PVector();
    acceleration = new PVector();
  }

  //GET & SET--------------------------------------------------------------------
  PVector getPosition()
  {return position;}
  void setPosition(PVector Position)
  {position = Position;}

  PVector getVelocity()
  {return velocity;}
  void setVelocity(PVector Velocity)
  {velocity = Velocity;}

  PVector getAcceleration()
  {return acceleration;}
  void setAcceleration(PVector Acceleration)
  {acceleration = Acceleration;}

  int getX()
  {return x;}
  void setX(int X)
  {x = X;}
  int getY()
  {return y;}
  void setY(int Y)
  {x = Y;}

  float getMass()
  {return mass;}
  void setMass(float Mass)
  {mass = Mass;}
  
  //METHODS----------------------------------------------------------------------

  void move()
  {
    // TEST DROPPING
    acceleration = new PVector(0, 0.98); //G-force
    velocity.add(acceleration);
    position.add(velocity);
    //acc.setMag(0.1);
  }

  void show()
  {          
    //TODO 
    //Follow G-force based on Platform inclination

    //ellipse(X, Y, width, height) Y = Half height + half this.radius - half bar radius
    ellipse(500, 450 + 25 - 12, 50, 50);
  }
}

1 Like

I ran your code but I didn’t explore it fully. I have some suggestions:

Start with the flat platform. Use another set of keys to make the ball roll. Although this is not your intention, to have the user to move the ball but the ball to react to contact forces and gravity, it is still a good exercise to undertand how to introduce motion into your system.

Then, use another key to make the ball jump. This will help you to start using gravity to your advantage. Can you make the ball bounce? If you want to have a starting point for this, explore the Processing foundation’s examples in their website.

After you get these concepts working, then you can implement the engine that makes the ball react to tilting.

Notice this approach I am suggesting is based on what you mention in your post. In other words. I am taking you for a longer ride hoping you get the best out of it.

Also how confident do you feel with Physics and vectors? Can you generate the formulas for slidding of objects on an incline plane?

Kf

1 Like

Well, I already see how can I implement interaction between these 2 objs but Im not able to generate formulas for slidding object on an incline plane!
Well maybe I can, but not sure!
Every other things You said I can “easly” accomplish!

I probably will use JBox 2D

I believe JBox will do all the work for you. Not a bad option.

If you work the equations for incline plane, then it is very easy to include it in the code as the only parameter there is the anglg of inclination.
However, you need to also figure out how to show motion, as the ball rolling.

Kf

Wll I dont motion just want to that the ball move towards the gravity and If he collide try to turn around if It can!

This is my attempt. The physics are not quite right because you do not add acceleration to velocity and position as straight sums but you need to consider the integration resultants of those operations. That belongs to the physics realm. Here, is a demonstration of how to change the position with respect to angle. From the incline plane, the effective gravity component along the incline is defined by g * sin(theta) where g is gravity and theta is the inclination angle. In your case, the latter changes as the platform rotates. As a first order approximation, this examples works ok. I mean, if the angle of rotation is close to zero, you will see that the code sort of works. However, at a larger angles, the position of the ball turns out to be wrong. you can see that easily if you set the gravity to 0 and add a value of 100 on the X psotion of the ball. If you ran the code you will see that as the angle increases, the ball will start overlapping with the platform. To fix this… hmmm, it is possible but this will require to manage all the forces interacting in your scene. I have only introduce the effective acceleration along the platform. One needs to introduce the forces perpendicular to the platform and one needs to work with time units if you want to simulate the real case.

To understand the code, this is what I did:

  • First, notice I introduce a fake factor to reduce the magnitude of gravity for testing purposes
  • Translation and rotation transformations were isolated to each system: the platform and the ball
  • For the ball, I set the translation to the center of the ball. Then when I applied the translation, it is with respect to this center AFTER it is rotated. In other words, a move the world in a reference frame that is rotated along the platform. The ball doesn’t know that the platform was rotated. I have chosen this reference frame as it would make this demo easier to implement. However, there could be another ref frame more convenient for the real case.
  • I remove all your setters and getters. I find this practice is encouraged in OOP courses. Really not needed here.

Kf

import java.text.DecimalFormat;


//physics constants
final float GRAVITY = 9.801;  //Units: m/s^2 
final float YOFFSET=150; 
final float TESTFACTOR=0.1;  //To reduce gravity magnitude, for testing purposes. Otherwise, set to 1

DecimalFormat df = new DecimalFormat("#.##");

int FPS = 25;//Initial frame rate
int howMuchFPS = 5;//FPS to increase every + key pressed
int attempts = 1;


//GLOBAL VARs
public static float pitchLeft = 0;
public static float pitchRight = 0;


Ball ball;
Platform plat;
float angle = 0.05;  //Units: Radians

void setup()
{
  //on startup
  size(1000, 700);
  frameRate(FPS);      
  rectMode(CENTER);


  plat = new Platform();
  ball = new Ball(plat.h);
}

void draw()
{      
  background(40);
  fill(255);
  stroke(255);
  // line(0, 250, 250, 250);
  line(0, 500, 1000, 500); //Line(x1, y1, x2, y2)
  textSize(25);
  fill(0);    
  text("FPS: " + FPS, 480, 600); 
  textSize(35); 
  text("PitchL: " + df.format(pitchLeft), 100, 100);  
  text("PitchR: " + df.format(pitchRight), 700, 100); 
  text("degrees" + df.format(degrees(plat.rotation)), 700, 140);

  ball.move();
  ball.show();  

  plat.move();
  plat.show();
}

//---------------------------------------------------------------------------------------------------------------------------------------------------------  

void keyPressed()
{
  switch(key)
  {
  case 'a'://Go left //<>//
    plat.spin = -angle;
    break;
  case 'd'://Go right //<>//
    plat.spin = angle;
    break;
  case 'r':
    plat.rotation = 0;
    pitchLeft = 0;
    pitchRight = 0;
    break;
    //FRAMERATE SETUP+++++--
  case '+'://speed up frame rate
    FPS += howMuchFPS;
    frameRate(FPS);
    break;
  case '-'://slow down frame rate
    if (FPS > 10) //Check framerate > 10
    {
      FPS -= howMuchFPS;
      frameRate(FPS);
    }
    break;
  case 'p':
    FPS += 50;
    frameRate(FPS);    
    break;   
  case 'm':
    FPS -= 50;
    frameRate(FPS);    
    break;
  }
}

void keyReleased()
{
  switch(key)
  {
  case 'a'://Go left //<>//
    plat.spin = 0;
    break;
  case 'd'://Go right //<>//
    plat.spin = 0;
    break;
  }
}


class Platform
{
  PVector position;
  PVector velocity;
  float spin; // Value of Spin
  float rotation; // The Bar current rotation
  int x, y;
  int w, h;

  //Contsructors
  Platform()
  {
    position = new PVector();
    velocity = new PVector();    
    x = 0;
    y = 0;
    w=500;
    h=20;
    spin = 0;
    rotation = 0;

    //Get initial random inclination
    float rand = random(-1, 1);
    if (rand > 0)
      rotation += 0.05;
    else
      rotation -= 0.05;
  }

  //METHODS-----------------------------------------------------------------------------

  //Spin platform
  public void rotatePlatform()
  {
    rotation += spin;

    //SET TEXT INFOs
    /*     if(spin > 0)
     {
     pitchLeft = rotation;
     pitchRight = -rotation;
     }
     else if(spin < 0)
     {
     pitchRight = rotation; 
     pitchLeft = -rotation;
     } */
  }

  public void move()
  {    
    rotatePlatform();
  }

  public void show()
  {   
    pushMatrix();
    translate(width/2, height/2 + YOFFSET);
    rotate(rotation); 
    rect(0, 0, w, h, 5);
    popMatrix();
  }
}


class Ball
{
  PVector position;
  PVector velocity;
  PVector acceleration;
  float mass;

  int x, y;
  int r;  //radius

  Ball(int platformHeight)
  {
    x = 0;
    y = 0;
    r=50;
    mass = 0.0;
    position = new PVector(0, -r-platformHeight/2.0);   // Offset ball by its radius and half of platform's height   
    velocity = new PVector();
    acceleration = new PVector(0, GRAVITY); //G-force
  }


  //METHODS----------------------------------------------------------------------

  void move()
  {
    // TEST DROPPING
    acceleration=new PVector(GRAVITY*TESTFACTOR*sin(plat.rotation), 0);
    
    if(frameCount%30==0) println(acceleration);

    velocity.add(acceleration);
    position.add(velocity);
    //acc.setMag(0.1);
  }

  void show()
  {    
    pushMatrix();
    translate(width/2, height/2 + YOFFSET+position.y);
    rotate(plat.rotation); 

    //TODO 
    //Follow G-force based on Platform inclination

    //ellipse(X, Y, width, height) Y = Half height + half this.radius - half bar radius
    ellipse(position.x, 0, r*2, r*2);
    popMatrix();
  }
}
1 Like

U ARE CRAZY!
Well <3 Thank you, tomorrow Ill check the code!
But, It wasnt necessary to waste time on this!
If you find it helful so ok!
Thank you again man

In addition to kfrajer’s specific discussion of the forces and code implementation – when I looked for a general conceptual overview on this, based on your question:

…I found this helpful physics lesson sequence with diagrams and formulas. Might be useful for you:

Well I already studied this stuff on my degree course :smiley:
But it’s ok, I took a revision :slight_smile:

It wasn’t so complex at the end!
Thank you mate!