0
\$\begingroup\$

I am using this approach:

http://clintbellanger.net/articles/isometric_math/

Basically, you can calculate the iso coordinates based on the screen coordinates. What I am doing is, getting the actual world position the mouse is pointing at using get_mouse_global_position() and convert this position to isometric values.

Then I translate those coordinates back to world space coordinates to actually display the sprite.

Problem is, that when the world coordinates come from a negative position, the tiles get offset by almost an entire tile amount. Here is the relevant code.

The get_coord() function returns the actual world position of the tile used to display the Sprite

func get_coord(pos : Vector2):
    var t = Vector2()
    var e = screen_to_iso(pos)
    t = iso_to_screen(e)
    print(pos)
    print(e)
    print(t)
    return t
    pass
var buildings

func screen_to_iso(pos :Vector2):
    var flipx = 0
    var flipy = 0
    var t = Vector2()
    var x_size = size/2
    var y_size = size/4
    t.x = int((pos.x/x_size) + (pos.y/y_size))/2
    t.y = int((pos.y/y_size) - (pos.x/x_size))/2
    return t
    pass

func iso_to_screen(pos : Vector2):
    var t = Vector2()
    var x_size = size/2
    var y_size = size/4
    t = Vector2((pos.x-pos.y)*x_size, (pos.x+pos.y)*y_size)
    return t
    pass

I can't seem to figure out a way

\$\endgroup\$
1
  • \$\begingroup\$ Geometric problems are often easier to solve if you can show the error visually in a screenshot or diagram. Or even an animated Gif so we can see how the output changes as the mouse moves. \$\endgroup\$
    – DMGregory
    Oct 15, 2020 at 12:00

1 Answer 1

1
\$\begingroup\$

I'm not familiar with the language you're using (GDScript?) but the usual reason for negative sides of a grid to be off by one is that you're using an operation that rounds towards zero, where you want one that rounds down.

t.x = int((pos.x/x_size) + (pos.y/y_size))/2
t.y = int((pos.y/y_size) - (pos.x/x_size))/2

I looked for documentation and this page says

int int ( float from )

Cast a float value to an integer value, this method simply removes the number fractions, so for example int(2.7) will be equals to 2, int(.1) will be equals to 0 and int(-2.7) will be equals to -2.

That will explain your error: you want -3 and you get -2.

One solution is to use the floor function, which always rounds towards negative numbers, before converting to int.

However, I notice that you're dividing by 2 after converting to int; dividing by 2 will also round towards zero, so you can't just insert int(floor(...)) into your existing expression. I haven't studied your code enough to understand it completely, but it's possible this would work (spaces and bold inserted to highlight differences):

t.x = int(floor( ( (pos.x/x_size) + (pos.y/y_size) )/2 ))
t.y = int(floor( ( (pos.y/y_size) - (pos.x/x_size) )/2 ))
\$\endgroup\$
2
  • \$\begingroup\$ You are awesome! :) Yes, it is GDScript and I got the code from the mentioned link. \$\endgroup\$
    – SPL
    Oct 17, 2020 at 9:09
  • \$\begingroup\$ Can I upvote you more than once? :D I was struggling with this for days now! \$\endgroup\$
    – SPL
    Oct 17, 2020 at 9:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .