HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Gravity and Physics

06-12-2004, 01:31 AM#1
Kaluo
Does anyone have a good way to program a parabolic arc simulating gravity in a unit's movement height? Working on a sphere that travels in a slight arc reaching 300 pixels over a horizontal journey of 850 pixels. I can make it move in a triangular climb/fall by just using 2 changes of height actions but it doesn't look realistic at all. Think of the 'gravity' in that baseball map if anyone has played.
06-12-2004, 02:21 AM#2
johnfn
You should be able to model this via a quadratic model. First you need to find a nice, gradual , curve. Then, you need to set the height to the Y value of f(x) = (x^2 + x...). The X value should be incremented by 1 each time and set the X pos of the unit to X.

If I just told you completely useless information, then dont flame, I was just trying to be helpful.
06-12-2004, 02:41 AM#3
-={tWiStÄr}=-
well... you could do a loop,
variables
real x = 1
real y = 0
point point = default, null whatever
Code:
event - whatever
condition - whatever
actions -
for each integer a 1 to 10 do// the 10 is how long in seconds you want it to take.
set point = polarprojection(get unit position(thespere) offset  1, (angle beetween points(pos of unit and pos of destination)//phew.. that was long, that sets point to a little bit away from the unit
set y = x^2
move unit to point
set unit flying height = y
set x = x + 1
hmm.. i just whipped that up and im not sure exactly what u want so it may not work. on the other hand.. it may not work at all *shrug*
06-12-2004, 04:37 PM#4
Vexorian
Actually,

Code:
//============================================================================================================
function UnitMoveToAsProjectileGen takes unit m, real arc, real x2, real y2, unit target, real z2 returns nothing
//
//   The internal projectile system used by all the projectile functions
//
 local real x1=GetUnitX(m)
 local real y1=GetUnitY(m)
 local real acel=arc*1600
 local real speed=GetUnitMoveSpeed(m) 
 local real z1=GetUnitFlyHeight(m)
 local real d
 local real d1
 local real d2
 local real t
 local real vel
 local real dif=0
 local integer error=0
    if target!=null then
        set x2=GetUnitX(target)
        set y2=GetUnitY(target)
        set z2=GetUnitFlyHeight(target)+z2
    endif
    set d=SquareRoot(Pow(x2-x1,2)+Pow(y2-y1,2))
    set d1=1000000
    set d2=0
    set t=d/speed
    if t==0 then
        set t=0.001
    endif
    set vel=(z2-z1+0.5*acel*t*t)/t
    call SetUnitFacing( m, Atan2BJ(y2 - y1, x2 - x2) )
    call IssuePointOrder( m, "move", x2,y2)
    set t=0
    loop
        set d2=d1
        if target != null then
            set x2=GetUnitX(target)
            set y2=GetUnitY(target)
        endif
        set d1=SquareRoot(Pow(x2-GetUnitX(m),2)+Pow(y2-GetUnitY(m),2))
        exitwhen d1<=speed*(t-dif)
        if target != null then
            call IssuePointOrder( m, "move", x2,y2)
        elseif d1>=d2 then
            call IssuePointOrder( m, "move", x2,y2)
            set error=error+1
        endif
        exitwhen error>2
        set dif=t
        if dif==0 then
           set t=20/speed
           set dif=t
        else
            set t= (d-d1)/speed
        endif
        set t= 2*t-dif
        call SetUnitFlyHeight( m, z1+(vel*t-0.5*acel*t*t), RAbsBJ( vel-acel*(t+dif)/2) )
        set t=(t+dif)/2
        call TriggerSleepAction(0)
    endloop
    if target != null then
        set x2=GetUnitX(target)
        set y2=GetUnitY(target)
    endif
    call SetUnitFlyHeight( m,z2,0)
    call SetUnitPosition(m,x2,y2)
endfunction

which shall be found at my caster system map in my sig if interested
06-14-2004, 04:46 PM#5
Kaluo
I couldn't find that in your caster system... Could you either copy the part that uses it or give an example of a trigger using all that? Sorry, but i'm a bit new to jass and it took me a good 2 days to figure everything in that post out... I'm not really sure how that internal function is called to help establish height.
06-14-2004, 06:44 PM#6
Anitarf
Ok, lets try to explain this simple. A parabolic curve has an equation of x^2. however, this curve starts at point (0,0) and then goes up more and more quickly. What you want is a deformed formula that would go like this:

y(x) = (((-4) * h) / (l^2)) * ((x^2) - (l * x))

Where x is the position of the projectile in it's path, l is the total lenght of the path the projectile must travel, h is the max height the projectile reaches and y(x) is the height the projectile is at when on position x.

In the example you gave, l would be 850 and h would be 300.

For changing the flying height, you would use a periodic trigger, the faster it happens, the more accurate the flying curve will be. Let's say the trigger runs once every f seconds (of course, f would need to be less than a second, maybe one tenth of a second, you can experiment with this), you would change the unit's flying height to what it should be. Since you would be operating with time now, you will need the connection between time and distance, that is the velocity (v), the speed of the projectile (you set this in the object editor).

so, when you launch the projectile, you set x to 0 and activate your periodic trigger, which would do the following:
set variable x = x + (v * f)
change the flying height of the projectile to y(x) over the next f seconds.

The y(x) is the formula written above. You can choose h at will, while l is the distance between the starting point of the projectile and the point where it must hit the ground again.
06-14-2004, 08:13 PM#7
Vexorian
it is in the custom script section above the projectile functions you shall call.

But anyways, you can just use that function to make a flying unit move to a point as if it were a projectile with the arc.
06-15-2004, 02:41 PM#8
TheSnorBlob
Like the ball in this baseball map?
I really wanted to have a look at how he did the ball in that map... but its protected

Can't someone show me how to do this in gui?
06-15-2004, 03:14 PM#9
Kaluo
Quote:
Originally Posted by Anitar
Ok, lets try to explain this simple. A parabolic curve has an equation of x^2. however, this curve starts at point (0,0) and then goes up more and more quickly. What you want is a deformed formula that would go like this:

y(x) = (((-4) * h) / (l^2)) * ((x^2) - (l * x))

Where x is the position of the projectile in it's path, l is the total lenght of the path the projectile must travel, h is the max height the projectile reaches and y(x) is the height the projectile is at when on position x.

In the example you gave, l would be 850 and h would be 300.

For changing the flying height, you would use a periodic trigger, the faster it happens, the more accurate the flying curve will be. Let's say the trigger runs once every f seconds (of course, f would need to be less than a second, maybe one tenth of a second, you can experiment with this), you would change the unit's flying height to what it should be. Since you would be operating with time now, you will need the connection between time and distance, that is the velocity (v), the speed of the projectile (you set this in the object editor).

so, when you launch the projectile, you set x to 0 and activate your periodic trigger, which would do the following:
set variable x = x + (v * f)
change the flying height of the projectile to y(x) over the next f seconds.

The y(x) is the formula written above. You can choose h at will, while l is the distance between the starting point of the projectile and the point where it must hit the ground again.


Here's my copied triggers. First the periodic one

Code:
Flying Sphere
    Events
        Time - Every 0.10 seconds of game time
    Conditions
    Actions
        Set realx = (realx + (realv x 0.10))
        Animation - Change Sphere flying height to (((-4.00 x 300.00) / (Power(850.00, 2.00))) x ((Power(realx, 2.00)) - (850.00 x realx))) at (10.00 x (((-4.00 x 300.00) / (Power(850.00, 2.00))) x ((Power(realx, 2.00)) - (850.00 x realx))))

And the trigger that runs it

Code:
Testing
    Events
        Unit - A unit Begins casting an ability
    Conditions
        (Ability being cast) Equal to Air Shot 
    Actions
        Set Sphere_Units[1] = (Casting unit)
        Wait 0.80 seconds
        Unit - Order Sphere to Move To ((Position of Sphere) offset by 850.00 towards (Angle from (Position of Sphere_Units[1]) to (Position of Sphere)) degrees)
        Trigger - Turn on Flying Sphere <gen>
        Wait 5.00 seconds
        Trigger - Turn off Flying Sphere <gen>
The initial waiting of .8 seconds is to make the casters attack animation line up with the movement of the sphere.

Doing that causes it to move in a really choppy arc. I tried changing it to every .25 seconds and having it update over 1/4 seconds, that made a beautiful arc that stopped when it had peaked, then gone down about 50 pixels. Copy it and see. I'll probably end up using Lord Vexorian's help (thank you for that) but i'd just like to know why this isn't working.