How to find nearest N grid points (greedy) - arrays

I'm using 2d arrays for to handle objects in a game. The dimensions of the array act like coordinates on a cartesian grid. When the player selects a point on I want to collect the N nearest grid cells from the array, even if the point is not a valid array index.
Example:
An array that goes from [0,0] to [10,10]
If the player selects (-1,-1), N=3, the nearest points would be [(0,0),(0,1),(1,0)]
The brute force approach would be to calculate the euclidean distance between the point selected and each array grid cell, put it in a list, and then sort. With very large arrays this might be performance prohibitive. Is there any greedier way to do this, if for example I knew what N was?
I know if the point selected was INSIDE the grid we could use the formula for a circle to get a rough area to check e.g. N/Pi = R^2. We can check the square that this R value creates in the x and y dimensions, which is much faster.
But what about when the point selected is near the edge of the grid. or off it? Or if you want to ignore certain grid cells?

I would start by finding the point with fractional co-ordinates (that is, not necessarily integers) which is closest to the given point. If only one co-ordinate is outside the range of the grid then just set this co-ordinate to the nearest in-range co-ordinate. If both co-ordinates are outside the range of the grid, then the closest point will be one of the corners.
Given that starting point you need to find N points with integer co-ordinates. If the closest point was a corner it already has integer co-ordinates. Otherwise the closest point is one of the grid points to either side of the closest point.
You know the other N-1 points will be connected to the closest grid point, because you are working out the intersection of two convex shapes - a circle and a rectangle. I would keep a heap of points ordered by distance. Start it off with the neighbours of the closest grid point. Repeatedly remove the point in the heap nearest to the original point outside the grid and put into the heap its neighbours, if they are not there already, until you have extracted the other N-1 points.

Related

How do I transform a distorted quadratic polynomial obtained from a 2D image of 3D space and obtain its formula?

Given an array of points representing a quadratic polynomial but that is warped/distorted due to the 3D perspective of the image (see figure 1). The first index of the array contains (x,y) pixel coordinate of the left intersection with the x-axis, the last index of the array contains the (x,y) pixel coordinate of the right intersection with the x-axis.
How can I transform each pixel coordinate of the array into a formula for the quadratic polynomial as depicted in figure 2? Is this even possible?
I have tried to use the cross-ratio as it does contain a vanishing point, but was unable to see if and how that would be helpful in this case. I also think the polynomial regression theory can be of use in some way.

Add Random Number to List only if it's different than others

