Trigonometry >.<

Trollvottel

never aging title
Reaction score
262
So, im making a sfx system. It should create a ring of dummy units and then be able to turn, be attached to units, move to points, etc. and everything including the z-axis. So that is the code i came up with.

JASS:

library TE uses TT, UsedFuncs

globals
    // Maximum of Units each Figure
    private constant integer MAXUNITS = 40

endglobals


// put in desired custom struct members or methods (only advanced)
//! textmacro TEStructMembers
    
//! endtextmacro

// this will be done everytime the timer runs (only advanced)
//! textmacro TEPeriodic

//! endtextmacro

public struct Figure
    private real    TE_cx     
    private real    TE_cy
    private real    TE_cz
    private real    TE_radius
    private real    TE_nface
    private real    TE_zface
    private real    TE_offset
    private integer TE_number
    private unit    array TE_member[MAXUNITS]
    private real    array TE_sin[MAXUNITS]
    private real    array TE_cos[MAXUNITS]
    
    
    private boolean TE_zturning = false
    private real    TE_zturnage
    
    private boolean TE_nturning = false
    private real    TE_nturnage
    
    private boolean TE_attached = false
    private unit    TE_towhich
    
    private boolean TE_moving   = false
    private real    TE_wherex
    private real    TE_wherey
    private real    TE_wherez
    private real    TE_moverate
    
    //! runtextmacro TEStructMembers()
    
        method GetX takes nothing returns real
            return .TE_cx
        endmethod
    
        method GetY takes nothing returns real
            return .TE_cy
        endmethod
    
        method GetZ takes nothing returns real
            return .TE_cz
        endmethod
        
        method SetZAngle takes real Z returns nothing
            set .TE_zface = Z
        endmethod
        
        method SetNAngle takes real N returns nothing
            set .TE_nface = N
        endmethod
        
         method StartZTurn takes real rate returns nothing
            set .TE_zturning = true
            set .TE_zturnage = rate * TT_PERIOD
        endmethod
        
        method StartNTurn takes real rate returns nothing
            set .TE_nturning = true
            set .TE_nturnage = rate * TT_PERIOD
        endmethod
 
        method Attach takes unit whichto returns nothing
            set .TE_attached = true
            set .TE_moving = false
            set .TE_towhich = whichto
            set .TE_cz = .TE_radius
        endmethod
        
        method UnAttach takes nothing returns nothing
            set .TE_attached = false
        endmethod
        
        method MoveTo takes real x, real y, real z, real rate returns nothing
            set .TE_moverate = RAbsBJ(rate) * TT_PERIOD
            set .TE_wherex = x
            set .TE_wherey = y
            set .TE_wherez = z
            set .TE_attached = false
            set .TE_moving = true
        endmethod
        
        method GetUnitsInRange takes nothing returns group
            local group g = CreateGroup()
            local group swap = CreateGroup()
            local unit u
            local real dx
            local real dy
            local real dz
            call GroupEnumUnitsInRange(g, .TE_cx, .TE_cy, .TE_radius, AliveFilter)
            
            loop
                set u = FirstOfGroup(g)
                exitwhen u == null
                
                set dx = GetUnitX(u) - .TE_cx
                set dy = GetUnitY(u) - .TE_cy
                set dz = GetUnitZ(u) - .TE_cz
                
                if dx*dx + dy*dy + dz*dz &lt;= .TE_radius * .TE_radius then
                    call GroupAddUnit(swap, u)
                endif
            
            endloop
            call DestroyGroup(g)
            set g = null
            
            return swap
        endmethod
        
        static method create takes integer rawcode, player owner, real x, real y, real z, real radius, real nface, real zface, integer edges returns Figure
            local Figure init   = Figure.allocate()
            local real offset   
            local integer i     = 0
            local real      x0
            local real      y0
            local real      z0
            local real      zangle
            local real      height
            local real      angle
            local real      anglez
            local real      distance
            local real      x1
            local real      y1
            
            //save:
            if rawcode == 0 or rawcode == null then
                call BJDebugMsg(&quot;TE System Error: Null rawcode!&quot;)
            endif
            
            if owner == null then
                set owner = Player(15)
            endif
            
            set radius = RAbsBJ(radius)
            set edges = IAbsBJ(edges)
            
            //system:
            call MoveLocation(UsedFuncs_loc, x, y)
            set height = GetLocationZ(UsedFuncs_loc)
            
            set init.TE_cx         = x
            set init.TE_cy         = y
            if z &gt;= radius then
                set init.TE_cz     = z
            else 
                set init.TE_cz     = radius
            endif
            set init.TE_radius     = radius
            set init.TE_nface      = nface
            set init.TE_zface      = zface
            
            if edges &lt;= MAXUNITS then
                set init.TE_number     = edges
            else
                set init.TE_number = MAXUNITS
            endif
            set offset = 360. / init.TE_number 
            set init.TE_offset = offset
            loop
                exitwhen i &gt;= init.TE_number
                set zangle = offset  * i 
                set init.TE_cos<i> = Cos(zangle * DTR)
                set init.TE_sin<i> = Sin(zangle * DTR)
                set x0 = x           + radius * init.TE_cos<i> * Cos(zface * DTR)
                set y0 = y           + radius * init.TE_sin<i> * Cos(zface * DTR)
                set z0 = init.TE_cz  + radius * init.TE_cos<i> * Sin(zface * DTR)
                
                set x1 = x0
                set y1 = y0
                
                set distance = SquareRoot(SquareDistance(x0, y0, init.TE_cx, init.TE_cy))
                set angle = AngleBetweenCoords(init.TE_cx, init.TE_cy, x0, y0) * bj_RADTODEG
                set x1 = init.TE_cx + distance * Cos( (angle+nface) * DTR ) 
                set y1 = init.TE_cy + distance * Sin( (angle+nface) * DTR ) 
                
                
                
                set init.TE_member<i> = CreateUnit(owner, rawcode, x1,y1,0)
                call SetUnitZ(init.TE_member<i>, height + z0)
                call SetSafeX(init.TE_member<i>, x1)
                call SetSafeY(init.TE_member<i>, y1)
                set i = i + 1
            endloop
            
            call TT_Start(function Figure.ThingsToDo, init)
            
            return init
        endmethod   
        
        static method ThingsToDo takes nothing returns boolean
            local Figure this = TT_GetData()
            local real x0
            local real y0
            local real z0
            local integer i = 0
            local real height
            local real      angle
            local real      zangle
            local real      distance
            local real      x1
            local real      y1
            
            if .TE_moving then
                set distance = DistanceBetweenCoords(.TE_cx, .TE_cy, .TE_cz, .TE_wherex, .TE_wherey, .TE_wherez)
                
                if distance &gt; .TE_moverate * 2 then
                    set angle = AngleBetweenCoords(.TE_cx, .TE_cy, .TE_wherex, .TE_wherey)
                    set zangle = AngleBetweenCoordsB(.TE_cx, .TE_cy, .TE_cz, .TE_wherex, .TE_wherey, .TE_wherez)
                    set .TE_cx = .TE_cx + .TE_moverate * Cos(angle) * Cos(zangle)
                    set .TE_cy = .TE_cy + .TE_moverate * Sin(angle) * Cos(zangle)
                    set .TE_cz = .TE_cz + .TE_moverate              * Sin(zangle)
                endif
            endif
            
            if .TE_attached then
                set .TE_cx = GetUnitX(.TE_towhich)
                set .TE_cy = GetUnitY(.TE_towhich)
            endif
            
            if .TE_zturning then
                set .TE_zface = .TE_zface + .TE_zturnage
            endif
            if .TE_nturning then
                set .TE_nface = .TE_nface + .TE_nturnage
            endif
            
            if .TE_zturning or .TE_nturning or .TE_attached or .TE_moving then
                call MoveLocation(UsedFuncs_loc, .TE_cx, .TE_cy)
                set height = GetLocationZ(UsedFuncs_loc)
                loop
                    exitwhen i &gt;= .TE_number
                    
                    set x0 = .TE_cx + .TE_radius * .TE_cos<i> * Cos(.TE_zface * DTR)
                    set y0 = .TE_cy + .TE_radius * .TE_sin<i> * Sin(.TE_zface * DTR)
                    set z0 = .TE_cz + .TE_radius * .TE_cos<i> * Sin(.TE_zface * DTR)
                    
                    set x1 = x0
                    set y1 = y0
                    
                    set distance = SquareRoot(SquareDistance(x0, y0, .TE_cx, .TE_cy))
                    set angle = AngleBetweenCoords(.TE_cx, .TE_cy, x0, y0) * bj_RADTODEG
                        
                    set x1 = .TE_cx + .TE_radius * Cos( (angle+.TE_nface) * DTR ) 
                    set y1 = .TE_cy + .TE_radius * Sin( (angle+.TE_nface) * DTR ) 
                    
                    
                    
                    call SetSafeX(.TE_member<i>, x1)
                    call SetSafeY(.TE_member<i>, y1)
                    call SetUnitZ(.TE_member<i>, height + z0)
                    
                    
                    set i = i + 1
                endloop
            endif
            
            
            return false
        endmethod
        

        
endstruct


endlibrary
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>


Im currently testing the turning around the z-axis. This does NOT work, the movement ist very strange and so i think it has to do with this piece of code:

JASS:

                    set x0 = .TE_cx + .TE_radius * .TE_cos<i> * Cos(.TE_zface * DTR)
                    set y0 = .TE_cy + .TE_radius * .TE_sin<i> * Sin(.TE_zface * DTR)
                    set z0 = .TE_cz + .TE_radius * .TE_cos<i> * Sin(.TE_zface * DTR)
</i></i></i>


but i cant find the right formula, so what am i doing wrong?
Map attached...
 

Attachments

  • a.w3x
    29.5 KB · Views: 96
Reaction score
86
Spherical Coord = X = X+ Radius*Sin(phi)*Cos(theta)
Y = Y+Radius*Sin(phi)*Sin(theta)
Z = Z+Radius*Cos(phi)

Here ya go I believe those are the right ones.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top