Fill a parabole track


#1

Hi

I have this code and I want to draw each point of the parabole instead of viewing only the point moving.

Code is the following

float dx=10;  // Inital x position
float dy=620; // Inital y position
float vx=0;  // Inital x velocity
float vy=0; //Inital v velocity, remember negative y is up
float t=.1;  // Time steps
float g=9.8; // Acceleration due to gravity, where each pixel = 1 meter
float vyf=0; // Final Velocity
float aimX=50;
float aimY=320;
int angle = 0;
int vi=0;
boolean launch=false;
float time=0.000;
float alturamax;
float projV;
float projAngle;

void setup()
{
  size(900, 630);
  smooth();
  background(100);
  frameRate (30/t);
  textSize(20);
}

void draw ()
{
  background(100);
  strokeWeight(1);
  fill(255);
  ellipse (50, height/2, 50, 50);
  ellipse (dx, dy, 20, 20);
  fill(180);
  rect(25, 25, 90, 25);
  rect(25, 75, 90, 25);
  strokeWeight(6);
  line(-angle+25, 25, -angle+25, 50);
  text(-angle+" Deg.", 125, 50);
  line(vi+25, 75, vi+25, 100);
  text(vi+" m/s", 125, 100);
  text("Temps =", 680, 50);
  text(time+" s", 770, 50);
  text("La velocitat inicial és =", 545, 70);
  text(vi +" m/s", 770, 70);
  text("L'angle inicial és =", 585, 90);
  text(-angle +"º", 770, 90); 
  text("La longitud màxima és =", 525, 110);
  text(int(dx-10)+" m", 770, 110);  
  alturamax=vi*vi*sin(-angle)*sin(-angle)/(2*9.8);
  text("La alçada màxima és =", 545, 130);
  text(int(alturamax) + " m", 770, 130);  


  pushMatrix();
  translate(50, height/2);
  rotate(radians(angle));
  line(0, 0, vi, 0);
  line(vi, 0, vi-10, -10);
  line(vi, 0, vi-10, 10);
  popMatrix();
  if (launch)
  {
    vyf=vy+g*t;
    dy=dy+vy*t+.5*(vyf-vy)*t;
    vy=vyf;
    dx=dx+vx*t;
    if (dy<height-10)
    {
      time=time+t;
    }
  }
  if (dy>(height-10))
  {
    dy=height-10;
    vy=0;
    vx=0;
    if (dx<770)
    {
      text(int(dx-10)+" m", dx+15, height-2);
    } else
    {
      text(int(dx-10)+" m", dx-110, height-2);
    }
  }
}

void mouseDragged()
{
  if (mouseX > 25 && mouseX < 115  && mouseY > 25 && mouseY < 50 && dx<11)
  {
    angle=-mouseX+25;
  } else if (mouseX > 25 && mouseX < 115  && mouseY > 75 && mouseY < 100 && dx<11)
  {
    vi=mouseX-25;
  }
}

void mouseReleased()
{
  if (dx<11)
  {
    vy=vi*sin(radians(angle));
    vx=vi*cos(radians(angle));
    launch=true;
    time=0;
  }
}

void mousePressed()
{
  launch=false;
  dx=10;
  dy=620;
}

Thanks in advance


#2

Hi,

You need a way to save the previous position in order to perform the effect you want. You can use an ArrayList for example.

Then, the idea is to add to that list all the position that the ball have ever had and use that list to display a “phantom tray”.

I made quick changes to your code:

float dx=10;  // Inital x position
float dy=620; // Inital y position
float vx=0;  // Inital x velocity
float vy=0; //Inital v velocity, remember negative y is up
float t=.1;  // Time steps
float g=9.8; // Acceleration due to gravity, where each pixel = 1 meter
float vyf=0; // Final Velocity
float aimX=50;
float aimY=320;
int angle = 0;
int vi=0;
boolean launch=false;
float time=0.000;
float alturamax;
float projV;
float projAngle;

ArrayList<PVector> ballTrack; // Keep track of the old ball positions

void setup()
{
  size(900, 630);
  smooth();
  background(100);
  frameRate (30/t);
  textSize(20);
  
  ballTrack = new ArrayList<PVector>();
}

