Math Questions

tommerbob

Minecraft. :D
Reaction score
110
I think I'm just gonna create a thread for all of my math questions I ever have in the future. I should pay more attention in math class. :p

So here's my problem:

I'm trying to launch a projectile in a random direction from the point of origin:

JASS:
local projectile p  = 0
local real       ux = GetUnitX(d.orb)
local real       uy = GetUnitY(d.orb)
local real       tx = GetRandomReal(0, 360)
local real       ty = GetRandomReal(0, 360)
             
set p = projectile.create(ux,uy,50.00,Atan2((ty - uy),(tx - ux)))


(I'm using Kenny's Projectile system)

I thought the angle here:

JASS:
Atan2((ty - uy),(tx - ux))


should be random, but its not. The projectile is always going in the same direction. :confused:

Thanks for help.
 

Solmyr

Ultra Cool Member
Reaction score
30
[ljass]projectile.create(ux, uy, 50.00, GetRandomReal(0, 2 * bj_PI)) // You may want to pre-calculate 2 * bj_PI though.[/ljass]
 

Dirac

22710180
Reaction score
147
[ljass]Atan2(a,b)[/ljass] takes radians, not angles.
[ljass]bj_PI/2[/ljass]=90 degrees
[ljass]bj_PI[/ljass]=180 degrees
 

tommerbob

Minecraft. :D
Reaction score
110
Okay, sorry I should have specified more. I need a random X/Y coordinate, to get the angle for

JASS:
 projectile.create(ux,uy,50.00,Atan2((ty - uy),(tx - ux)))


and I need the same random X/Y coordinate for this:

JASS:
call p.projectArcing(tx, ty, p.posZ + 25.00, SHARD_SPEED, 0.08)
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
And Pi is equal to:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632788659361533818279682303019520353018529689957736225994138912497217752834791315155748572424541506959...

:p Wikipedia FTW
 

Sevion

The DIY Ninja
Reaction score
413
Let's not post useless things, NoobImbaPro.

Realistically, in vJASS, Pi only needs to be accurate to the 4th decimal place. And actually, going up to the 2nd decimal place would be more than enough precision for anything vJASS related.
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
Why useless mate, I gave you the first 1100+ decimals of pi exactly
vJass can read a number with 6 decimals, but 3.1415 is accurate enough, even 3.14.

@tommerbob
give us another questions guy, we hope we help you understand many things that don't make sense to you
 

Nestharus

o-o
Reaction score
84
vjass can read a number with 20 decimals too.. they are stored in floats after all. However, to add/subtract things that are like 20 decimals, you have to do a trick because vjass value reading is weird (for numbers, not variables).
 

tommerbob

Minecraft. :D
Reaction score
110
Okay it didn't take me long to get lost in math again. :p Sorry for the double post.

I'm working on a "leap" spell. The unit jumps 600 distance toward his facing angle. I based it off a spell written by Dinowc, so I don't completely understand all of the math functions.

Problem: instead of jumping 600, he jumps like 3000.

Code:

JASS:
scope Leap initializer init

// Requirements:
//      NewGen
//      Timer Utils (TU)
//      Math Functions

// configurables:

globals
    //========================================
    private constant integer SPELL_ID = 'A01C' // raw code of Leap spell
    private constant integer CROW_FORM = 'Amrf' // raw code of Crow Form
    
    //========================================
    private constant boolean INVULNERABLE = false // make unit invulnerable while in the air?
    //========================================
    private constant real INTERVAL = 0.03125
    //========================================
    private constant real MOVESPEED  = 800.
    private constant real MAX_HEIGHT = 250.
    private constant real JUMP_SPEED = 800. // wont affect much, but keep it at 800.
    
    //========================================
    private constant real DAMAGE_BASE = 20.
    private constant real DAMAGE_LVL  = 10.
    private constant real STR_BASE    = 2.
    private constant real STR_LVL     = 0.25
    private constant real INITIAL_AOE = 200.
    private constant real AOE_PER_LVL = 0.
    
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_HERO
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL
    
    //========================================
    // don't touch anything bellow:
    
    private constant real MS = MOVESPEED * INTERVAL
endglobals

// Math functions:

globals
    private constant real RADIANS = 0.0174
    
    private real MaxX
    private real MaxY
    private real MinX
    private real MinY
endglobals

