• Check out the results of the Techtree Contest #19!
  • 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.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

[JASS] Strange wrong calculation when entering certain values

Status
Not open for further replies.

Ardenian

A

Ardenian

Another life-decisive problem:

When I wanted to update my Simple Grid system with an additional function, I noticed there is a mistake in the calculation.

When entering certain integer values, the function gives wrong real values and therefore a wrong point. However, after the first row jump it doesn't work anymore, or at least doesn't do for certain values ( e.g. 10 ( wrong coordinates, wrong GetTilePosition) or 25 ( wrong coordiantes, but correct GetTilePosition)


JASS:
// For simplicity, I merged the previously x and y calculation into a shared point calculation, until the problem is fixed

// The grid and as well the calculation start frmo the top left and run to the bottom right

// Calculates the point based on grid number i and grid position i2
function GridPoint takes integer i, integer i2 returns location
    local integer ic = 1 // counts how many tiles we moved already
    local real iy = 0 // iy is responsible for calculating how many rows to move down.
    local real ix = 1 // ix is responsible for calculating how many tiles to move right
    local integer i3 = 1 // i3 checks if a row is full
    
    if i2 > udg_SUG_GridBreadth[i]*udg_SUG_GridLength[i] then // when the entered tile number is higher than the total grid tiles amount
        call DisplayTextToForce( GetPlayersAll(), "Searched position exceeds grid's tile count" )
        return Location( ix, iy) 
    endif
    loop 
    exitwhen ic == i2+1 // exitwhen the searched position is reached
        if i3 == udg_SUG_GridBreadth[i]+1 then // check if a row jump is required
            set ix = 1 // ix = 1 means being on the first x position
            set iy = iy - 1 // since we move down, iy - 1
            set i3 = 1
        else 
            set ix = ix + 1 // move one x tile to the right
            set i3 = i3 + 1 
        endif
        set ic = ic + 1 // + 1 to total tiles counted
        
    endloop
    set ix = GetLocationX(udg_SUG_StartingPoint[i]) + (ix-1) * udg_SUG_Distance[i] // - 1, since ix = 1 when no x change from the starting point
    set iy = GetLocationY(udg_SUG_StartingPoint[i]) + iy * udg_SUG_Distance[i] // row jumps
    return Location( ix, iy)
endfunction

// Checks if the point is in the entered grid ( integer i)

function IsInGrid takes integer i, real x, real y returns boolean
    local real gx2 = GetLocationX(udg_SUG_StartingPoint[i]) // if x lower than x starting position -> not in grid
    local real gy2 = GetLocationY(udg_SUG_StartingPoint[i])
    local real gx = gx2 + udg_SUG_Distance[i] * (udg_SUG_GridBreadth[i]-1)
    local real gy = gy2 - udg_SUG_Distance[i] * (udg_SUG_GridLength[i]-1)

    return not((x > gx) or(x < gx2) or(y < gy) or(y > gy2))
endfunction

// This function kinda works as a debug, it will give an integer based on the location and
// as we previously calculated a point based on an integer, it should be the same

function GetGridPosition takes integer i, location p returns integer
    local integer pos
    local real x = GetLocationX(p)
    local real y = GetLocationY(p)
    local real px = GetLocationX(udg_SUG_StartingPoint[i])
    local real py = GetLocationY(udg_SUG_StartingPoint[i])
    if IsInGrid( i, x, y) == true then
        set x = SquareRoot((x-px)*(x-px)) / udg_SUG_Distance[i] // get x distance between starting point x and tile x, then / tile distance of grid
        set y = SquareRoot((y-py)*(y-py)) / udg_SUG_Distance[i] // get y distance between starting point y and tile y, then / tile distance of grid
        if I2R(R2I(x)) != R2I(x) or I2R(R2I(y)) != R2I(y) then // when the distance matches not the distance between tiles
            call DisplayTextToForce( GetPlayersAll(), "Searched point is not a grid point" )    
        else
            set pos = R2I(x+1 + y*udg_SUG_GridBreadth[i]) // calculate grid position of point p
        endif 
    else
        call DisplayTextToForce( GetPlayersAll(), "Searched point is not in grid" ) // point is not in grid    
    endif
    return pos
endfunction


I already spent hours debugging and trying, but I cannot get it right.
I would appreciate if someone could help me, please. This system is quite important for me.
 
Last edited by a moderator:
Can you try to copy all page and paste into a new empty page ? code seemd well for me but some times shit happens in program (happens to me everytime)
 
Why in the name of all that is good in this world are you using a loop instead of simple arithmetic? Just divide i2 with grid breadth to get y coordinate, the remainder is the x coordinate.

SquareRoot((x-px)*(x-px)) Also, what is this? What's wrong with RAbsBJ?

Giving us some actual values of what the results are and what they should be on how big a grid could help us debug this. Just posting the code and saying the results are wrong without telling us how they are wrong isn't very helpful.
 
Thanks mjpsko, doesn't help sadly.

Wrong cases I noticed:
Entered integer Expected coordinates Actual coordinates integer of actual coordinates


25
-512, 128 -512, 256 17

17
-512, 256 -512, 384 9

26
-384, 128 -384, 256 18

EDIT: About Squareroot and Abs, I played around with the numbers and I wasn't sure about Abs, that's why I used Squareroot.

EDITEDIT:
JASS:
function GridPointX takes integer i, integer i2 returns real
    local real x = (i2/udg_SUG_GridBreadth[i]) - R2I(i2/udg_SUG_GridBreadth[i])
    set x = (x*udg_SUG_GridBreadth[i])-1
    set x = GetLocationX(udg_SUG_StartingPoint[i]) + x*udg_SUG_Distance[i]
    return x
endfunction

function GridPointY takes integer i, integer i2 returns real
    local real y = R2I((i2/udg_SUG_GridBreadth[i])-0.01)
    set y = GetLocationY(udg_SUG_StartingPoint[i]) - y*udg_SUG_Distance[i]
    return y
endfunction

function GridPoint takes integer i, integer i2 returns location
    local real x = GridPointX(i,i2)
    local real y = GridPointY(i,i2)
    return Location(x,y)
endfunction

That's what I wrote now, after your suggestion, for the point calculation.
However, x is always - 640 and y is wrong, too ( like one row wrong, 11 is e.g. y = 512, although supposed to be 384)

Manually calculating is using the formulae it works, but not in-game..

EDITEDITEDIT:
JASS:
  local real x = (i2/udg_SUG_GridBreadth[i]) - R2I(i2/udg_SUG_GridBreadth[i])
// this line is always 0, but shouldn't it be between 0 and 1, dependent on i2 ?
 
Last edited by a moderator:
That line shall work like the following:
Example: i2 = 11, breadth = 8

local real x = 11/8 - R2I(11/8)
local real x = 1.375 - 1 = 0.375

It should filter out the remainder, to calculate the x steps ( as Anitarf suggested)
 
Is udg_SUG_GridBreadth a real or an integer?

It is an integer. Do I have to convert them to real first ?
Shouldn't it not matter in mathematical operations whether they are integer or real ?
 
If you do a mathematical operation between two integers, the result will be an integer. So, 3 / 5 = 0 but 3 / 5.0 = 0.6.
 
I have this one for x, after your previous suggestions:

JASS:
x = i2/udg_SUG_GridBreadth[i] - R2I(I2R(i2)/I2R(udg_SUG_GridBreadth[i]))
However, it still results to 0.00

To get back the problem: I have to integers, one divided through the other, resulting into a real. This real is going to be converted to integer then.

Edit: Never mind

JASS:
 x = I2R(i2)/I2R(udg_SUG_GridBreadth[i]) - R2I(I2R(i2)/I2R(udg_SUG_GridBreadth[i]))
This seems to work
Now y is still wrong, I investigate why.



Alright, it correctly calculates x and y now, thanks a lot guys!

For the distance check in GetTilePosition,
may I ask what was the alternate solution with Abs instead of Squareroot ?
 
SquareRoot((x-px)*(x-px)) will give the same result as RAbsBJ(x-px), but in your case I don't think you even need that? Shouldn't you simply be using (px-x) there?
 
Well, I had some turn-overs with the algebraic sign, but it seems simple now.

px = -512, x = -256 -> px-x = -256
px = - 512, x = 512 -> px-x = -1024
px = 512, x = 1024 -> px-x = -512

That's why I need Abs, doesn't I ? Since I need a positive integer after all.
 
But if point x is less than grid start x, wouldn't the point be outside the grid? The only way to pass the IsInGrid check at the start is if point x is greater than grid start x.

Of course, for y it is the opposite since your grid start point is in the upper-left corner, so there you'd use (y-py) instead of (py-y).
 
Yes, but point x is more than grid start x, since the grid starting point is in the left top corner of a grid. This way, point x is always equal or more than grid start x and the opposite for y.

However, there seems to be an inaccuracy with the IsInGrid function. I haven't investigated it yet, but if you see by chance why, I would be very grateful.

https://www.hiveworkshop.com/forums/spells-569/simple-grid-1-3-a-276337/
 
Status
Not open for further replies.
Back
Top