• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

[JASS] Math of Curving Projectile

Status
Not open for further replies.
Level 3
Joined
Sep 3, 2004
Messages
50
I am looking to understand the math behind creating a projectile that can curve given 3 defined points. So for example, let's say a hero is casting some spell:

JASS:
    local unit u = GetTriggerUnit()
    local player p = GetOwningPlayer( u )
    local real a = GetUnitFacing( u )
    local real x1 = GetUnitX( u )
    local real y1 = GetUnitY( u )
    local real deg = (3.14159265/180)
    local real x2 = (x1 + 290 * Cos((a - 50) * deg))
    local real y2 = (y1 + 290 * Sin((a - 50) * deg))
    local real x3 = (x1 + 750 * Cos((a - 3) * deg))
    local real y3 = (y1 + 750 * Sin((a - 3) * deg))

So pretty much I just defined 3 points of [x1, y1], [x2, y2], [x3, y3]. It should be obvious that the projectile would start at [x1, y1] and curve towards [x2, y2] (the maxima or minima I believe?) then curve towards [x3, y3]. I'm hoping there is some mathematical formula I could use without having to use If/Then/Else.

Also, I'm not looking for any editor addons or projectile systems, I'm looking to understand the math behind this problem.
 
Level 17
Joined
Jul 17, 2011
Messages
1,864
exactly what curve do you want to achieve you can have a 2d curve where the projectile will spin in a circle on the ground or a 3d curve such as a mortar team projectile for those you can use parabola equations this code that you have here will only get you location values such as if x1 is 200 x2 will be about 157
 
Level 3
Joined
Sep 3, 2004
Messages
50
I'm asking about the 2D curve, but if anyone has information about the 3D curve I'd love to hear about that too (It is pretty easy to just get a dummy unit to throw a projectile and make it come down like a parabola in the Warcraft engine, but I'd be interested in knowing the actual math behind that too).
 
Level 17
Joined
Jul 17, 2011
Messages
1,864
well to make a general 2d parabola on an x/y plane you will use y=ax^2 where x and y are negative or positive vertices for any given point on the parabola. the a determines in which way the parabola points if a is positive then the parabola will point up if a is negative it will point down a will be determined by the formula a=1/4y where y is a vertex of any point on the parabola

so if y = 2 then a will be 1/4*2 = .125


say you start from a point x= -2 and y = -3, then your y or the parabola's arc will either increase or decrease with .125*(-2)^2 or 0.5 so for your trigger use something like
[trigger=a trigger]Untitled Trigger 001
Events
A Unit Begins Casting an Ability

Conditions
Actions
Set X = (X of (Position of (Triggering unit)))
Set Y = (Y of (Position of (Triggering unit)))
[/trigger]
[trigger=trigger2]
Untitled Trigger 002
Events
Time - Every 0.05 seconds of game time
Conditions
Actions
Set Y = (a * (Square root(X)))
Set a = (1.00 / (4.00 * Y))
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
X Less than 0.00
Then - Actions
Set X = (X - 1.00)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
X Greater than 0.00
Then - Actions
Set X = (X + 1.00)
Else - Actions
Unit - Move (Triggering unit) instantly to ((Center of (Playable map area)) offset by (X, Y)), facing Default building facing degrees[/trigger]
if you where to use this for an ability then it will look somewhat odd since the parabola will only go in one direction
Unfortunately i dont know of a way to do this without if then else as wc3 has no other way of telling positive or negative values but this should give you some general idea of what a 2d parabola will look like

a much simpler way to do this would be to use angels and a point with offset but this will give the same arc each time unless you dynamically change the values:
[trigger=triggeranother]
CIrcle
Events
Time - Every 0.01 seconds of game time
Conditions
Actions

Set angle = (angle + 7)
Unit - Move (Triggering unit) instantly to Point offset by 450.00 towards angle degrees)
[/trigger]
this will only move the unit in a circle however if you decrease or increase the 7 using a static set of values then you can produce an ellipse for example
by a static set i mean something like
2,2
5,5
6,6
9,9
6,6
5,5
2,2
 

Cokemonkey11

Spell Reviewer
Level 30
Joined
May 9, 2006
Messages
3,540
I am looking to understand the math behind creating a projectile that can curve given 3 defined points. So for example, let's say a hero is casting some spell:

JASS:
    local unit u = GetTriggerUnit()
    local player p = GetOwningPlayer( u )
    local real a = GetUnitFacing( u )
    local real x1 = GetUnitX( u )
    local real y1 = GetUnitY( u )
    local real deg = (3.14159265/180)
    local real x2 = (x1 + 290 * Cos((a - 50) * deg))
    local real y2 = (y1 + 290 * Sin((a - 50) * deg))
    local real x3 = (x1 + 750 * Cos((a - 3) * deg))
    local real y3 = (y1 + 750 * Sin((a - 3) * deg))

So pretty much I just defined 3 points of [x1, y1], [x2, y2], [x3, y3]. It should be obvious that the projectile would start at [x1, y1] and curve towards [x2, y2] (the maxima or minima I believe?) then curve towards [x3, y3]. I'm hoping there is some mathematical formula I could use without having to use If/Then/Else.

Also, I'm not looking for any editor addons or projectile systems, I'm looking to understand the math behind this problem.

If you want to make "any" curve that goes through all the points, you can use the best fit polynomial function, but you'll quickly see that this is not what you want for an effect/projectile in a spell (imagine the points {(128.,128.),(130.,512.),(512.,256.)}) because the slope between some two points may approach infinity.

What do you think of instead of defining a mathematical equation for the path of the projectile, to create a piece-wise function?

JASS:
constant real ACCELERATION=5. //replace this with however quick you'd want the projectile to shift directions
boolean hasReachedPoint1=false
boolean hasReachedPoint2=false
boolean hasReachedPoint3=false
real vX
real vY

then calculate in each iteration to make the projectile move towards each point with some if/then logic.

That's how I'd personally do it because I think it would look great, even if it's not "best fit", nor constant velocity result.

If you want to do a best fit, smooth curve, I'm thinking you'll have to do some differential equations as well as calculate closest curves and such.

Hope that helps.
 
Status
Not open for further replies.
Top