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

[JASS] Mathathics, spherical equation

Status
Not open for further replies.
Level 18
Joined
Oct 18, 2007
Messages
930
Help.jpg


[RAINBOW]Sphere Information[/RAINBOW]
 
You don't need specifically wc3, you could also try it on a program with let's you program with visual outputs.


Anyway, I'm more used this way:
x = r*cos(φ)*cos(θ)
y = r*sin(φ)*cos(θ)
z = sin(θ)
where φ ranges from 0 to 2*π
and θ ranges from -π/2 to π/2

Thats because if you are only in xy plane, the θ=0 and z=0, which makes perfect sense as cos(θ)=1 and sin(θ)=0 thus you can ignore the functions with parameter θ.

http://en.wikipedia.org/wiki/Spherical_coordinates
 
Level 18
Joined
Oct 18, 2007
Messages
930
Here is an example

JASS:
function GetSphereLoc takes real x, real y, real z, real r, real xyAngle, real zAngle returns location
    local location loc = Location( x + r * Cos(zAngle) * Sin(xyAngle), y + r * Sin(zAngle) * Sin(xyAngle) )
    call SetLocationZ( loc, z + r * Cos(xyAngle) )

    return loc
endfunction
 
Level 18
Joined
Oct 18, 2007
Messages
930
Ok, I have tested it, does not work :/

JASS:
library SphereMotion

    globals
        private constant real FPS = 40.00
        
        private constant integer FlyId = 'Amrf'
        private constant integer DumId = 'n000'
    endglobals
    
    private struct Data
        unit Object
        
        real x0
        real y0
        real z0
        
        real zA = 0.0
        real xyA = 0.0
        
        real zV
        real xyV
        
        real r
        
        effect Art
        
        static integer array Sphere
        static integer TotalSpheres = 0
        
        static timer Timer = null
        
        static method Loop takes nothing returns nothing
            local Data dat
            local integer i = 0
            
            loop
                exitwhen i >= Data.TotalSpheres
                set dat = Data.Sphere[i]
                
                if GetWidgetLife(dat.Object) > .405 then
                    call SetUnitX(dat.Object, dat.x0 + (dat.r * Sin(dat.xyA) * Cos(dat.zA)))
                    call SetUnitY(dat.Object, dat.x0 + (dat.r * Sin(dat.xyA) * Sin(dat.zA)))
                    call SetUnitFlyHeight(dat.Object, dat.z0 + (dat.r * Cos(dat.xyA)), 0.0)
                    
                    set dat.zA = (dat.zA + dat.zV) * bj_RADTODEG
                    set dat.xyA = (dat.xyA + dat.xyV) * bj_RADTODEG
                    
                    if dat.zA > 360 then
                        set dat.zA = 0.0
                    elseif dat.zA < -360 then
                        set dat.zA = 0.0
                    else
                        set dat.zA = dat.zA * bj_DEGTORAD
                    endif
                    
                    if dat.xyA > 360 then
                        set dat.xyA = 0.0
                    elseif dat.xyA < -360 then
                        set dat.xyA = 0.0
                    else
                        set dat.xyA = dat.xyA * bj_DEGTORAD
                    endif
                else
                    call DestroyEffect(dat.Art)
                    set dat.Object = null
                    set dat.Art    = null
                    
                    call dat.destroy()
                    
                    set Data.TotalSpheres = Data.TotalSpheres - 1
                    set Data.Sphere[i] = dat.Sphere[Data.TotalSpheres]
                    
                    set i = i - 1
                endif
                
                set i = i + 1
            endloop
            
            if Data.TotalSpheres == 0 then
                call PauseTimer(Data.Timer)
            endif
        endmethod
        
        static method Start takes real x0, real y0, real z0, real r, real zA, real xyA, real zV, real xyV, string Art, real Time returns unit
            local Data dat = Data.allocate()
            
            set dat.x0 = x0
            set dat.y0 = y0
            set dat.z0 = z0 + r
            
            set dat.zA  = zA * bj_DEGTORAD
            set dat.xyA = xyA * bj_DEGTORAD
            set dat.zV  = (zV / FPS) * bj_DEGTORAD
            set dat.xyV = (xyV / FPS) * bj_DEGTORAD
            
            set dat.Object = CreateUnit(Player(PLAYER_NEUTRAL_AGGRESSIVE), DumId, x0, y0, 0)
            call UnitAddAbility(dat.Object, FlyId)
            call UnitRemoveAbility(dat.Object, FlyId)
            call SetUnitFlyHeight(dat.Object, z0, 0)
            
            set dat.Art = AddSpecialEffectTarget(Art, dat.Object, "origin")
            call SetUnitAnimationByIndex(dat.Object, 90)
            
            if Time > 0.0 then
                call UnitApplyTimedLife(dat.Object, 'BTLF', Time)
            endif
            
            if Data.TotalSpheres == 0 then
                call TimerStart(Data.Timer, 1.0/FPS, true, function Data.Loop)
            endif
            
            set Data.Sphere[Data.TotalSpheres] = dat
            set Data.TotalSpheres = Data.TotalSpheres + 1
            
            return dat.Object
        endmethod
    endstruct
    
    function CreateSphere takes real x0, real y0, real z0, real r, real zA, real xyA, real zV, real xyV, string Art, real Time, integer Parts, boolean Return returns group
        local group g = CreateGroup()
        local integer i = 0
        local real a = 360/Parts
        
        loop
            exitwhen i > Parts
            
            call GroupAddUnit(g, Data.Start(x0, y0, z0, r, zA, xyA + (a * i), zV, xyV, Art, Time))
            
            set i = i + 1
        endloop
        
        if Return then
            return g
        else
            call DestroyGroup(g)
            set g = null
            return g
        endif
    endfunction

