English 中文(简体)
In a triangulated isometric grid, what triangle is a given point in?
原标题:

I have a triangulated isometric grid, like this: alt text
(source: mathforum.org)

In my code, triangles are grouped by columns.

As I hover the mouse, I want to calculate what triangle the mouse coordinates are in. Is there a simple algorithm to do that?

问题回答

What you want to do is turn this into a grid as much as possible because grids are far easier to work with.

The first thing you do is work out what column it s in. You say you store that so it should be easier by doing a simple integer division on the x coordinate by the column width offset by the box start. Easy.

After that you want to work out what triangle it s in (obviously). How you partially turn this into a grid is you pretend that you have a stack of right angle triangles instead of a stack of isometric triangles.

The triangles have a length along the y axis (the side of the column). Divide that number in two and work out how many steps down you are. Based on the number of steps down and if the column is even or odd will tell you if you re looking at:

+--------+
|-_      |
|  -_    |
|    -_  |
|      -_|
+--------+

or the reverse. At this point you only need to determine which side of the line it s on to determine which right triangle it s in, which also tells you which isometric triangle it s in.

You have a couple of options for this.

  1. You could use something like Bresenham s line algorithm to rasterize the hypotenuse and when you hit the column you re in work out if you re above or below that line;
  2. Because you only have two possible grids here (one being the reverse of the other so it s really only one). You could store a array of row values, saying that for column 3, the hypotenuse is at offset 2, whereas for 6 it s at 4 and so on.

You could even use (1) to generate (2) as a fast lookup.

The only other thing to consider is what happens if the mouse cursor is on an edge?

This is similar to what cletus said, but a different way to look at it I suppose.

I am assuming the triangle side is 1.

Suppose you have the grid as below:

       y 
      /
     /__/__/__/__/__/__/
    /__/__/__/__/__/__/
   /__/__/__/__/__/__/____ x 
(0,0)

If you consider the grid in a co-ordinate system in which the x & y axes are at an angle of 60 degrees, a point whose co-ordinate in the angled system (x ,y ) will correspond to the coordinate in the orthogonal system (with same origin an general direction of axes) to (x,y).

In your problem, you are given (x,y), we need to find (x ,y ) and then figure out the triangle.

If i is the unit vector along x and j the orthogonal along y, then we have that

x * i + y ( i/2 + sqrt(3) * j /2) = xi + yj.

(Basically the unit vector along the angled y axis is i/2 + sqrt(3)/2 * j. The unit vector along the x axis is the same as the normal x-axis, i.e. i).

Thus

x  + y /2 = x
y  * sqrt(3)/2 = y

Solving gives:

y  = 2*y/sqrt(3)
x  = x - y/sqrt(3)

Assume for now that x and y are positive.

Now if c = [x ], the integer part of x

and r = [y ], the integer part of y

then in the (angular) grid, the point lies in the cth column and the rth row. (Counting right and up and start counting at 0).

Thus we have narrowed down your point to a parallelogram

       ____
      / * /   
     /___/
   (c,r)

Now in order to find out which triangle it is in you can consider the fractional parts of x and y .

{x} = x  - [x ] = x  - c.
{y} = y  - [y ] = y  - r.

Now,

if {x} + {y} > 1, then the point lies in the triangle marked with *. if {x} + {y} < 1, then the point lies in the other triangle. if {x} + {y} = 1, then the point lies on the line common to the two triangles.

Hope that helps too.





相关问题
How to add/merge several Big O s into one

If I have an algorithm which is comprised of (let s say) three sub-algorithms, all with different O() characteristics, e.g.: algorithm A: O(n) algorithm B: O(log(n)) algorithm C: O(n log(n)) How do ...

Grokking Timsort

There s a (relatively) new sort on the block called Timsort. It s been used as Python s list.sort, and is now going to be the new Array.sort in Java 7. There s some documentation and a tiny Wikipedia ...

Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Enumerating All Minimal Directed Cycles Of A Directed Graph

I have a directed graph and my problem is to enumerate all the minimal (cycles that cannot be constructed as the union of other cycles) directed cycles of this graph. This is different from what the ...

Quick padding of a string in Delphi

I was trying to speed up a certain routine in an application, and my profiler, AQTime, identified one method in particular as a bottleneck. The method has been with us for years, and is part of a "...

热门标签