Setting the linear velocity of an object to hit a specific vertex

I’m trying to fire an object from a specific coordinate in a parabola shape so that it passes through another point as it’s vertex.

I’m using the formula  v2 = 2gy + vi2

where  vi  would be equal to 0

g = gravity and y = Y displacement

Code:

    local xEndPos = 280 local yEndPos = 120     local xStartPos = 60     local yStartPos = 260     local distance = yEndPos - yStartPos     print ("distance " .. distance)     local t = 1 / display.fps     local a = t \* -9.8     local vy = math.sqrt(2 \* a \* distance) \* display.fps -- I don't understand why this is necessary     vy = vy \* -1 -- vx isn't calculated yet either just trying to get y right for now     proj:setLinearVelocity( vx,vy ) 

I should get about -278 as the initial velocity required to hit the End coords but I’m getting close to -396. Can’t work out what I’m doing wrong. Am I using the wrong formula or converting to frames incorrectly. Physics gravity is set to the default -9.8 m/s

Hi @ralph.ward,

The following tutorial (second part) may help you solve this:

https://coronalabs.com/blog/2013/04/09/physics-radial-gravity-and-predicting-trajectory/

Best regards,

Brent

Hi Brent, thanks for the response. I’ve seen the tutorial you linked and I have used it quite a bit already but it doesn’t help in this case unfortunately. 

haven’t tried to run your code, but as a guess… wouldn’t you need to convert dy (aka “distance”) to meters to match g’s SI m/s^2?  (divide by physics scale)

btw, aside, if you work at 30fps and default scale 30ppm, then can sometimes omit certain conversions (if equation is such that the 30ppm will cancel the 1/30s)

gravity is backwards because opengl is backwards (you don’t necessarily notice it if JUST using corona, because EVERYTHING is upside down, and so matches, but just try physics.setGravity(0,-9.8) and watch gravity fall “up”)   so if you’re doing your own calcs in a +y=up cartesian frame, then you must invert y when talking back/forth to corona.

Hi Dave, thanks for the response. I feel like this is probably the correct answer. I don’t fully understand why but I multiplied distance by 0.5 and the answer for the above scenario comes out very close to what I thought would be the correct answer. I guess because 30 / 60 = 0.5… does this seem right?

Code:

local vy = math.sqrt(2 \* a \* (distance \* 0.5))

I’m not in front of my computer now so I can’t test other scenarios. If it works when I get home in a few hours I’ll mark this as the correct answer.

just another quick “drive-by” observation, if helpful - also perhaps odd that you’d be time-scaling g by dt instead of dt^2

I tried out multiplying dy (or distance) by 0.5 which seemed to work perfectly, but I think that’s a bit of a fluke with that working and correct code should be below (where the magic number 30 is equal to pixels per meter)  - it should now work for various screen resolutions and fps. And your drive by comment is correct - should be t^2. Thanks very much for your help dave, I really appreciate it!

    local dy = (yf - y0) \* 30     local dx = (xf - x0) \* 30     local t = 1 / display.fps     local a = t \* t \* -9.8     vy = math.sqrt(2 \* a \* (dy)) \* display.fps \* -1     vx = dx \* math.sqrt(a / (2 \* dy)) \* display.fps     local startingVelocity = { x=vx,  y=vy}

if i find some “tinker time” this wknd i might do so – i have nearly equiv functionality in an app (tho for diff purpose).  fe, your vx calc might very well produce the correct answer, but seems “wordier” than ought be necessary, as vx should in theory just be linear dx/t_y (t_y being delta time from y0 to yf)

[edit] oop, nevermind, sounds like you have it working :slight_smile:

The equation I grabbed to calculate vx is

vx = dx * sqrt(g / (2 * dy))

Not sure if this is the easiest thing to use… I should clean up the code a bit to calculate the conversions outside the main equation and it would make it a bit clearer to read

local dy = yf - y0 \* 30 local dx = xf - x0 \* 30

then vx calc becomes:

vx = dx \* math.sqrt(g / (2 \* dy)) \* 30

Edit: Have updated the code above to be the correct working answer as well, so it can be copied and pasted by anyone else looking for this

non-issue, i think my post was before an edit of yours - vx just maybe slight dup of vy, iirc only one sqrt necessary, but it’s a one time calc at launch so wouldn’t worry about it

Hi @ralph.ward,

The following tutorial (second part) may help you solve this:

https://coronalabs.com/blog/2013/04/09/physics-radial-gravity-and-predicting-trajectory/

Best regards,

Brent

Hi Brent, thanks for the response. I’ve seen the tutorial you linked and I have used it quite a bit already but it doesn’t help in this case unfortunately. 

haven’t tried to run your code, but as a guess… wouldn’t you need to convert dy (aka “distance”) to meters to match g’s SI m/s^2?  (divide by physics scale)

btw, aside, if you work at 30fps and default scale 30ppm, then can sometimes omit certain conversions (if equation is such that the 30ppm will cancel the 1/30s)

gravity is backwards because opengl is backwards (you don’t necessarily notice it if JUST using corona, because EVERYTHING is upside down, and so matches, but just try physics.setGravity(0,-9.8) and watch gravity fall “up”)   so if you’re doing your own calcs in a +y=up cartesian frame, then you must invert y when talking back/forth to corona.

Hi Dave, thanks for the response. I feel like this is probably the correct answer. I don’t fully understand why but I multiplied distance by 0.5 and the answer for the above scenario comes out very close to what I thought would be the correct answer. I guess because 30 / 60 = 0.5… does this seem right?

Code:

local vy = math.sqrt(2 \* a \* (distance \* 0.5))

I’m not in front of my computer now so I can’t test other scenarios. If it works when I get home in a few hours I’ll mark this as the correct answer.

just another quick “drive-by” observation, if helpful - also perhaps odd that you’d be time-scaling g by dt instead of dt^2

I tried out multiplying dy (or distance) by 0.5 which seemed to work perfectly, but I think that’s a bit of a fluke with that working and correct code should be below (where the magic number 30 is equal to pixels per meter)  - it should now work for various screen resolutions and fps. And your drive by comment is correct - should be t^2. Thanks very much for your help dave, I really appreciate it!

    local dy = (yf - y0) \* 30     local dx = (xf - x0) \* 30     local t = 1 / display.fps     local a = t \* t \* -9.8     vy = math.sqrt(2 \* a \* (dy)) \* display.fps \* -1     vx = dx \* math.sqrt(a / (2 \* dy)) \* display.fps     local startingVelocity = { x=vx,  y=vy}

if i find some “tinker time” this wknd i might do so – i have nearly equiv functionality in an app (tho for diff purpose).  fe, your vx calc might very well produce the correct answer, but seems “wordier” than ought be necessary, as vx should in theory just be linear dx/t_y (t_y being delta time from y0 to yf)

[edit] oop, nevermind, sounds like you have it working :slight_smile:

The equation I grabbed to calculate vx is

vx = dx * sqrt(g / (2 * dy))

Not sure if this is the easiest thing to use… I should clean up the code a bit to calculate the conversions outside the main equation and it would make it a bit clearer to read

local dy = yf - y0 \* 30 local dx = xf - x0 \* 30

then vx calc becomes:

vx = dx \* math.sqrt(g / (2 \* dy)) \* 30

Edit: Have updated the code above to be the correct working answer as well, so it can be copied and pasted by anyone else looking for this

non-issue, i think my post was before an edit of yours - vx just maybe slight dup of vy, iirc only one sqrt necessary, but it’s a one time calc at launch so wouldn’t worry about it