PVector: setting force of vector to something

Recently 3Blue1Brown posted vid:

calculating PI with physics, and i wanted to recreate it in processing.
I know it would be inacurate representation of it, but i want to challenge myself.
So, how can i set force of vector to something? Pls dont post solution of this problem, so i can do it myself.
I want to apply blue square starting velocity of 1m/s, and than transfer it to white object and so on.

1 Like

Which part of this is giving you trouble? Which step are you stuck on?

As the video says, start with a physics simulator. You will want two masses, both of which will have a position, mass and speed.

Next, you will want a wall. Put the wall at x = 0, so positions are always positive…

Give your masses’ variables initial values.

Simulate the simulation for one step. That is, how do the positions of the masses change?

Next, add logic to simulate collisions.

What happens when the small mass’s position hits the wall at position x=0?

What happens when the large mass’s position hits the small masses’s position?

Will the large mass ever hit the wall?

Did you remember to count the collisions?

Try other initial values!

Here’s a page with some handy formulas…

Bonus question: Does the widths of the masses make any difference? Does their starting positions?

1 Like

Also you should know not all elastic collisions are handled the same and it’s important you find a solution that matches the one in this video. I’d check the links in the video description

DON’T LOOK! This is what I came up with…

float am = 1, as = 0, ap = 10;
float bm = 100, bs = -1, bp = 100;
int c = 0;

void setup(){
  size(800,200);
}

void draw(){
  
  simulate();
  
  background(0);
  fill(200);
  noStroke();
  rect(0,0,20,height);
  translate(20,100);
  stroke(200);
  line(0,0,width,0);
  
  pushMatrix();
  translate(ap,-40);
  rect(0,0,40,40);
  
  popMatrix();
  
  pushMatrix();
  translate(bp+40,-40);
  rect(0,0,40,40);
  
  popMatrix();

  fill(200);
  text( c , 100, 50);
  
}

void simulate(){
  ap += as;
  bp += bs;
  
  if( ap <= 0 ){
    ap = 0;
    as *= -1;
    c++;
  }
  
  if( bp <= ap ){
    float as_t =  ( (am - bm) / (am + bm) ) * as + ( (2 * bm) / (am + bm) ) * bs;
    bs =  ( 2 * am / (am + bm) ) * as + ( (bm - am) / (am + bm) ) * bs;
    as = as_t;
    bp = ap;
    c++;
  }
  
}

Wow.

1 Like

Thx guys! I hope it didnt take u too much time… emm… and if u enjoyed doing it TfGuy, im happy for u :slight_smile:

it didnt make too much sense…

@TfGuy44 's demo helps you see one or two digits. A solution that will allow you to view 4+ digits in a reasonable amount of time (and have the bounces appear within the horizontal screen space) is going to have to incorporate things that account for the exponential number of frames to display it.

There are many ways to approach that. For example, have simulate loop n number of times in a single frame,

steps = 8;
//...
simulate(steps);
//...

void simulate(int steps) {
  for (int i=0; i<steps; i++) {
  //...

…perhaps scale the horizontal output based on the number of degrees requested?

float scale = 1;
//...
scale = scale * 1/digits;
//...
translate(scale * (bp+40), -40);

Also, adjust the frameRate()

frameRate(120);

…et cetera.

well 3Blue1Brown has made a vid with better way to solve it

I don’t know what that means.

The video renders e.g. 314 clacks, then shows them again in slow motion, then shows them in groups of billion billions.

I was suggesting some ways to produce output like the video output, “recreate it in processing” – which was your question. Some ideas are multi-pass frames (which could be algorithmic), scaling, and frameRate control.