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

[Plugin] Equation

Level 33
Joined
Apr 24, 2012
Messages
5,113
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:
Level 29
Joined
Oct 24, 2012
Messages
6,543
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.
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
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?
 
Level 33
Joined
Apr 24, 2012
Messages
5,113
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