private function PolarX takes real x, real dist, real angle returns real
    return x + (dist * Cos(angle * RADIANS))
endfunction

private function PolarY takes real y, real dist, real angle returns real
    return y + (dist * Sin(angle * RADIANS))
endfunction

private function GetParabolaZ takes real x, real d, real h returns real
    return 4 * h * x * (d - x) / (d * d)
endfunction

private function distance takes real x1, real y1, real x2, real y2 returns real
    local real dx = x2 - x1
    local real dy = y2 - y1
    return SquareRoot(dx * dx + dy * dy)
endfunction

private function AngleBetween takes real x1, real y1, real x2, real y2 returns real
    return Rad2Deg(Atan2(y2 - y1, x2 - x1))
endfunction

private function SafeX takes real x returns real
    if x < MaxX then
        return x
    else
        return MaxX
    endif
    
    if x > MinX then
        return x
    else
        return MinX
    endif
endfunction

private function SafeY takes real y returns real
    if y < MaxY then
        return y
    else
        return MaxY
    endif
    
    if y > MinY then
        return y
    else
        return MinY
    endif
endfunction

//=========================================================

private function AOE takes integer level returns real
    return INITIAL_AOE + ((level - 1) * AOE_PER_LVL)
endfunction

private function DAMAGE takes unit u, integer level returns real
    return (DAMAGE_BASE + DAMAGE_LVL * (level - 1)) + ((STR_BASE + STR_LVL * (level - 1)) * GetHeroStr(u, true))
endfunction

private struct data
    unit caster
    real damage
    real x
    real d
    real cos
    real sin
    integer level
    timer t
    
    static method create takes unit whichUnit, real tx, real ty returns data
        local data d = data.allocate()
        
        local real ux = GetUnitX(whichUnit)
        local real uy = GetUnitY(whichUnit)
        local real angle = GetUnitFacing(whichUnit)
        
        set d.caster = whichUnit
        
        set d.x = MS
        set d.d = distance(ux, uy, tx, ty)
        
        set d.cos = PolarX(0., MS, angle)
        set d.sin = PolarY(0., MS, angle)
    
        set d.level = GetUnitAbilityLevel(d.caster, SPELL_ID)
        set d.damage = DAMAGE(d.caster, GetUnitAbilityLevel(d.caster, SPELL_ID))
        
        set d.t = NewTimer()
        
        call UnitAddAbility(d.caster, CROW_FORM)
        call UnitRemoveAbility(d.caster, CROW_FORM)
        
        call SetUnitInvulnerable(d.caster, INVULNERABLE)
        
        if d.d < 100. then
            set d.d = 100.
        endif

        call SetUnitAnimation(d.caster, "attack slam")
        call SetUnitTimeScale(d.caster, 0.4)
        
        return d
    endmethod
    
    method destroy takes nothing returns nothing
        call ReleaseTimer(.t)
    endmethod
endstruct

globals
    private group G = CreateGroup()
    private player P
    private data D
endglobals

//=======================================================

private function filterFunc takes nothing returns boolean
    local unit picked = GetFilterUnit()
    
    if IsUnitEnemy(picked, P) and UnitAlive(picked) then
        call UnitDamageTargetEx(D.caster, picked, D.damage, true, false, ATTACK_TYPE, DAMAGE_TYPE, WEAPON_TYPE_WHOKNOWS)
    endif
    
    set picked = null
    
    return false
endfunction

//=======================================================

private function callback takes nothing returns nothing
    local data d = GetTimerData(GetExpiredTimer())
    
    local real xc = GetUnitX(d.caster)
    local real yc = GetUnitY(d.caster)
    local real angle = GetUnitFacing(d.caster)
    
    if d.x <= d.d then
        
        if d.x == MS then
            call PauseUnit(d.caster, true)
        endif
        
        call SetUnitX(d.caster, SafeX(xc + d.cos))
        call SetUnitY(d.caster, SafeY(yc + d.sin))
        
        call SetUnitFlyHeight(d.caster, GetParabolaZ(d.x, d.d, MAX_HEIGHT), JUMP_SPEED)
        
        set d.x = d.x + MS
    else
        if GetUnitAbilityLevel(d.caster, 'BSTN') == 0 and GetUnitAbilityLevel(d.caster, 'BPSE') == 0 then
            
            set D = d
            set P = GetOwningPlayer(d.caster)

            call GroupEnumUnitsInRange(G, xc, yc, AOE(d.level), Filter(function filterFunc))
            
            call PauseTimer(d.t)
        else
            call d.destroy()
        endif

        call PauseUnit(d.caster, false)
        call SetUnitTimeScale(d.caster, 1.)
        call QueueUnitAnimation(d.caster, "stand")
        call SetUnitInvulnerable(d.caster, false)
        
        call SetUnitFlyHeight(d.caster, 0., JUMP_SPEED)
    endif