void draw ()
{
  background(100);
  strokeWeight(1);
  fill(255);
  ellipse (50, height/2, 50, 50);
  
  // Display the previous ball position
  for (int i = 0; i < ballTrack.size(); i++) {
    fill(200);
    ellipse (ballTrack.get(i).x, ballTrack.get(i).y, 20, 20);
  }
  
  // Display your current position 
  fill(255);
  ellipse (dx, dy, 20, 20);
  
  // Add the new position to the liste of the old position for the next turn
  ballTrack.add(new PVector(dx, dy));
  
  fill(180);
  rect(25, 25, 90, 25);
  rect(25, 75, 90, 25);
  strokeWeight(6);
  line(-angle+25, 25, -angle+25, 50);
  text(-angle+" Deg.", 125, 50);
  line(vi+25, 75, vi+25, 100);
  text(vi+" m/s", 125, 100);
  text("Temps =", 680, 50);
  text(time+" s", 770, 50);
  text("La velocitat inicial és =", 545, 70);
  text(vi +" m/s", 770, 70);
  text("L'angle inicial és =", 585, 90);
  text(-angle +"º", 770, 90); 
  text("La longitud màxima és =", 525, 110);
  text(int(dx-10)+" m", 770, 110);  
  alturamax=vi*vi*sin(-angle)*sin(-angle)/(2*9.8);
  text("La alçada màxima és =", 545, 130);
  text(int(alturamax) + " m", 770, 130);  


  pushMatrix();
  translate(50, height/2);
  rotate(radians(angle));
  line(0, 0, vi, 0);
  line(vi, 0, vi-10, -10);
  line(vi, 0, vi-10, 10);
  popMatrix();
  if (launch)
  {
    vyf=vy+g*t;
    dy=dy+vy*t+.5*(vyf-vy)*t;
    vy=vyf;
    dx=dx+vx*t;
    if (dy<height-10)
    {
      time=time+t;
    }
  }
  if (dy>(height-10))
  {
    dy=height-10;
    vy=0;
    vx=0;
    if (dx<770)
    {
      text(int(dx-10)+" m", dx+15, height-2);
    } else
    {
      text(int(dx-10)+" m", dx-110, height-2);
    }
  }
}

void mouseDragged()
{
  if (mouseX > 25 && mouseX < 115  && mouseY > 25 && mouseY < 50 && dx<11)
  {
    angle=-mouseX+25;
  } else if (mouseX > 25 && mouseX < 115  && mouseY > 75 && mouseY < 100 && dx<11)
  {
    vi=mouseX-25;
  }
}

void mouseReleased()
{
  if (dx<11)
  {
    vy=vi*sin(radians(angle));
    vx=vi*cos(radians(angle));
    launch=true;
    time=0;
  }
}

void mousePressed()
{
  launch=false;
  dx=10;
  dy=620;
}

Of course there are plenty of stuff to improve like resetting the array, change the way it is displayed depending on how old the phantom is, save less position so the “phantom tray” has less ellipses, etc.


#3

Thanks, this exactly that I was looking for. A last question, how I clear the screen on the next shot. The first line in draw is background() but seems that didn’t clear the previous track.

Many thanks again


#4

As I wrote at the end there are plenty of things to improve.

Resetting the array will do the trick. I will let you figure out where is the best place to reset it. If you can do it, it means that you probably understand how the code is working.


#5

In java willl be like that

float[] arr = ballTrack;
arr = new float[arr.length];

But in processing i haven’t enough skills to solve this issue.

Thanks again


#6

Processing is Java so if you can do it in Java, you can do it in Processing.

Now what you are refering to is fixed size array. It is not what I used, I used an object call an arrayList.

You can find all the information you need here: https://processing.org/reference/ArrayList.html


#7

I’ve readed the topic but I didn’t find what I’m looking for. In java is easy as ballTrack.clear(), but here in Processing I’m unable to make it so easy. Other option is clearing element by element, but I haven’t found how is done.

Thanks again.


#8

@saotome doesn’t adding

  ballTrack = new ArrayList<PVector>();

to mousePressed() or wherever you want to reset work?


#9

I never realize it was so simple. Thanks again


#10

also can try:

ArrayList<PVector> ballTrack = new ArrayList<PVector>(); // Keep track of the old ball positions

void setup() {
  ballTrack.add(new PVector(mouseX,mouseY));
  println("after add "+ballTrack.size());
  ballTrack.clear();
  println("after clear "+ballTrack.size());

}

many of that possible commands on list can find
https://processing.org/reference/StringList.html


#11

Thanks kll, it’s an other useful way to clear the array list. I have only a question more, how I can now the maximum number of this code

ballTrack.get(i).x

I tryied with max but doesn’t work

Thanaks again


#12

for the length of the array,
actually the answer you can see 10cm up in my example:

for ( int i =0 ; i < ballTrack.size(); i++ ) point( ballTrack.get(i).x,ballTrack.get(i).y);

possibly you not even need to know:

for ( PVector ball : ballTrack ) point(ball.x,ball.y);

speak:
for each item “ball” ( of type PVector ) IN the list “ballTrack” execute …

//_____________________________________________

for finding the biggest .x in the array:

float xmax = 0;
for ( PVector ball : ballTrack ) if (ball.x > xmax ) xmax = ball.x;
println("xmax: "+xmax);

#13

Hi, this is the code I have currently

