• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Fixed Velocity Spiral

Status
Not open for further replies.
Level 4
Joined
May 2, 2019
Messages
15
There are many spells which move in a spiral pattern, but they pretty much all use a fixed angular velocity as they spiral out. This means the movement itself increases in speed as it gets further and further away from the center.

I've written a function that allows a spiral path to be traced at a fixed velocity, rather than a fixed angular velocity.
For comparison, using fixed angular velocity spawns points along a path like this:

firefox_G99KxgPczZ.png

While a fixed velocity spiral path looks more like:
firefox_5nvUTSYtY3.png

JASS:
//l is the length of the spiral
//a is the distance between the "rings" of the spiral
function GetSpiralAngle takes real l, real a returns real
    local real sq
    local real phi = 3.544907*SquareRoot(l/a) //first guess 2*sqrt(pi)*sqrt(l/a)
    local real fx
    local real gx
    local real ap = a*0.159155  // a/2pi
    local real ap2 = a*0.079577 // a/4pi

    //newton's method iteration 1
    set sq = SquareRoot(1+phi*phi)
    set fx = ap2*(phi*sq+Ln(phi+sq))-l
    set gx = ap*sq
    set phi = phi-fx/gx

    //newton's method iteration 2
    set sq = SquareRoot(1+phi*phi)
    set fx = ap2*(phi*sq+Ln(phi+sq))-l
    set gx = ap*sq
    set phi = phi-fx/gx

    return phi
endfunction

Where Ln() is the natural log function, which I conveniently plagiarized from elsewhere.

JASS:
//stolen from https://www.hiveworkshop.com/threads/snippet-natural-logarithm.108059/
//credits to BlinkBoy
//range is [1,+inf)
//since Ln is only ever used in one place, and the range is actually always within 1 to +inf, use this version instead of a safer/slower one
function Ln takes real a returns real
    local real sum = 0.0
    loop
        exitwhen a < bj_E
        set a = a/bj_E
        set sum = sum + 1.
    endloop
    return sum + (a-1.)*(1. + 8./(1.+ a) + 1./a)/6.
endfunction

Here's a demonstration of using this in wc3 to draw spirals
Warcraft_III_R0O7xzSOMX.png

JASS:
function Trig_spiral_Actions takes nothing returns nothing
    local integer counter = 0
    local real speed = 80
    local real radius = 500
    local real loops = 5
    local real x = 0
    local real y = 0
    local real angle = 0
    local real currentradius = 0
    local real length = 0
    call AddSpecialEffect("Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl",x,y)

    loop
        exitwhen angle >= bj_PI*2*loops
        set currentradius = radius*angle/(2*bj_PI*loops)
        call AddSpecialEffect("units\\nightelf\\Wisp\\Wisp.mdl",x+currentradius*Cos(angle),y+currentradius*Sin(angle)) //use negative angle value for clockwise spirals
        set length = length+speed
        set angle = GetSpiralAngle(length,radius/loops)
    endloop
endfunction

There are probably better ways to get a first guess, and do root finding, but I don't know what they are and/or how they would be implemented.
If there are any related resources, or if this has actually already been done somewhere in the depths of wc3 mapmaking, please let me know so that I can never post again, out of embarrassment.
 
Last edited:
Status
Not open for further replies.
Top