• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[Plugin] Equation

JASS:
//! zinc
library Equation { /*
*************************************************************************************
*
*    Library of Geometric and Math Equations or simply Math Equations.
*    This library is mainly a group of plugins.
*
*************************************************************************************
*    
*    Credits
*
*        looking_for_help
*        PurgeAndFire111
*        moyackx
*        D4RK_G4ND4LF
*
*************************************************************************************
*
*                           MODULES AND EXPLANATIONS
*
*************************************************************************************
*
*    Get Random Angle
*
*    --------------------------------------------
*
*        retrieves random degrees and also random radians.
*
*************************************************************************************/
    public module GetRandomAngle
    {
        static method randomRadian() -> real { return GetRandomReal(-bj_PI, bj_PI); }
        static method randomDegree() -> real { return GetRandomReal(-180, 180); }
    }
/*************************************************************************************
*
*    Distance 2D
*
*    --------------------------------------------
*
*        retrieves distance between two points. Takes reals x and y coordinates not
*        locations
*
*************************************************************************************/
    public function Distance2d ( real x, real y, real x2, real y2 ) -> real { return SquareRoot((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)); } }
/*************************************************************************************
*
*    Angle 2D
*
*    --------------------------------------------
*
*        retrieves angle between coordinates.
*
*************************************************************************************/
    public function Angle2d( real x, real y, real x2, real y2 ) -> real { return Atan2(y2 - y, x2 - x) * bj_RADTODEG; } }
/*************************************************************************************
*
*    Atan3
*
*    --------------------------------------------
*
*        to calculate PROPERLY the correct angle. the values (x1;y1)
*        will be the pivot and (x2;y2) the extreme point. returns radians.
*
*        Thanks to moyackx
*
*************************************************************************************/
    public function Atan3 ( real x, real y, real x2, real y2 ) -> real
    {
        real a = Atan2( y2 - y, x2 - x );
        if ( a < 0) { return 2 * bj_PI + a; }
        return a;
    }
/*************************************************************************************
*
*    IsUnitBehindUnit
*
*    --------------------------------------------
*
*        Determines whether a unit is behind a given unit depending on a given angle. 
*        Member module of UnitOrientation module.
*
*        Thanks to PurgeAndFire111
*
*************************************************************************************/
    public function IsUnitBehindUnit( unit behind, unit front, real angleMargin ) -> boolean
    {
        real angle = ModuloReal(angle2d( GetUnitX(behind), GetUnitY(behind), GetUnitX(front), GetUnitY(front)), 360);
        real difference = GetUnitFacing(front) - angle;
        if (difference < 0) { difference = -difference; }
        return difference > (180 - angleMargin) && difference < (180 + angleMargin);
    }
/*************************************************************************************
*
*    IsUnitFacingUnitBehind
*
*    --------------------------------------------
*
*        Determines whether a unit is facing a unit's back. Depends on a given angle.
*        Member module of UnitOrientation module.
*
*        Thanks to PurgeAndFire111
*
*************************************************************************************/  
    public function IsUnitFacingUnitBehind ( unit behind , unit front, real angle ) -> boolean
    {
        real difference = GetUnitFacing(front) - GetUnitFacing(behind);
        if (difference < 0) { difference = -difference; }
        return difference < angle && isUnitBehindUnit( front, behind, angle );
    }
/*************************************************************************************
*
*    IsUnitFacingUnit
*
*    --------------------------------------------
*
*        Determines whether a unit is facing a given unit depending on a given angle. 
*        Member module of UnitOrientation module.
*
*        Thanks to PurgeAndFire111
*
*************************************************************************************/  
    public function IsUnitFacingUnit( unit facer, unit faced, real angleMargin ) -> boolean
    {
        real angle = ModuloReal(Atan2(GetUnitX(facer), GetUnitY(facer), GetUnitX(faced), GetUnitY(faced)), 360);
        real difference = GetUnitFacing(facer) - angle;
        if (difference < 0) { difference = -difference; }
        return difference > (180 - angleMargin) && difference < (180 + angleMargin);
    }
/*************************************************************************************
*
*    GetPolarPoint
*
*    --------------------------------------------
*
*        consists of two methods. One projects x and other one is y. Angl must be in
*        degrees. 
*
*        Thanks to moyackx
*
*************************************************************************************/
    public module GetPolarPoint
    {
        static method polarX( real x, real angle, real dist ) -> real { return x + dist * Cos(angle * bj_DEGTORAD); }
        static method polarY( real y, real angle, real dist ) -> real { return y + dist * Sin(angle * bj_DEGTORAD); }
    }
/*************************************************************************************
*
*    GetPointZ
*
*    --------------------------------------------
*
*        retrieves a given point/coordinates' terrain height. 
*
*        Thanks to PurgeAndFire111
*
*************************************************************************************/
    location l = Location(0, 0);
    
    public function GetPointZ ( real x, real y ) -> real
    { 
        MoveLocation(l , x, y);
        return GetLocationZ(l);
    }
/*************************************************************************************
*
*    GetUnitZ
*
*    --------------------------------------------
*
*        retrieves to complete height of the unit( flyHeight + terrain height. 
*
*        Thanks to PurgeAndFire111
*
*************************************************************************************/  
    public function GetUnitZ( unit u ) -> real { return GetPointZ(GetUnitX(u), GetUnitY(u)) + GetUnitFlyHeight(u); }}
/*************************************************************************************
*
*    GetDistance3D
*
*    --------------------------------------------
*
*        retrieves the distance between two points,taking account the terrain height.
*
*        Thanks to moyackx
*
*************************************************************************************/  
    public function Distance3d ( real x, real y, real x2, real y2) -> real
    {
        real dx = x2 - x;
        real dy = y2 - y;
        real dz = GetPointZ( x2, y2 ) - GetPointZ( x, y);
        return SquareRoot(( dx * dx ) + ( dy * dy ) + ( dz * dz ));
    }