float dx=10;  // Posició inicial de x
float dy=620; // Posició inicial de y
float vx=0;  // Velocitat inicial de x
float vy=0; // Velocitat inicial de y. y NEGATIU ES AMUNT
float t=.1;  // Increment temps
float g=9.8; // Acceleració de la gravetat. 1 pixel equival a 1 metre
float vyf=0; // Velocitat final
int angle = 0; // Angle inicial
float alturamax; //Alçada máxima
int vi=0;
boolean launch=false;
float time=0.00;
ArrayList<PVector> ballTrack = new ArrayList<PVector>(); // Manté el registre de les el.lipses anteriors

void setup()
{
  size(900, 630);
  smooth();
  background(100);
  frameRate (30/t);
  textSize(20);
  ballTrack = new ArrayList<PVector>();
  ballTrack.add(new PVector(mouseX,mouseY));
  println("after add "+ballTrack.size());
  ballTrack.clear();
  println("after clear "+ballTrack.size());
}

void draw ()
{
  background(100);
  strokeWeight(1);
  fill(255);
  ellipse (50, height/2, 50, 50);

  // Display the previous ball position
  for (int i = 0; i < ballTrack.size(); i++) {
    fill(200);
    ellipse (ballTrack.get(i).x, ballTrack.get(i).y, 20, 20);
  }

  // Pinta la posició actual
  fill(255);
  ellipse (dx, dy, 20, 20);

  // Afegeix la nova posició al array de posicions per a preparar la següent el.lipse
  ballTrack.add(new PVector(dx, dy));
  fill(180);
  rect(25, 25, 90, 25);
  rect(25, 75, 90, 25);
  strokeWeight(6);

  // Escric els textos i els valors
  text ("Les barres es mouen amb el ratolí", 25, 130);
  text ("No funciona amb el teclat", 25, 150);
  line(-angle+25, 25, -angle+25, 50);
  text(-angle+"º", 125, 50);
  line(vi+25, 75, vi+25, 100);
  text(vi+" m/s", 125, 100);
  text("Temps =", 680, 50);
  text(time+" s", 770, 50);
  text("La velocitat inicial és =", 545, 70);
  text(vi +" m/s", 770, 70);
  text("L'angle inicial és =", 585, 90);
  text(-angle +"º", 770, 90); 
  text("La longitud màxima és =", 525, 110);
  text(int(dx-10)+" m", 770, 110);  
  alturamax=(vi*vi*sin(-angle)*sin(-angle))/(2*9.8);
  text("La alçada màxima és =", 545, 130);
  text(int(alturamax) + " m", 770, 130);  

  pushMatrix();
  translate(50, height/2);
  rotate(radians(angle));
  line(0, 0, vi, 0);
  line(vi, 0, vi-10, -10);
  line(vi, 0, vi-10, 10);
  popMatrix();
  if (launch)
  {
    vyf=vy+g*t;
    dy=dy+vy*t+.5*(vyf-vy)*t;
    vy=vyf;
    dx=dx+vx*t;
    if (dy<height-10)
    {
      time=time+t;
    }
  }
  if (dy>(height-10))
  {
    dy=height-10;
    vy=0;
    vx=0;
    if (dx<770)
    {
      text(int(dx-10)+" m", dx+15, height-2);
    } else
    {
      text(int(dx-10)+" m", dx-110, height-2);
    }
  }
}

void mouseDragged()
{
  if (mouseX > 25 && mouseX < 115  && mouseY > 25 && mouseY < 50 && dx<11)
  {
    angle=-mouseX+25;
  } else if (mouseX > 25 && mouseX < 115  && mouseY > 75 && mouseY < 100 && dx<11)
  {
    vi=mouseX-25;
  }
}

void mouseReleased()
{
  if (dx<11)
  {
    vy=vi*sin(radians(angle));
    vx=vi*cos(radians(angle));
    launch=true;
    time=0;
  }
}

void mousePressed()
{
  launch=false;
  ballTrack = new ArrayList<PVector>(); //Reinicio l'ArrayList i esborro el traç anterior
  dx=10;
  dy=620;
}

My concern is to know the max heigh that the ball hass, ie, the max value of the y component of the ArrayList.

Currently I apply this formula, but sometimes didn’t work

alturamax=(vi*vi*sin(-angle)*sin(-angle))/(2*9.8);

But sometimes goes crazy and shows not consistent data

Thanks in advance


#14

this line i would move down after the actual calculation of dx and dy

//
ok in my prior post see the loop for finding xmax,
just change to ymax.


#15

Thanks again, but I’m unable to fit the new code. I will try to insert the commands in the correct place


#16

the problem is NOT to find any max position/value in the array,
the problem is the calculation:
try

  alturamax=(vi*vi*sin(radians(-angle))*sin(radians(-angle)))/(2*9.8);

#17

Solved. Thanks so much…