I'm designing a game in Scratch. The game is suppose to have a Spaceship travel through space, avoiding asteroids. These asteroids start at a fixed X position on the right side of the screen and go to the left, horizontally until they hit a fixed X position and they'll disappear. The asteroids will start in groups between 2-6 (it's a random number generated), and each set is about 1 second apart.
Assuming the game throws out up to 6 asteroids at once, I want to make sure each asteroid is distant from the next. I tried using two variables and comparing the distance, but this did not work. I can put the group of asteroids Y spawning position into a list. So say for instance in my list, I have:
0, 100, 5, 30, -20
As you can see, there are two items in that list that are close together. What I'm trying to do, is prevent this, so the third item would be something else, like -50, for instance, and then if a six item is generated, ensure it's also distant.
Can someone pseudocode how to achieve something like this? It doesn't matter what programming language it's in, I can probably translate the general idea into Scratch.
There is a way to do this without a trial-and-error loop.
Instead of picking random positions, pick random distances, then scale them to fit the screen.
Roughly, the approach is as follows.
The lists below represent the distances between neighboring asteroids (ordered by Y coordinate), as well as distances between the outermost asteroids and the edges of the screen.
For example, if a group contains 6 asteroids, then you need lists of 7 elements each.
Create a list L1 of minimal distances. Obviously, these are all fixed values.
Create a list L2 of random numbers. Take them from some arbitrary, fixed range with a positive lower bound, e.g. [1..100].
Calculate the total 'slack' = height of screen minus sum(L1).
Calculate a multiplication factor = slack divided by sum(L2).
Multiply every element of L2 with the multiplication factor.
Add every value from L1 to the value in L2 at the same index.
L2 now contains a list of distances that:
obey the minimal distances specified in L1
together equal the height of the screen
The final step is to position every asteroid relative to its neightbor, based on the distances in L2.
Note: if step 3 gives a negative number, then obviously there is not enough room on screen for all asteroids. What's worse, a naive 'trial-and-error' algorithm would then result in an infinite loop. The solution is of course to fix your parameters; you cannot fit 6 asteroids in 360 pixels with a minimal distance of 100.
To do this, you need to do through each previous entry in the array, compare that value to the new value, and if any element is too close change the value. This process needs to repeat until a suitable number is found. If this number is less then some minimum distance, then a variable tooClose is set to yes and the value will be reset. At the begining of the loop tooClose is set to yes so that at least one random number will be generated. Then, at the beginning of the loop, the value is randomized, and tooClose is set to no, then, I loop through all the previous entries with the value i, comparing each element and setting tooClose to yes if it is too close. The comparison between numbers is done with a subtraction, followed by an absolute value, which will ensure the result is positive, giving the difference between the two numbers as a positive value.
Here is a screenshot of the code:
And here is the project:
https://scratch.mit.edu/projects/408196031/

Julia: extract nearest neighbors from first shell of Voronoi tesselation

I'm assuming the best answer to this question requires using VoronoiDelaunay.jl, but I'm also open to other packages/approaches.
If I have a set of points in 2D (or 3D? Though not I'm not sure this is possible with the package VoronoiDelaunay.jl), what is the fastest way to get each of their nearest neighbors in a Voronoi-tesselation sense (e.g the neighbors within the 'first Voronoi shell')? I am also not really confident on the mathematics behind this or how it relates to Delaunay triangulation.
The data structure doesn't matter too much to me, but let's just assume the data is stored in a 2D array of type Array{Float64,2} called my_points, whose size is (nDims, nPoints), and nDims is 2 or 3, and nPoints is the number of points. Let's say I want to have the output be an edge list of some kind, e.g. array of arrays called edge_list (Array{Array{Int64,1}}) where each element i of edge_list gives me the indices of those points that are Voronoi neighbors of the focal point i (whose coordinates are stored in my_points[:,i]).
For every point (point in the red tessellation), I want the coordinates / identities of the points that are its Voronoi neighbors (the points in the orange tessellations). This image is taken from Figure 1b of this paper: https://journals.plos.org/ploscompbiol/article?id=10.1371/journal.pcbi.1002678

Filling a plane with random points

I would like to fill a plane with randomly placed points, check whether any of them overlap (and if they do, move one of them to empty place) and then calculate the average distance between them. Later I plan on extending that to 3D so that it is kind of having particles in a box.
I know there must be better ways of doing it but here's what I came up with. For placing random points in a plane:
int pos[NUMBER][2]; /* Creates an array of NUMBER amount of points with x and y coordinate */
int a, b;
srand( time(NULL) );
for(a=0;a<NUMBER;a++)
for(b=0;b<2;b++)
pos[a][b]=rand()%11; /* Using modulus is random enough for now */
The next stage is finding points that over lap:
for(a=0;a<NUMBER-1;a++)
for(b=a+1;b<NUMBER;b++)
if( pos[a][0] == pos[b][0] && pos[a][1] == pos[b][1])
printf("These points overlap:\t", pos[a][0], pos[a][1]);
Now when I identify which points overlap I have to move one of them, but when I do the point in new position might overlap with one of the earlier ones. Is there any accepted way of solving this problem? One way is infinite while(true) loop with breaking condition but that seems very inefficient especially when system gets dense.
Thank you!
Here's a sketch of a solution that I think could work:
Your point generation algorithm is good, can be left as is.
The correct time to check for overlap is already when the point is generated. We simply generate new points until we generate one that doesn't overlap with any previous.
To quickly find overlap, use a hash table such as the one from '''glib'''. The key could be two int32_t packed into a int64_t union:
typedef union _Point {
struct {
int32_t x;
int32_t y;
};
int64_t hashkey;
} Point;
Use the "iterate over all keys" functionality of your hash table to build the output array.
I haven't been able to test this but it should work. This assumes that the plane is large in relation to the number of points, so that overlaps are less likely. If the opposite is true, you can invert the logic: start with a full plane and add holes randomly.
Average complexity of this algorithm is O(n).
As you hinted that it should work for high densities as well, the best course of action is to create a 2D array of booleans (or bit vectors if you want to save space), where all elements are set to false initially. Then you loop NUMBER times, generating a random coordinate, and check whether the value in the array is true or not. If true, you generate another random coordinate. If false, you add the coordinate to the list, and set the corresponding element in the array to true.
The above assumes you want exactly NUMBER points, and a completely uniform chance of placing them. If either of those constraints are not necessary, there are other algorithms possible that use much less memory.
One solution is to place points at random, see if they overlap, and re-try on overlap. To avoid testing every point, you need to set up an index by space - if you have a 100*100 plane and a cut-off of 3-4, you could use 10*10 grid squares. Then you have to search four grid squares to check you don't have a hit.
But there are other ways of doing it. Uniformly placing points on a gird will create a Poisson distribution. So for each point, you can create a random number with the Poisson distribution. What happens when you get 2 or more? This method forces you to answer that question. Maybe you artificially clamp to one, maybe you move into the neighbouring slot. This method won't create exactly N points, so if you must have N, you can put in a fudge (randomly add/remove the last few points).

How do I build a Voronoi diagram over a grid of points?

I have a two-dimensional array of doubles that implicitly define values on a two-dimensional bounded integer lattice. Separately, I have n 2D seed points (possibly with non-integer coordinates). I'd like to identify each grid point with its closest seed point, and then sum up the values of the grid points identified with each seed point.
What's the most efficient way to do with with JTS/Geotools? I've gotten as far as building a Voronoi diagram with VoronoiDiagramBuilder, but I'm not sure how to efficiently assign all the grid points based on it.
The best way to do this depends on the size of n and the number of polygons in your voronoi diagram. However basically you need to iterate of one of the sets and find the element in the other set that interacts with it.
So assuming that n is less than the number of polygons, I'd do something like:
// features is the collection of Voronoi polygons
// Points is the N points
Expression propertyName = filterFactory.property(features.getSchema()
.getGeometryDescriptor()
.getName());
for (Point p: points) {
Filter filter = filterFactory.contains(propertyName,
filterFactory.literal(p));
SimpleFeatureCollection sub = features.subCollection(filter);
//sub now contains your polygon
//do some processing or save ID
}
If n is larger than number of polygons - reverse the loops and use within instead of contains to find all the points in each polygon.

Resources