I would like to write a function that returns closest grid node (as a point) of a triangular grid (made of equilateral triangles with a base width w, parallel to OX axis) closest to some point p. Grid starts in point s. Function signature should look like:
def snapToGrid(p,w,s):
...
for exapmle snapToGrid([0.49,0],0.5,[0.0]) == [0.5,0]
any ideas how to start?
EDIT: This answer was before knowing that the triangular grid was to be dynamically computed, I will leave it up for now, because it could be helpful, but it will not help with dynamic point generation.
I do believe the answer to dynamically generating the points will rely on finding the height of a triangle and then realising that the nodes will only ever exist at multiples of that triangle height.
This should take care of your X
component.
Finding the width of a triangle will also tell you the multiples at which the nodes occur along the Y
axis, however, every second row of triangles will have the node point at 1/2 the width of the triangle.
Finding the number of rows away from your origin your original point will be is the first step.
This in turn will allow let you know whether to use triangle width
as the the Y
coordinate multiple, or triangle width+1/2 triangle width
for the Y
multiplier.
Using these two values it should be easy to find the closest n*height
and n*width
combination that is closest to your point.
Sorry about the wall of text, if you draw your grid on paper, you will see that the triangles form rows of nodes along the X
axis, and columns (for even rows
) and half columns (for odd rows
).
When finding the nearest point it usually doesn't matter what type / shape the grid is. Logically the point you are closest to will belong to the shape your point is in. So to simplify things all you need to do is find the nearest point to yours, which is quite a simple problem.
This seems like it would most easily be found by using a K-D Tree, where the split points are the X
and Y
coordinates of the grid. A simple binary search will then reveal the closest grid point to the coordinate you have input.
The linked article has pseudo code for K-D Tree operations.
You could also have a dictionary mapped to X
coordinates, with each value containing a dictionary of y:name
pairs that correspond to that X
coordinate.
This will allow you to search for a node in the following way:
coordinate_x[<xvale>][<yvalue>]
which will then return the node you are looking for, to get xvalue
and yvalue
simply do a nearest search through the dictionary keys like:
for x in coordinate_x.keys():
if x-point_x < min:
make x-point the closest