endlibrary
 

Attachments

  • Sphere.w3x
    24.7 KB · Views: 63
Level 18
Joined
Oct 18, 2007
Messages
930
Mkay

Here is the movement

JASS:
                    call SetUnitX(dat.Object, dat.x0 + (dat.r * Sin(dat.xyA) * Cos(dat.zA)))
                    call SetUnitY(dat.Object, dat.x0 + (dat.r * Sin(dat.xyA) * Sin(dat.zA)))
                    call SetUnitFlyHeight(dat.Object, dat.z0 + (dat.r * Cos(dat.xyA)), 0.0)

                    set dat.zA = (dat.zA + dat.zV) * bj_RADTODEG
                    set dat.xyA = (dat.xyA + dat.xyV) * bj_RADTODEG

                    if dat.zA > 360 then
                        set dat.zA = 0.0
                    elseif dat.zA < -360 then
                        set dat.zA = 0.0
                    else
                        set dat.zA = dat.zA * bj_DEGTORAD
                    endif

                    if dat.xyA > 360 then
                        set dat.xyA = 0.0
                    elseif dat.xyA < -360 then
                        set dat.xyA = 0.0
                    else
                        set dat.xyA = dat.xyA * bj_DEGTORAD
                    endif
 
You don't create the timer :p

EDIT:
And there is a another problem, I made an init function which creates the timer and now my debug message displays, but the orbs go high into the air as soon as they are created and stay there...

EDIT:
Another problem: you use dat.x0 to set the unit's y position...

EDIT:
...yet ANOTHER problem - you never set dat.r...

EDIT:
And the trig is all screwed, but I can't really help you there... anyways this is my fixed version - it looks kinda cool, but it's not spherical. It's more American Football-Shaped.
 

Attachments

  • Sphere.w3x
    25 KB · Views: 90
Last edited:
Level 18
Joined
Oct 18, 2007
Messages
930
I suppose... maybe you should make functions like angle cutoff point - so you can make like semi-spheres and stuff, like if you want a big dome on the ground... and I'd make an option so the missiles can damage units...

i can do the dome, but the damage is up to the user.

It is easy, like pick every units in "yourspheregroup" and do damage every units in 50 range of picked unit

This would make more damage if there is more parts ;)
 
Level 18
Joined
Oct 18, 2007
Messages
930
Lets say you have 2 cutoff points, 90 and 270. You would increase the angle by the velocity each interval, and if angle becomes greater than 270, multiply the velocity by -1, and if the angle becomes less than 90, multiply the velocity by -1. That way, you get a semi-circle motion, bouncing between those 2 angles.

meh :p


Anyways, redid the system. It is now a Ellipsoid motion ( can be sphere ).
Where 'a' 'b' 'c' controls the size and shape of the ellipsoid.

if a = b = c you get a perfect sphere.
 

Attachments

  • Ellipsoid.w3x
    29.9 KB · Views: 51
Status
Not open for further replies.
Top