0

I am creating a circular motion simulation, where a box of mass m hangs freely on a string. A force will then be applied to the box which will either put it in circular motion, or put it in weird motion depending on the strength of the force applied.

The rope physics works fine - at least it looks ropelike, and I used a Verlet algorithm based upon suggestions from other threads on stackoverflow and various YouTube videos after failing to apply a forces and angles based approach. This is the first time I have used this method.

The problem is that the time dependency doesn't seem to work correctly, its far too slow. I have created a stack blitz with the base code for this part of the sim. Without timeSimSpeed it looks ropey and like I would expect in real life, except far too fast.

I assumed it is something to do how I applied the force and time dependency to the sim:

processPoints2() {
    for(var i = 0; i < this.points.length; i++) {
        var p = this.points[i];
        var timeSimSpeed = ((this.elapsedSinceFrame + this.previousElapsedSinceFrame) / 2000) * this.simulationSpeed;

        if(!p.fixed) {
            var vx = (p.x - p.oldx);
            var vy = (p.y - p.oldy);
            p.oldx = p.x;
            p.oldy = p.y;
            p.x += vx * timeSimSpeed;
            p.y += (this.gravity + vy) * timeSimSpeed;
        }          
    }
}

But this, logically at least, seems to make sense to me. Elasped and previousElasped are in ms and averaged which is why I have 2000 there, but even using only the current frame speed its the same outcome. I'm not familiar enough with Verlet methods to be able to work through the mathematics of whether the sticks could be restricting the motion and creating this speed issue.

Any help is much appreciated, even if it is a link to somewhere this has been addressed before that I have failed to see.

EDIT:

OK so after a bunch of comments on this I have gotten around to make some modifications. I have dropped the weird way of calculating velocity and am explicit with that now, and have also been explicit with the distance units (before it was 1 pixel per meter, but this is now defined, and I changed it to 10meters per pixel. I have also updated my stackblitz.

You will notice there are still some errors (the rope has no maximum extension and will keep stretching!) but the major one for me is that it still doesnt fall under gravity correctly...

The processing looks a lot simpler now:

processPoints2() {
    for(var i = 0; i < this.points.length; i++) {
        var p: point = this.points[i];
        var timeSimSpeed: number = (this.elapsedSinceFrame / 1000) * this.simulationSpeed;

        if(!p.fixed) {
           p.vx += p.ax * timeSimSpeed;
           p.vy += p.ay * timeSimSpeed;
           p.x += p.vx * this.pixelsPerMeter * timeSimSpeed;
           p.y += p.vy * this.pixelsPerMeter * timeSimSpeed;
        }          
    }
}

As it just uses a classical method of calculating velocity and position.

Any help would continue to be appreciated. It has been pointed out that this isnt verlet so I have amended the title and tags to appropriately represent the question.

bouteillebleu
  • 2,456
  • 23
  • 32
Bogomip
  • 417
  • 6
  • 22
  • 2
    `this.gravity + vy` looks wrong from the physics standpoint. You cannot add values of incomparable units. – user58697 Nov 08 '20 at 19:21
  • Eugh, simple things - you're right, cant add things with two different units. Thanks, this has solved it - I will add an answer below. – Bogomip Nov 09 '20 at 07:01
  • what you are doing is standard rectangular numeric integration of Newton/d'Alembert equations... [Verlet integration](https://en.wikipedia.org/wiki/Verlet_integration) has different equations for integration: `Vec3d new_pos = pos + vel*dt + acc*(dt*dt*0.5); Vec3d new_acc = apply_forces(); Vec3d new_vel = vel + (acc+new_acc)*(dt*0.5); pos = new_pos; vel = new_vel; acc = new_acc;` as you can see you are using just `dt` (timesimspeed) instead of `0.5*dt^2` therms ... of coarse your integration is correct (I use it heavily too) but its not verlet – Spektre Nov 09 '20 at 09:01
  • see: [physics engine - phase order and other general information](https://stackoverflow.com/a/26584358/2521214) , [How to implement a constraint solver for 2-D geometry?](https://stackoverflow.com/a/40827518/2521214) , [Newton - D'ALembert physics for non relativistic speeds](https://stackoverflow.com/a/19764828/2521214) , [Is it possible to make realistic n-body solar system simulation in matter of size and mass?](https://stackoverflow.com/a/28020934/2521214) and [Can't flip direction of ball without messing up gravity](https://stackoverflow.com/a/53637567/2521214) for inspiration – Spektre Nov 09 '20 at 09:09
  • Ok so after some testing I go back on what I said, the line seemed realistic on the scale on the screen but upon further investigation it was moving far too fast - answer sadly deleted. Thanks Spektre for the links, I tried your integration but that also did not work - but I'm going to make velocity explicit because I'm unhappy with the way I currently deal with velocity and think it could be messing things up. – Bogomip Nov 09 '20 at 10:23
  • The code in my first comment is not mine intergration its the verlet from wiki ... the last link in my previous comment is example doing almost the same as you are doing now (has added collision detection) you got 2 problems. 1. no scale which means your units are not SI so your constants are also not SI that means `g!=9.81` I would use SI and then apply scale to view area from SI `[m]` into `[pixels]`. 2. your velocity is not global variable and its initialized every iteration that is wrong as you lose accuracy each iteration. `timeSimSpeed` should be timer or update interval in `[seconds]` – Spektre Nov 09 '20 at 14:19
  • Thanks Spektre. The scale was 1px/m thus I just omitted it. This wasnt a great move as it confused the sim (and was not in line with other simulations) and so I added it (then made it 10pm/m!). I also took your advice and made velocity explicit. This is something I had done previously but followed a tutorial on rope physics for this and so did it another persons way. Changed back to how I like to work now. timeSimSpeed is in second. Elapsed is a ms value and the simulation speed is unitless :) Thanks so much for your help. – Bogomip Nov 18 '20 at 10:31

0 Answers0