11

Or, perhaps, better, what does it mean?

What the units are supposed be?

If I'm trying to simulate friction against the "background", like this:

return this
    .velocityDirection
    .mult(mu * this.mass * g)
    .negate();

I expect to use g as 9.80665 m/s^2. It was working this way before PhysicsJS:

var
    frictionForce;
    frictionForce = vec2.create();
    vec2.scale(
        frictionForce,
        vec2.negate(
            frictionForce,
            this.velocityDirection
        ),
        mu * this.mass * g
    );
return frictionForce;

Was using glMatrix for my linear algebra.

I was considering mass in kilograms and forces in newtons (etc) but in PhysicsJS it doesn't seem to work like that. (For example: if I have a circle body with radius 1, it's 1 what? Cause it'll make difference when I have to use this value for something else, and when "converting" it to pixels on the screen)

Now that I'm using a physics library I feel like I'm missing some of the physics...

I Hope someone can point me in the right direction to understand it better. I'm going through the API Docs right now and learning a lot but not I'm finding the answers I'm wishing for.

UPDATE

I received a very straightforward answer. This is just to let anyone interested to know what I did then...

Thanks to Jasper and dandelany I came to understand how some of PhysicsJS works much much better. To achieve my "dream" of using inputs in newtons, metres per second squared (etc) in PhysicsJS (and also have configurable pixels per metre ratio) I decided to create another integrator.

It's just a slight variation of the original (and default) verlet integrator. I explain it, more or less, at this (crude) article Metres, Seconds and Newtons in PhysicsJS

slacktracer
  • 6,262
  • 6
  • 28
  • 33
  • Probably just a value that "works". Treating pixels as real world units is tricky, especially in a game. Imagine "1 pixel = 1 ft" -- how much must this gravity constant be in pixels/sec² to fall a certain distance in a reasonable amount of time? Easier just to try different values until it appears right :-) – Jongware May 16 '14 at 21:35
  • @Jongware wow... I really don't want to believe it. =P Previously I was handling the movement by myself and was "using" the usual units (at least, relative to each other). I just set 1 metre equal 50 pixels and everything worked out just fine. But at any time I could adjust this relation manually. And then I could simulate real forces with realistic values. As Burak Kanber does (http://burakkanber.com/blog/modeling-physics-javascript-gravity-and-drag/)... I ain't giving up yet. =) – slacktracer May 16 '14 at 22:53

3 Answers3

6

The units are pixels for distance, and milliseconds for time.

So the acceleration is 0.0004 pixels/ms/ms

Using meters doesn't make sense for a variety of reasons. The number of pixels per inch changes depending on device. Also, even if you did the conversion, an acceleration of 9.8 m/s/s would appear to be really fast because usually computer simulations want to give the appearance of looking at it from a distance... so you wouldn't want a meter on the screen to correspond to a meter in the simulation.

Jasper
  • 1,193
  • 1
  • 9
  • 14
  • 1
    What does acceleration have to do with the distance of looking at the object that is accelerated? – Bergi May 17 '14 at 16:51
  • Sure, I don't want a metre on the screen be a metre on the simulation. I just want choose how many pixels should a metre be. If I'm able to consider the usual units (newtons, metres, seconds, metres per second squared etc) are in play, my simulation will be just like "the real world" I would only have to choose: how many pixels are a metre (it would account for the "distance" I'm looking from. Say, from "here" a 180 centimetres person is 50 pixels tall (for example), and everything else will follow... Am I really missing something obvious that makes it inappropriate or unfeasible? – slacktracer May 18 '14 at 17:47
  • You can make those conversions if you want, but it will be highly dependent on screen resolution, and it will also likely look weird. It will look like you placed objects literally on top of your screen. They will fall extremely quickly. Generally most applications want to create a scene that is as if you are looking at it from a distance away. Not right in front of your eyes. It's a matter of perspective. – Jasper May 19 '14 at 15:28
  • I really don't get it, @Jasper. To me this conversion is the perspective. First I say this one metre tall box will have 50 pixels, then my camera, my perspective zooms out and now it has 10 pixels. I doesn't matter for my simulation. If the box is moving two metres per second to the right it will keep moving two metres per second to the right and now it'll mean 20 pixels per second to the right (ok, I'm thinking in a square). Anyway. I have my answer now. And new questions. If you have any tips on doing the conversion I really appreciate. Thank you very much. – slacktracer May 19 '14 at 17:42
  • Sorry to insist. I guess I wish to be understood. =P Last words. Promise. How everything translate to pixels is a rendering problem and not a physics matter... Thank you very much again. Bye. – slacktracer May 19 '14 at 23:22
  • What you've said is exactly correct. But instead of making the default perspective be 1:1, we make the default perspective look as if you're looking from a distance, because that is more commonly needed. You can scale it yourself as needed. – Jasper May 31 '14 at 15:49
  • @Jasper Hey, I'm trying an approach to achieve my objectives and wrote about it: https://coderwall.com/p/ntb6bg If you ever have time to check it out I would love to hear your feedback. (As my approach may have a lot of unexpected (to me) consequences...) Thank you. – slacktracer Jun 11 '14 at 21:53
