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

[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:
Level 3
Joined
Mar 5, 2016
Messages
25
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)
 
Level 7
Joined
Oct 19, 2015
Messages
286
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.
 

Ardenian

A

Ardenian

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:

Ardenian

A

Ardenian

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)
 

Ardenian

A

Ardenian

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 ?
 
Level 7
Joined
Oct 19, 2015
Messages
286
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.
 

Ardenian

A

Ardenian

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 ?
 
Level 7
Joined
Oct 19, 2015
Messages
286
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?
 

Ardenian

A

Ardenian

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.
 
Level 7
Joined
Oct 19, 2015
Messages
286
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).
 

Ardenian

A

Ardenian

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.

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