• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker Math Conversions

dialgpalkia

Member
Hi there,

I am trying to adapt a C++ code for a program I am making in GMS2 but I am finding that my output numbers aren't correct. After reviewing the code I am suspecting that the order of operations is getting messed up when I convert the code directly.
There are two main sections that I am talking about:
C++ Section 1:
C++:
        public static double getT(double x, double y)
        {
            double theta = Math.Atan2(y, x) * 180f / Math.PI;
            if ((-135.0 <= theta) && (theta <= -45.0))
            {
                double yp = Math.Floor(y);
                double xp = x * yp / y;
                double max = getMax(-(int)yp);
                double min = getMin(-(int)yp);
                return min + 7.0 * (max - min) / 8.0 - xp;
            }
            else if ((-45.0 <= theta) && (theta <= 45.0))
            {
                double xp = Math.Ceiling(x);
                double yp = y * xp / x;
                double max = getMax((int)xp);
                double min = getMin((int)xp);
                return min + 5.0 * (max - min) / 8.0 - yp;
            }
            else if ((45.0 <= theta) && (theta <= 135.0))
            {
                double yp = Math.Ceiling(y);
                double xp = x * yp / y;
                double max = getMax((int)yp);
                double min = getMin((int)yp);
                return min + 3.0 * (max - min) / 8.0 + xp;
            }
            else
            {
                double xp = Math.Floor(x);
                if ((theta >= Math.Atan2(xp, xp + 1) * 180.0 / Math.PI) && (theta <= -135.0))
                {
                    double yp = Math.Floor(y);
                    xp = x * yp / y;
                    double max = getMax(-(int)yp);
                    double min = getMin(-(int)yp);
                    return min + 7.0 * (max - min) / 8.0 * xp;
                }
                else
                {
                    double yp = y * xp / x;
                    double max = getMax(-(int)xp);
                    double min = getMin(-(int)xp);
                    return min + 1.0 * (max - min) / 8.0 + yp;
                }
            }
        }

Here's my GML conversion:
GML:
var _x = argument0;
var _y = argument1;

var _theta = arctan2(_y,_x)*(180/pi); //Finds the arctan in degrees.

if((-135.0 <= _theta) && (_theta <= -45.0)) {
    var _yp = floor(_y);
    var _xp = _x * _yp / _y;
    var _max = scrGetMaxValueInRing(-_yp);
    var _min = scrGetMaxOfPreviousRing(-_yp);
    return (_min + 7.0 * (_max - _min) / 8.0 - _xp);
}

else if((-45.0 <= _theta) && (_theta <= 45.0)) {
    var _xp = ceil(_x);
    var _yp = _y * _xp / _x;
    var _max = scrGetMaxValueInRing(_xp);
    var _min = scrGetMaxOfPreviousRing(_xp);
    return (_min + 5.0 * (_max - _min) / 8.0 - _yp);
}

else if((45.0 <= _theta) && (_theta <= 135.0)) {
    var _yp = ceil(_y);
    var _xp = _x * _yp / _y;
    var _max = scrGetMaxValueInRing(_yp);
    var _min = scrGetMaxOfPreviousRing(_yp);
    return (_min + 3.0 * (_max - _min) / 8.0 + _xp);
}

else {
    var _xp = floor(_x);
    if (_theta >= (arctan2(_xp, _xp + 1) * 180.0 / pi) && (_theta <= -135.0)) {
        var _yp = floor(_y);
        _xp = _x * _yp / _y;
        var _max = scrGetMaxValueInRing(-_yp);
        var _min = scrGetMaxOfPreviousRing(-_yp);
        return (_min + 7.0 * (_max - _min) / 8.0 * _xp);
    }
    else {
        var _yp = (_y*_xp)/_x;
        var _max = scrGetMaxValueInRing(-_xp);
        var _min = scrGetMaxOfPreviousRing(-_xp);
        return (_min + 1.0 * (_max - _min) / 8.0 + _yp);
    }
}

Here's the C++ Section 2:
C++:
        public static List<double> getTIntersections(int rings, double res, double T)
        {
            List<double> tI = new List<double>();
            double p = getPercent(T);
            int rt = getRing(T);
            double delR = getMax(rt) - getMin(rt);
            if (p * delR < 1.0)
            {
                double delr1 = getMax(rt - 1) - getMin(rt - 1);
                double pn = p;
                p = pn / (delr1 / delr1 + pn * delr1 - pn * delr1);
            }
            for (int r = 0; r < rings; r++)
            {
                tI.Add(snapT(getTfromP(p, r + 1), res));
            }
            return tI;
        }

Here's my conversion (definitions removed for clarity):
GML:
if(_percent*_deltaR < 1.0) {
    var _deltaR1 = scrGetMaxValueInRing(_ringNumber - 1) - scrGetMaxOfPreviousRing(_ringNumber - 1);
    var _pn = _percent;
    _percent = _pn/(_deltaR1 / _deltaR1 + _pn * _deltaR1 - _pn * _deltaR1);
}

Most of my outputs (made further down the code which is my next place to check) end up being off by ~0.1-0.5 which ends up becoming exponential, so that by the time the code is at say the 5th component in the input it's off by as much as 20.

This may not be the area that the issue is coming from, but since I wasn't entirely sure how the brackets would convert I figured I would get some help.

Anyone have any ideas on if my conversions are correct?

Thanks!
 

TheouAegis

Member
pn / (delr1 / delr1 + pn * delr1 - pn * delr1);
That should just evaluate to pn/1....


All i can think of is issues between floats and doubles. Or an issue with how pi is stored or arctan2 is calculated. You should output the results of each line and see at which point it actually breaks down.
 
Last edited:

dialgpalkia

Member
That should just evaluate to pn/1....


All i can think of is issues between floats and doubles. Or an issue with how pi is stored or arctan2 is calculated. You should output the results of each line and see at which point it actually breaks down.
Yeah that's what I thought too... it's a very strange code (then again it is created in C++) so maybe you're right the difference would come in the differences between floats and doubles. Is there a way to force a variable to have a float or double type? I know in some languages like C++ you can just cast it to a different type; e.g. scrDoSomething( (int)varCastInputToIntType) ) or define it as a float.

The GML manual says that our "Real" numbers are "floating points" so the question then focuses on double types.
 
Top