5

Apparently I can't comment on posts yet so here's a follow-up to Jasper's answer, since you asked for tips on making the conversion:

Jasper gives the units as 0.0004 px/ms/ms (or px/ms^2). Knowing the units makes this conversion pretty straightforward using unit cancellation. First we convert that figure to px/s^2:

0.0004 px/ms^2 * 1000 ms/s * 1000 ms/s = 400 px/s^2

Since we know that gravity on Earth is ~9.8 m/s^2, this means that the default value is simulating a scale of:

400 px/s^2 * (1/9.8) s^2/m ~= 41 px/m

So with the default setting, PhysicsJS is simulating a world where a meter is 41 pixels long. If we use your example where "a 180 centimetres person is 50 pixels tall", then we are converting to a scale of:

50px / 0.180m ~= 278px/m

Convert this back to px/ms^2 with an acceleration of 9.8 m/s^2 and you get:

278 px/m * 9.8 m/s^2 * (1/1000) s/ms * (1/1000) s/ms ~= 0.00272 px/ms^2

So, to simulate a world where a 180cm person is 50px tall, you'd use 0.00272 for the PhysicsJS y-acceleration parameter.

dandelany
  • 71
  • 3
  • 1
    Yeah. =) I thought about it for a few days and came to a similar understanding (yours is more thorough). I also went through the source code and found a way to, not only use my preferred units, but make the pixels per meter ratio configurable. Seems a nice way to zoom in and out, among other things. I will have time to deal with it again next week and intend to write a few lines and make a few demos. I'll update my question then... Thank you very much! Every bit makes my thoughts clearer. – slacktracer Jun 06 '14 at 21:33
  • Hey, I wrote that "few lines": https://coderwall.com/p/ntb6bg If you ever have time to check it out I would love to hear your insights! – slacktracer Jun 11 '14 at 21:43
0

From PhysicsJS Basic Usage - Behaviors

// add some gravity
var gravity = Physics.behavior('constant-acceleration', {
    acc: { x : 0, y: 0.0004 } // this is the default
});

You have control over how gravity works, but it doesn't seem to provide a unit reference.

adamdc78
  • 1,153
  • 8
  • 18
  • But why? 0.0004 what? – slacktracer May 16 '14 at 22:45
  • It's your world; I believe it's for you to decide. – adamdc78 May 19 '14 at 19:05
  • That can't be right. =) If I want to simulate some specific drag I need specific and consistent units. `return this.velocityDirection.mult(-0.5 * rho, this.dragCoefficient * this.area * this.body.state.vel.clone().normSq());` If my area is on metres squared (as it is) and my velocity on pixels per millisecond (as it seems to be) I will have problems. Big problems, unfortunately. – slacktracer May 19 '14 at 19:20
  • 1
    In that case you'd want to convert your area to pixels squared (no idea how you'd do that to account for scaling and display resolution) before passing it in to the method, wouldn't you? I've not actually used the library, but that's what I would do. I wish I could be more useful. – adamdc78 May 19 '14 at 21:10
  • Thank you anyway, @adamdc78. =) I haven't thinked about converting to pixels... I don't know. I will try to wrap my head around it... Will see if there is a efficient way to do all the conversions and keep the flexibility with PhysicsJS... – slacktracer May 19 '14 at 23:06