/*************************************************************************************
*
*    GetDistanceBetweenUnits3D
*
*    --------------------------------------------
*
*        retrieves the distance between two units,taking account the complete unit z.
*
*        Thanks to moyackx
*
*************************************************************************************/
    public function DistanceBetweenUnits3d( unit u, unit u2 ) -> real
    {
        real dx = GetUnitX(u2) - GetUnitY(u);
        real dy = GetUnitY(u2) - GetUnitY(u);
        real dz = GetUnitZ(u2) - GetUnitZ(u);
        return SquareRoot((dx * dx) + (dy * dy) + (dz * dz));
    }
/*************************************************************************************
*
*    GetZAngle
*
*    --------------------------------------------
*
*        retrieves the angle between two coordinates,returns the angle between the
*        height of the first location to the second location.
*
*        Thanks to moyackx
*
*************************************************************************************/
    public module GetZAngle {     static method zAngle ( real x, real y, real x2, real y2) -> real { return Acos( distance2d(x, y, x2, y2), distance3d(x, y, x2, y2)) * bj_RADTODEG; }}
/*************************************************************************************
*
*    GetZAngleBetweenUnits
*
*    --------------------------------------------
*
*        retrieves the angle between two units,returns the angle between the
*        height of the first unit to the second unit.
*
*        Thanks to moyackx
*
*        Requires : GetDistance2D, GetDistanceBetweenUnits3D
*
*************************************************************************************/
    public module GetZAngleBetweenUnits {     static method zAngleBetweenUnits ( unit u, unit u2 ) -> real { return Acos ( distance2d(GetUnitX(u), GetUnitY(u), GetUnitX(u2), GetUnitY(u2)), DistanceBetweenUnits3d(u, u2)) * bj_RADTODEG;}}
/*************************************************************************************
*
*    Parabola
*
*    --------------------------------------------
*
*        retrieves the parabolic height. depends on the max value and current value and
*        the highest height of the parabola.
*
*        Thanks to D4RK_G4ND4LF
*
*************************************************************************************/
    public function Parabola( real height, real max, real current) -> real { return 4 * height * current * (max - current) / (max * max); }}
/*************************************************************************************
*
*    ParabolaEx
*
*    --------------------------------------------
*
*        parabola that takes account the terrain height
*
*        Thanks to D4RK_G4ND4LF
*
*************************************************************************************/
    public module ParabolaEx {        static method parabolaEx( real height, real maxDist, real currentDist, real startHeight, real endHeight, real x, real y) -> real 
    { return parabola( height, maxDist, currentDist) + currentDist * (endHeight - startHeight) / currentDist + (startHeight - getPointZ(x, y)); }}
}
//! endzinc
 
Last edited:
Whats the Atan3 for ? Ive only ever seen Atan2 and Atan lol.

The is unit behind is nice and the in unit facing behind. Same with the is unit facing unit.

The get distance one is simple. Same with most of the others.

I like the GetDistanceBetweenUnits3D and GetZAngleBetweenUnits.
thats one i havent used yet lol.

Parabola is nice since it checks the terrain height and figures that in as well.

All in all i think this is a nice little math library.
 
btw, so what atan3 does is that it prevents the returning of negative radians which atan2 does?

and, since I'm still not so familiar with module usage, what does this mean?

JASS:
public module IsUnitFacingUnitBehind
{
    module IsUnitBehindUnit;

does it work like implementing the IsUnitBehindUnit module into the other module?
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,258
static method randomRadian() -> real { return GetRandomReal(-bj_PI, bj_PI); }
static method randomDegree() -> real { return randomRadian() * bj_RADTODEG; }
Why use one to generate the other? Surely...
JASS:
     static method randomDegree() -> real { return GetRandomReal(-180.0, 180.0); }
Would be more efficient? Also why -pi to pi and not 0 to 2pi?
 
Why use one to generate the other? Surely...
JASS:
     static method randomDegree() -> real { return GetRandomReal(-180.0, 180.0); }
Would be more efficient? Also why -pi to pi and not 0 to 2pi?

To match the -180 and 180 degree angle :D

@lfh
Thanks :D

Code updated.
Removed the Angle/Distance BetweenUnits2d. Compiled the code and expected some syntax errors but now fixed.
 
Last edited:
The functions that inline are perfectly fine because they are not going to be present in the end product. The other functions are problems. If we had a smarter inliner or maybe an "inline" keyword, they would all be perfectly fine.

Your best bet is to keep the one-liners in the modules and move the larger functions outside of the modules. Just make them functions.
 
Level 4
Joined
May 25, 2009
Messages
100
I have a question to the IsUnitBehindUnit:
JASS:
    public function IsUnitBehindUnit( unit behind, unit front, real angle ) -> boolean
    {
        real angle = ModuloReal(angle2d( GetUnitX(behind), GetUnitY(behind), GetUnitX(front), GetUnitY(front)), 360);
        real difference = GetUnitFacing(front) - angle;
        if (difference < 0) { difference = -difference; }
        return difference > (180 - angle) && difference < (180 + angle);
    }


You have "angle" as a parameter and in the first line you create a local real "angle" (I guess...i never used zinc and i'm new to vjass as well) and give this "angle" a value. So whats the case of having "angle" as a parameter and then create a new "angle"?
 
Level 7
Joined
Feb 9, 2021
Messages
301
Why is it in the graveyard? I thought there is a sub-chapter of this in Advanced Maths but could not find it.
 
Top