• 🏆 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!

[vJASS] TrigoTable

AGD

AGD

Level 16
Joined
Mar 29, 2016
Messages
688
A short snippet for optimized usage of the three common trigonometric functions - Sin(), Cos, and Tan() in loops with constant angle steps. Could be useful for spells and systems that deal with a lot of circular objects.


Pro:
- Replaces your trigonometric functions with a couple of array reads without any trade-off for accuracy


Trigo Table
JASS:
library TrigoTable /* v1.0.1 https://www.hiveworkshop.com/threads/324557/


    */uses /*

    */optional ErrorMessage /*  https://github.com/nestharus/JASS/blob/master/jass/Systems/ErrorMessage/main.j


    *///! novjass

    |-----|
    | API |
    |-----|

        struct SinTable extends array
        struct CosTable extends array
        struct TanTable extends array

            readonly real step/*
                - Measured in radian

          */static method operator [] takes integer stepCount returns thistype/*
                - Returns a Trigo function table

          */method operator [] takes integer i returns real/*
                - Returns the Sin/Cos/Tan of <step*i> radians


    *///! endnovjass

    /*==========================================================================================*/
    globals
        /*
        *   This is important to be set correctly for the system to adjust to JASS_MAX_ARRAY_SIZE
        */
        private constant boolean PATCH_PAST_1_29 = false
    endglobals
    /*==========================================================================================*/

    static if DEBUG_MODE then
        private function AssertError takes boolean condition, string methodName, string structName, integer node, string message returns nothing
            static if LIBRARY_ErrorMessage then
                call ThrowError(condition, SCOPE_PREFIX, methodName, structName, node, message)
            endif
        endfunction
    endif

    //! textmacro TRIGO_TABLE_STRUCT takes FUNC
    struct $FUNC$Table extends array

        private integer arrayStep
        private static real array table
        private static thistype array instance

        private method initTable takes integer count returns nothing
            local real step = (2.00*bj_PI)/count
            static if PATCH_PAST_1_29 then
                local integer arrayStep = R2I(step*5000)
            else
                local integer arrayStep = R2I(step*1250)
            endif
            set this.arrayStep = arrayStep
            loop
                exitwhen count == 0
                set table[count*arrayStep] = $FUNC$(count*step)
                set count = count - 1
            endloop
        endmethod

        method operator step takes nothing returns real
            static if PATCH_PAST_1_29 then
                return this.arrayStep/5000.00
            else
                return this.arrayStep/1250.00
            endif
        endmethod

        method operator [] takes integer i returns real
            debug call AssertError(this == 0, "operator []", "thistype", 0, "Null node")
            return table[i*this.arrayStep]
        endmethod

        static method operator [] takes integer count returns thistype
            local thistype node
            static if LIBRARY_ErrorMessage then
                debug call AssertError(count <= 0, "static operator []", "thistype", 0, "Invalid step count (" + I2S(count) + ")")
            else
                if count <= 0 then
                    return 0
                endif
            endif
            set node = instance[count]
            if node == 0 then
                set node = instance[0] + 1
                set instance[0] = node
                set instance[count] = node
                call node.initTable(count)
            endif
            return node
        endmethod

    endstruct
    //! endtextmacro

    //! runtextmacro TRIGO_TABLE_STRUCT("Sin")
    //! runtextmacro TRIGO_TABLE_STRUCT("Cos")
    //! runtextmacro TRIGO_TABLE_STRUCT("Tan")


endlibrary

JASS:
local integer count = circularBorderPoints
local real targetX = GetSpellTargetX()
local real targetY = GetSpellTargetY()
local real radius = SpellRadius()
local SinTable sin = SinTable[count]
local CosTable cos = CosTable[count]

...
// sin[0] == sin[count] == Sin(2*bj_PI), same with the other two trigo functions
loop
    exitwhen count == 0
    set this.borderEffectTable[count] = AddSpecialEffect(BORDER_SFX_MODEL, targetX + radius*cos[count], targetY + radius*sin[count])
    set count = count - 1
endloop


v1.0.1
- Restructured code

v1.0.0
- Initial release
 
Last edited:

AGD

AGD

Level 16
Joined
Mar 29, 2016
Messages
688
I would vote for this to be graveyarded. The speed gain would probably be very insignificant if there ever is. The only possible benefit you can gain from this is that it would remove the need for users to do any arithmetics involving the angles and instead they would only need specify the number of points in the circle. But I don't think it's worth a separate library of this size.
 
Top