• 💀 Happy Halloween! 💀 It's time to vote for the best terrain! Check out the entries to Hive's HD Terrain Contest #2 - Vampire Folklore.❗️Poll closes on November 14, 2023. 🔗Click here to cast your vote!
  • 🏆 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!
  • 🏆 HD Level Design Contest #1 is OPEN! Contestants must create a maze with at least one entry point, and at least one exit point. The map should be made in HD mode, and should not be openable in SD. Only custom models from Hive's HD model and texture sections are allowed. The only exceptions are DNC models and omnilights. This is mainly a visual and design oriented contest, not technical. The UI and video walkthrough rules are there to give everyone an equal shot at victory by standardizing how viewers see the terrain. 🔗Click here to enter!

Fixed Velocity Spiral

Not open for further replies.
Level 4
May 2, 2019
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:


While a fixed velocity spiral path looks more like:

//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

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

//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
        exitwhen a < bj_E
        set a = a/bj_E
        set sum = sum + 1.
    return sum + (a-1.)*(1. + 8./(1.+ a) + 1./a)/6.

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

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)

        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)

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:
Not open for further replies.