endfunction

private function actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local real angle = GetUnitFacing(caster)
    local real ux = GetUnitX(caster)
    local real uy = GetUnitX(caster)
    local real tx    = ux + 600 * Cos(angle)
    local real ty    = uy + 600 * Sin(angle)
    local data d = data.create(caster, tx, ty)
        
    call SetTimerData(d.t, d)
    
    call TimerStart(d.t, INTERVAL, true, function callback)
    
    set caster = null
endfunction

//=======================================================

private function conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELL_ID
endfunction

private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer i = 0
    
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
        set i = i + 1
        exitwhen i == MAX_PLAYERS - 1 
    endloop
    call TriggerAddCondition(t, Condition(function conditions))
    call TriggerAddAction(t, function actions)
    
    
    set MaxX = GetRectMaxX(bj_mapInitialPlayableArea)-50.
    set MaxY = GetRectMaxY(bj_mapInitialPlayableArea)-50.
    
    set MinX = GetRectMinX(bj_mapInitialPlayableArea)+50.
    set MinY = GetRectMinY(bj_mapInitialPlayableArea)+50.
    
    set t = null
endfunction

endscope
 

Sevion

The DIY Ninja
Reaction score
413
Are you sure [ljass]GetUnitFacing[/ljass] returns the angle in radians? I'm 99.99% sure that it returns it in degrees.

If that's the case, in your actions, do [ljass]local real angle = GetUnitFacing(caster) * bj_DEGTORAD[/ljass].

I haven't done vJASS in a while, but IIRC that is what you have to do with Cos/Sin. They take radians and GetUnitFacing returns degrees.
 

tommerbob

Minecraft. :D
Reaction score
110
Well the caster always moved in the correct direction, but always too far.

I changed the angle to:

JASS:
local real angle = GetUnitFacing(caster) * bj_DEGTORAD


and the caster now never moves in the correct direction, always to the right, the distance is still way too far.

I simplified the above code to cut down on space to make it easier to read through. Below should be just the necessary math functions/data that would screw this up:

JASS:
scope Leap initializer init

// Requirements:
//      NewGen
//      Timer Utils (TU)
//      Math Functions

// configurables:

globals
 
    private constant real INTERVAL = 0.03125
    //========================================
    private constant real MOVESPEED  = 800.
    private constant real MAX_HEIGHT = 250.
    private constant real JUMP_SPEED = 800. // wont affect much, but keep it at 800.

    // don't touch anything bellow:
    
    private constant real MS = MOVESPEED * INTERVAL
endglobals

// Math functions:

globals
    private constant real RADIANS = 0.0174
    
    private real MaxX
    private real MaxY
    private real MinX
    private real MinY
endglobals

private function PolarX takes real x, real dist, real angle returns real
    return x + (dist * Cos(angle * RADIANS))
endfunction

private function PolarY takes real y, real dist, real angle returns real
    return y + (dist * Sin(angle * RADIANS))
endfunction

private function GetParabolaZ takes real x, real d, real h returns real
    return 4 * h * x * (d - x) / (d * d)
endfunction

private function distance takes real x1, real y1, real x2, real y2 returns real
    local real dx = x2 - x1
    local real dy = y2 - y1
    return SquareRoot(dx * dx + dy * dy)
endfunction

private function AngleBetween takes real x1, real y1, real x2, real y2 returns real
    return Rad2Deg(Atan2(y2 - y1, x2 - x1))
endfunction

private function SafeX takes real x returns real
    if x < MaxX then
        return x
    else
        return MaxX
    endif
    
    if x > MinX then
        return x
    else
        return MinX
    endif
endfunction

private function SafeY takes real y returns real
    if y < MaxY then
        return y
    else
        return MaxY
    endif
    
    if y > MinY then
        return y
    else
        return MinY
    endif
endfunction

