LurkerAspect
Now officially a Super Lurker
- Reaction score
- 118
Sine-wave movement by da1nOnlyEd!
What is it?
Sine-wave movement is a set of mathematical functions making use of trigonometric equations. Basically, it can make an object move in an S-shaped movement, create a curvy line of special effects, and by changing the values, can even duplicate a cluster-rocket-like missile barrage attack. Think of a skiing slalom.
"Sine" in maths is pronounced like "sign" or s-EYE-n, although it's often shown as sin. It is not an evil act, it is a mathematical function in this context.
What do I need to use it?
As far as I know, this function is not dependant on Newgen, so it should even work on vanilla WE, unless you like using privates and scopes.
Let's see it:
JASS:
//real s = step
//real d = distance
//real p = max side-to-side movement
//real c = no. of cycles
//real a = angle to move
function GetSinX takes real s, real d, real a, real p, real c, real X returns real
return (X+s*Cos(a*bj_DEGTORAD))+p*Sin((c*(360*(s/d)))*bj_DEGTORAD)*Cos((a+90)*bj_DEGTORAD)
endfunction
//Gives you your X displacement according to a sin wave, just plug in those values.
function GetSinY takes real s, real d, real a, real p, real c, real Y returns real
return (Y+s*Sin(a*bj_DEGTORAD))+p*Sin((c*(360*(s/d))*bj_DEGTORAD))*Sin((a+90)*bj_DEGTORAD)
endfunction
//Gives you your Y displacement according to a sin wave, just plug in those values.
What..? How do I use that?
Simple. Just plug in the following values:
- real X or Y = the X or Y position of your unit
- real s = your current movement step
- real d = your maximum distance
- real p = the distance of left-right movement
- real c = the number of complete S's to make
- real a = your angle of motion.
um... I still don't get it.
Ok, let's say you were sliding a unit from A to B, and you wanted it to move from side-to-side as well. Then, you would create a sliding trigger, but instead of using [ljass]set offsetX = unitX+step*Cos(angle*bj_DEGTORAD)[/ljass], you would substitute in [ljass]GetSinX(s, d, a, p, c, X)[/ljass] Easy?
...no. Can you show me an example?
Sure, this is the function I used to create the above screenshots:
JASS:
function sinActions takes nothing returns nothing
local unit u = GetTriggerUnit()
local real step = 0
local real uX = GetUnitX(u)
local real uY = GetUnitY(u)
local real tX = GetLocationX(GetSpellTargetLoc())
local real tY = GetLocationY(GetSpellTargetLoc())
local real distance = SquareRoot((uX-tX)*(uX-tX)+(uY-tY)*(uY-tY))
local real angle = bj_RADTODEG*Atan2(tY-uY, tX-uX)
local real oX
local real oY
loop
exitwhen step > distance
set oX = GetSinXa(step, distance, angle, 400, 2, GetUnitX(u))
set oY = GetSinYa(step, distance, angle, 400, 2, GetUnitY(u))
call DestroyEffect(AddSpecialEffect("Abilities\\Weapons\\IllidanMissile\\IllidanMissile.mdl", oX, oY))
set step = step+10
endloop
set u = null
endfunction
Oh cool. Can you explain the math behind that?
Of course. As a lot of JASS programmers know, to get the X and Y values of a point with offset to a certain angle, they have to use [lJASS]Offset = UnitX+OffsetDistance*Cos(Angle*bj_DEGTORAD) /*to get the X value and*/ UnitY+OffsetDistance*Sin(Angle*bj_DEGTORAD) /*for the Y value. [/lJASS]
However, I'm sure that some of you don't know that that set of equations is also doable on a cartesian plane, or a plane with X and Y coordinates, because in essence, that's what a Warcraft map is.
What my equation does is like using one of these offset equations twice in the same line, once to get the offset point, and another to get it's offset according to the sin wave.
So, the first part of the equation, [ljass] (X+s*Cos(a*bj_DEGTORAD))[/ljass], we are calculating this first offset with s being the current distance step from your starting point.
Then, with the [ljass]p*Sin(c(360*(s/d))[/ljass], I am simply working out the offset we'd get according to the current position of the sin wave, multiplying the result and the given X value with p and c respectfully to get the size and length of the sin wave. The complicated bit in the middle turns your step over your distance into a percentage, then gets that percentage of 360 in order to make it work. The last part of the equation simply does what the first bit did, multiplied that value by sin or cos to get the relative offset to that direction.
It's not really advanced mathematics, and is actually quite simple. I had a bit of spare time in class, so I decided to see if I could make such an equation.
You said something about a cluster-rockets effect?
Yes I did. If you wanted to do that, you would set c = 0.5, then it would only do half a wave (ie out and then back in, not out and in and out and in again). Then, you set the amplitude (p) to a random value from a positive to a negative to make the wave invert itself. Then use a jump parabola to get a convincing gravity effect.
Cool. I'd like to know exactly what the variables are, in scientific terms.
Well, in terms of a sin wave, the variables you must input are as follows:
- real X or Y = Your starting X or Y point
- real s = your current distance from the starting point
- real d = the distance from the start to the finishing points
- real a = the angle of motion, or the angle between start and finish.
- real p = the amplitude of the sin wave, the maximum distance of displacement
- real c = the coefficient of the period of the sin wave, a value above 1 will give more repititions. The period is 360/c in this case.
But isn't this a rather slow and strenuous equation?
I thought the same while I was writing it, but I was immensely surprised when I found out it worked effortlessly, even when doing over 100 equations at the same time. If you try this in a normal scientific calculator, there's a small delay, so a full 2.0ghz processor has no problems at all
If I use this in my map, do I have to give credit?
Credit is nice, but it doesn't matter so long as you don't claim that you made these functions. That's really mean.
I really think YOU plagiarised this from someone else!
Naturally, there is no immediate way I can prove to you that I came up with this myself, and I'm sure it's been done before. If you need hard evidence, then I will scan in my maths books and notes for you to see.
I hope you can trust me enough to trust that I made this equation myself.
If you have any suggestions on how I can improve this thread, or if you've spotted a leak, or if it doesn't work for you, or if I haven't given enough information, please don't hesitate to post a reply. I welcome both positive and negative criticism, although I much prefer the positive!
*please note, I don't currently have a pic of a cluster-rocket example with this function. It is expected within the next two days, however.