| Home Page | Recent Changes | Preferences

# Useful Maths Functions

Some useful functions and operators to fill in some of UnrealScript's gaps. See also:

- Scripting Operators for more information and other examples.
- Global Functions for built-in maths functions

## Number functions and operators

#### divides

This is an operator that returns true if A is a divisor of B: for example:

     ( 3 divides 5 ) is false
     ( 3 divides 6 ) is true

    static final operator(24) bool divides ( float A , float B )
    {
      if( int( B / A ) == B / A )
        return true ;
    }

#### sgn

This is a function that crops up in maths from time to time, that has proved useful on occasion in UnrealScript. It returns -1, 0 or +1 depending on the sign of the input.

    function float Sgn( float theValue )
    {
      if( theValue == 0 )
        return 0;
      return theValue / Abs(theValue);
    }

#### Modulo operator

UnrealScript already has a modulus operator, `%` but its behaviour with negative numbers is not consistent with the mathematical definition:

UnrealScript says -8 % 10 = -8

Maths says -8 % 10 = 2

Interestingly enough, this also occurs with C's own % operator, showing the source of the "bug".

    static final operator(18) float mod  ( float A, float B )
    {
      if( A % B >= 0 )
        return A % B ;
      else
        return ( A % B ) + B ;
    }

#### Log

UnrealScript has an ln (Loge) operator, but no log with a variable base. This function allows that. 10 is the default if 0 or no base is passed:

    static final function float Logarithm (float a, optional float Base){
      if (Base==0)
        Base=10;
      return Loge(a)/Loge(base);
    }

## Trigonometic functions

Unrealscript includes Sin, Cos, Tan, and arcTan functions, defined in the Object class. The sin, cos, and tan assume an angle in radians is passed and aTan will return an angle in radians. Here are some const conversions:

    Const RadianToDegree = 57.2957795131;
    Const DegreeToRadian = 0.01745329252;
    Const RadianToURot = 10430.3783505;
    Const URotToRadian = 0.000095873799;

Where URot is an unreal rotation unit (used in rotators).

#### arcSin function

Inverse Sin function. Pass the sin of an angle, and it returns the angle:

    static final function float ASin  ( float A ){
      if (A>1||A<-1) //outside domain!
        return 0;
      if (A==1)  //div by 0 checks
        return Pi/2.0;
      if (A==-1)
        return Pi/-2.0;
      return ATan(A/Sqrt(1-Square(A)));
    }

#### arcCos funtion

Inverse Cosine funtion. Pass the cosine of an angle and the angle is returned:

    static final function float ACos  ( float A )
    {
      if (A>1||A<-1) //outside domain!
        return 0;
      if (A==0) //div by 0 check
        return (Pi/2.0);
      A=ATan(Sqrt(1.0-Square(A))/A);
      if (A<0)
        A+=Pi;
      Return A;
    }

#### aTan2 funtion

ArcTangent2. Pass the adjacent triangle leg as X and the opposite leg as Y (or X compoent, Y compont of a triangle inscribed in a unit circle).:

Note that if Y and X are 0, it will return 0, although in reality there is no answer (no line = no angle). The ratio allows for more exact angles (i.e. anywhere on the unit circle, rather than just 1/2 of it).

    final static function float ATan2(float Y,float X)
    {
      local float tempang;

      if(X==0) { //div by 0 checks.
        if(Y<0)
          return -pi/2.0;
        else if(Y>0)
          return pi/2.0;
        else
          return 0; //technically impossible (nothing exists)
      }
      tempang=ATan(Y/X);

      if (X<0)
        tempang+=pi;  //1st/3th quad

      //normalize (from -pi to pi)
      if(tempang>pi)
        tempang-=pi*2.0;

      if(tempang<-pi)
        tempang+=pi*2.0;

      return tempang;
    }

#### aSin2 funtion

ArcSin2: a more precise asin. Y=opposite leg, R=radius/hypotenuse. Of course if R is 0, no line exists, so it will return 0. Note that this assumes you put the asin code in your script.

    final static function float ASin2(float Y,float Rad)
    {
      local float tempang;

      if(Rad==0)
         return 0; //technically impossible (no hypotenuse = nothing)
      tempang=ASin(Y/Rad);

      if (Rad<0)
        tempang=pi-tempang;  //lower quads

      return tempang;
    }

#### aCos2 funtion

a more precise acos. X=adjecent leg, R=opposite. Other rules are similar to ASin2:

    final static function float ACos2(float X,float Rad)
    {
      local float tempang;

      if(Rad==0)
         return 0; //no possible angle
      tempang=ACos(X/Rad);

      if (X<0)
        tempang*=-1;  //left quads

      return tempang;
    }

## Vector operators

Some simple vector operators, since most operators that you could want for vector have already been defined.

    // Extend vector by an unit length
    static final preoperator vector ++ ( out vector A )
    {
      return A += Normal(A);
    }
    // Shrink operator by an unit length
    static final preoperator vector -- ( out vector A )
    {
      return A -= Normal(A);
    }

    // Same thing, but postop
    static final postoperator vector ++ ( out vector A )
    {
      local vector B;
      B = A;
      A += Normal(A);
      return B;
    }

    static final postoperator vector -- ( out vector A )
    {
      local vector B;
      B = A;
      A += Normal(A);
      return B;
    }

Suggestions: Firstly, don't use <pre></pre>. Indent your code lines by an arbitary amount of blanks instead (two, for instance) – that'll make Wiki automatically format them in a monospaced font and with linebreaks preserved, and it makes the code samples stand out better. Secondly, avoid tabs – there's no standard way for rendering tabs, so you'll be lucky if it comes out as you wish on other people's computers; better use blanks instead. —Mychaeel

thanks these were a straight copy-paste from a posting I made in Buf-Coding – Tarquin

Using <uscript></uscript> is way better now. – Wormbo

Indeed. By the way, as a potentially useful trivia about <uscript>: It expands tabs to spaces in four-character steps because that's the setting I believe Epic's coders used (and UnrealEd's script editor does as well). Best way is to avoid tabs altogether though and indent with spaces... —Mychaeel

Personally, I don't see any use of unary vector operators. Perhaps the author can explain their purpose? (though I admit it serves as a demonstration of proper usage of pre/post operator defining)– UsAaR33

Corran: Does anyone know what the abs() function does? In object.uc it's in the same section as all the trig functions but I can't seem to work out whay it does.

Tarquin: is it abs(float) or abs(vector)? you should move this to Global Function.

Mychaeel: It returns the absolute value of its argument. That is, the positive value of the given number. (And the trigonometric functions only happen to be close to it because they also take a float as their arguments.)

The Unreal Engine Documentation Site

Wiki Community

Topic Categories

Image Uploads

Random Page

Recent Changes

Offline Wiki

Unreal Engine

Console Commands

Terminology

Mapping Topics

Mapping Lessons

UnrealEd Interface

Questions&Answers

Scripting Topics

Scripting Lessons

Making Mods

Class Tree

Questions&Answers

Modeling Topics

Questions&Answers

Log In