private struct data
    unit caster
    real damage
    real x
    real d
    real cos
    real sin
    integer level
    timer t
    
    static method create takes unit whichUnit, real tx, real ty returns data
        local data d = data.allocate()
        
        local real ux = GetUnitX(whichUnit)
        local real uy = GetUnitY(whichUnit)
        local real angle = GetUnitFacing(whichUnit)
        
        set d.caster = whichUnit
        
        set d.x = MS
        set d.d = distance(ux, uy, tx, ty)
        
        set d.cos = PolarX(0., MS, angle)
        set d.sin = PolarY(0., MS, angle)
        
        set d.t = NewTimer()
        
        call UnitAddAbility(d.caster, CROW_FORM)
        call UnitRemoveAbility(d.caster, CROW_FORM)
        
        if d.d < 100. then
            set d.d = 100.
        endif
        
        return d
    endmethod
    
    method destroy takes nothing returns nothing
        call ReleaseTimer(.t)
    endmethod
endstruct

globals
    private group G = CreateGroup()
    private player P
    private data D
endglobals

private function callback takes nothing returns nothing
    local data d = GetTimerData(GetExpiredTimer())
    
    local real xc = GetUnitX(d.caster)
    local real yc = GetUnitY(d.caster)
    local real angle = GetUnitFacing(d.caster)
    
    if d.x <= d.d then
        
        if d.x == MS then
            call PauseUnit(d.caster, true)
        endif
        
        call SetUnitX(d.caster, SafeX(xc + d.cos))
        call SetUnitY(d.caster, SafeY(yc + d.sin))
        
        call SetUnitFlyHeight(d.caster, GetParabolaZ(d.x, d.d, MAX_HEIGHT), JUMP_SPEED)
        
        set d.x = d.x + MS
    else
        if GetUnitAbilityLevel(d.caster, 'BSTN') == 0 and GetUnitAbilityLevel(d.caster, 'BPSE') == 0 then
            
            set D = d
            
            call PauseTimer(d.t)
        else
            call d.destroy()
        endif
        
        call SetUnitFlyHeight(d.caster, 0., JUMP_SPEED)
    endif
endfunction

private function actions takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local real angle = GetUnitFacing(caster)
    local real ux = GetUnitX(caster)
    local real uy = GetUnitX(caster)
    local real tx    = ux + 600. * Cos(angle)
    local real ty    = uy + 600. * Sin(angle)
    local data d = data.create(caster, tx, ty)
        
    call SetTimerData(d.t, d)
    call TimerStart(d.t, INTERVAL, true, function callback)
    
    set caster = null
endfunction

function init takes nothing returns nothing
    set MaxX = GetRectMaxX(bj_mapInitialPlayableArea)-50.
    set MaxY = GetRectMaxY(bj_mapInitialPlayableArea)-50.
    
    set MinX = GetRectMinX(bj_mapInitialPlayableArea)+50.
    set MinY = GetRectMinY(bj_mapInitialPlayableArea)+50.
    
endfunction

endscope
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
why don't you use my system?? AUMS

and see how I am doing all the stuff??

PS: You confuse radians with degrees, witch one will you use?? I prefer radians as emjlr3 does
 

tommerbob

Minecraft. :D
Reaction score
110

Dirac

22710180
Reaction score
147
IMO leaps are quite easy, you can write one yourself if you have basic sliding knowledge and AceHart's jump parabola or even this crazy equation i have here

y = [(2a-4c)/(b^2)]*x^2 + [(4c-3a)/b]*x + a

a = Initial height of the proyectile
c = Max height of the proyectile
/////////////////////////////////////////////////////////
x = distance traveled
y = returns the height of the proyectile
b = input the distance between the start point and the end point here
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
I haven't meant to use it, just see how it does the whole thing.
Because it isn't approved does not mean that it is a crappy one.
It is the half system, that's why it isn't approved. When I mean the half I mean like Timer32 without T32x module
 

NoobImbaPro

You can change this now in User CP.
Reaction score
60
@Dirac

yeah it may seem as a crazy equation, but a simpler one may be better, like my equation:
y=ax-bx[SUP]2[/SUP]+c

with b = 4*height/distance[SUP]2[/SUP]
a = b*distance

and it's a normal physics parabola.

Where height is the max height of the projectile, where distance the distance the projectile/unit will do, x is the current distance from start point and y the requested height at that point. Oh and c the initial height. Is same with aceheart's but with less arithmetics
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1

      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