Dynamic closest elements - grid

I have a 2D surface ( Grid ) with 50 elements at different locations.
I need to decide which are the 10 closest elements to a given point.
In addition, the given point is constantly moving and i need to do the calculation on each movement.
I know I can calculate the Euclidean distance to each point on each movement, but I want a faster way.
Thanks.

It sounds like you're trying to come up with a way where you can take the 10 closest points at time t and use those to help you figure out the 10 closest at time t+1. Here's an idea to consider.
When you calculate the 10 closest points, also store the angular direction of where they are relative to your current location. Then, when you move you can calculate the direction in which you moved. Focus your search on the space that's opened up to you (think of a circle around point A and another around point B. The space in B but not in A is where you want to focus your search).
Of course, to do this you need to have some way of searching in a particular area of the grid instead of doing a linear search through an array of points to find those close to you. I'd recommend looking into BSP trees for that. If you're not doing it already, using BSP trees instead of linear search might alone be the performance boost you're looking for.

So, I am going to put all the attempts that I went over to figure out my implementation and hopefully you will be able to figure out the best approach for you project.
I am working on somewhat similar project to what you have mentioned. But in my case I need to do extra cycles once I found the points within a given distance threshold. I have tried few iterations, first I started by creating a distance grid. Keep in mind, I am not working on 2D surface but I don't think changing this to 2D will take much work.
Here is how I developed my distance grid (its so simple even a cave man can do it, I making fun of myself) , Also keep in mind I didn't continue using the grid to finish up my implementation.
public double[][] distanceGrid() {
double[] gridSize = combineArrays(generateClusters(1, 3), generateClusters(12, 15));
double [][] pointsDistanceGrid = new double[gridSize.length][gridSize.length];
for (int i = 0; i < pointsDistanceGrid.length; i++) {
for (int j = 0; j < pointsDistanceGrid[i].length; j++) {
pointsDistanceGrid[i][j] = Math.abs(gridSize[i] - gridSize[j] );
System.out.print(" " + pointsDistanceGrid[i][j]);
}
System.out.println("");
}
return pointsDistanceGrid;
}
As I mentioned I didn't use it.
Since I had to deal with a distance threshold, and I decided before finding "The Nearest" i wanted to see all the points that are closer to the particular point that I am looking at, so I implemented this method.
/**
* Given a point method returns an array with point that are within the limit of threshold.
* #param point
* #return
*/
public double[] pointsWithinThreshold(double point) {
double[] neighbors = new double[bigCluster.length];
for (int i = 0; i < bigCluster.length; i++) {
if (bigCluster[i] != point) {
double distance = 0;
distance = Math.abs(point - bigCluster[i]);
if (distance <= getDistanceThreshold()) {
neighbors[i] = bigCluster[i];
}
}
}
return neighbors;
}
After this I realize I don't really care what are all the closest points so I end up not using this and refractor some of this functionalities to a method where I get the closest member and do recursive DFS.
Let me know if you would like to see that, I didn't put it here coz I thought you only need to know the closest 10 member.
Hope this helps and good luck.

Related

Is there a method for generating multiple irregular polygons and/or irregular blobs of equal surface area using p5.js?

For neuroscience research I'm attempting to train rats to press shapes on a touch screen. Ideally, these shapes would be highly distinct polygons or blobs to make it easier for the rats to discriminate. However, to limit some biases toward certain shapes, I'd like to keep the area of each shape equivalent. I've been trying to achieve this on p5.js, but I'm very new to this.
The code I've got so far provides some of the shape randomness, but not the consitency in area:
function setup() {
createCanvas(500, 500);
background(255);
fill(0);
translate(width/2, height/2);
beginShape();
for(let i = 0; i < 5; i++) {
const x = random(-250, 250);
const y = random(-250, 250);
vertex(x, y);
endShape();
}
}
Any help achieving this would be very appreciated
Maybe it's not what you need, the shapes are all inscribed in a circle(edit:the second code ones), not a bounding box as I said earlier.
Both examples are online at p5js editor:
The code I had was more free form, it will eternally increase the number of sides:
about 20 sides:
about 130 sides
But at the begining its more what I think you need
the code is here:
https://editor.p5js.org/v-k-/sketches/siYtDw423
And...
I made a tweeked version to try to go closer to what I think you want :)
The code is here:
https://editor.p5js.org/v-k-/sketches/oMsWC2NHv
Perhaps you can play with the numbers to get What you need. For instance:
You can set the number of sides, or even reject sides smaller than something.
It's very simple stuff ;) Easy to tweek.
Have fun, hope the rats like it.

Unity3D Linear interpolation from V1 to moving V2

I posted this question on the stack math site, but they are not too excited to see questions including programming. Anyway, now I am here :)
I have an object, which is located at MyTransform.position (Vector)
That object should follow the DesiredPosition (Vector), which is
moving in varius directions with a changing velocity
MaxDelayDistance (float) is the maximum distance my object is allowed
to have to the DesiredPosition.
DelayRecovery (float) are the seconds my object has in order to move
to the DesiredPosition if the MaxDelayDistance is reached.
Time.deltaTime (float) is a term we use to describe the time the last
frame update took. It's value is usually about 0.025f.
private Vector3 GetLerpedPosition(Vector3 DesiredPosition) {
//DesiredPosition now contains the goal
Vector3 dirToDesiredPosition = (DesiredPosition - MyTransform.position).normalized; //Direction to desired position
Vector3 lerpStart = DesiredPosition + (-dirToDesiredPosition * MaxDelayDistance); //Start the lerp at my farthest allowed position
float lerpCurrentT = Vector3.Distance(MyTransform.position, DesiredPosition) / Vector3.Distance(lerpStart, DesiredPosition); //My current fragtion (t) of the lerp
//Now I lerp from lerpStart to DesiredPosition using a calculated fraction
Vector3 result = Vector3.Lerp(
lerpStart,
DesiredPosition,
lerpCurrentT + (DelayRecovery / MaxDelayDistance * Vector3.Distance(MyTransform.position, DesiredPosition) * Time.deltaTime)
);
return result;
}
The main problem is that my object is not following the DesiredPosition smoothly.
It jumps from MaxDelayDistance to DesiredPosition and back.
Somehow the fraction (t) in my Lerp function always results in about 1.005 or about 0.001. Can you spot any problems in my approach?
I see several issue, and I'm not sure of the direction you have choose (at least never seen anything similar before).
Preamble:
Vector3.Distance(lerpStart, DesiredPosition)
this is a constant and is the radius around DesiredPosition.
Here's some problems I noticed:
Problem 1
lerpT is always >=1 for every point more distant more than MaxDelayDistance (outside the radius). So when an object is further distant than MaxDelayDistance it will be immediately moved to DesiredPosition.
Problem 2
DelayRecovery (float) are the seconds my object has in order to move
to the DesiredPosition if the MaxDelayDistance is reached.
Not sure of having completely understood your intricate lerp, btw the statement above seems to be false. DelayRecover is always taken in consideration while lerping despite its distance.
Problem 3
Possible division by zero when you are closed to DesiredPosition (* operator is evaluated before /)
Some considerations
I'll read with more attention your code, and I'll try to figure out the logic behind that. It's something I've never seen.
Some general approach for moving toward a given position:
If start and destination are known and fixed, than lerping (or an ease function) allow to control exactly the travel time incrementing t parameter from 0 to 1.
If destination is moving you can still smooth follow the target using lerp (maybe not the more correct use from a theoretical point of view, nor physical realistic but in any case effective). Lerp factor in this case is a kind of "speed toward the goal". Effectively linear proportional to the distance from the target.
Some physic based approach. Integrate. Define some kind of max speed and max acceleration and calculate the next position (eventually clamp to prevent overshooting and oscillation)
PID controllers. Lot of power, but I always found them hard to tweak.
Consider also to use Vector3.MoveToward, here's how it's implemented:
public static Vector3 MoveTowards(Vector3 current, Vector3 target, float maxDistanceDelta)
{
Vector3 a = target - current;
float magnitude = a.magnitude;
if (magnitude <= maxDistanceDelta || magnitude == 0f)
{
return target;
}
return current + a / magnitude * maxDistanceDelta;
}
Hope this helps.

Constrained (Delaunay) Triangulation

For a university project I need to implement a computer graphics paper that has been relased a couple of years ago. At one point, I need to triangulate the results I get from my simulation. I guess its easier to explain what I need looking at a picture contained within the paper:
Let's say I already have got all the information it takes to reconstruct the contour lines that you can see in the second thumbnail. Using those I need to do some triangulation using those siluettes as constrains. I have searched the internet for triangulation libraries like CGAL, VTK, Triangle, Triangle++, ... but I always ended up throwing my hands up in horror. I am not a good programmer and it seems impossible to me to get into one of those APIs before the deadline of this project passes.
I would appreciate any kind of help like code snipplets, tips, etc...
I know that the algorithms need segments (pairs of points) as input, so let's say I have got one std::vector containing all pairs of points defining the siluette as well as the left and right side of the rectangle.
Can you somehow give me a code snipplet for i.e. CGAL that I could use for my purpose? First of all I just want to achieve the state of the third thumbnail. Lateron I will have to do some displacement within the "cracks" and finally write the information into a VBO for OpenGL rendering.
I have started working it out with CGAL. One simple problem still drives me crazy:
It is possible to attach informations (like ints) to points before adding them up to the triangulator object. I do this since I need on the one hand an int-flag that I use lateron to define my texture coordinates and on the other hand an index which I use so that I can create a indexed VBO.
http://doc.cgal.org/latest/Triangulation_2/Triangulation_2_2info_insert_with_pair_iterator_2_8cpp-example.html
But instead of points I only want to insert constraint-edges. If I insert both CGAL returns strange results since points have been fed into two times (once as point and once as point of a constrained edge).
http://doc.cgal.org/latest/Triangulation_2/Triangulation_2_2constrained_8cpp-example.html
Is it possible to connect in the same way as with points information to "Constraints" so that I can only use this function cdt.insert_constraint( Point(j,0), Point(j,6)); before I iterate over the resulting faces?
Lateron when I loop over the triangles I need some way to access the int-flags that I defined before. Like this but not on acutal points but the "ends" defined by the constraint edges:
for(CDT::Finite_faces_iterator fit = m_cdt.finite_faces_begin(); fit != m_cdt.finite_faces_end(); ++fit, ++k) {
int j = k*3;
for(int i=0; i < 3; i++) {
indices[j+i] = fit->vertex(i)->info().first;
}
}

How to show if two objects are moving away in 3D space

I am working on a yet another 3d game engine and have following Problem. In order to improve Performance I want to check if two Objects are coming closer or moving away from each other. Only if they are coming closer to each other collision detection should happen.
At the moment the code calculates the current distance using the positions of both Objects. Then moves both positions about the velocity vector and calculates the expected distance. etc.
public class Model{
public boolean isApproaching(Model model) {
float [] otherPosition = model.getPosition();
float [] otherVelocity = model.getVelocity();
double currentDistance = Math.pow(this.position[0] - otherPosition[0], 2)
+ Math.pow(this.position[1] - otherPosition[1], 2)
+ Math.pow(this.position[2] - otherPosition[2], 2);
double expectedDistance = Math.pow(this.position[0] + this.velocityVector[0]/1000 - otherPosition[0] - otherVelocity[0]/1000, 2)
+ Math.pow(this.position[1] + this.velocityVector[1]/1000 - otherPosition[1] - otherVelocity[1]/1000, 2)
+ Math.pow(this.position[2] + this.velocityVector[2]/1000 - otherPosition[2] - otherVelocity[2]/1000, 2);
if(currentDistance < expectedDistance)
return false;
return true;
}
}
As you can see in the Picture it does not work for fast moving objects. Is there any good way to show if two points are moving towards each other?
Given the two straight line trajectories, there's a unique time when they're going to be closest, which may have been in the past. If it's in the past then it means that the objects are moving away from each other, but if its in the future it means that they're moving closer together. But even it they're moving closer together, I would guess that knowing how soon is the information that you need, so that you can schedule when to worry about it. This methodology should cater for both slow moving and fast moving objects.
It appears that you are using the /1000 versus any other value for some unstated reason that may negate the following.
By changing this scale factor you get better detection with a fast object. Perform your same isApproaching() calculation except with a /(1000*N) instead of /1000. You will then has N times better sensitivity to know if they are approaching or not.

find three nearest point

I have a list of points in cartesian plane, and a test point. I want to find list indices of three points nearest to test point. What's the better way to find these indices? Thanks in advance for tour replies.
=== EDIT ===
I've found a solution in C++. At first I create a vector:
typedef struct
{
int iIndex;
double dSqrDistance;
} IndexedDistance;
std::vector<IndexedDistance> xDistanceVector;
and then a function to sort its elements
bool compareIndexedDistance(IndexedDistance xD1, IndexedDistance xD2)
{
return (xD1.dSqrDistance < xD2.dSqrDistance);
}
Then in a loop I calculate all distances, then I sort them and at the end I take first three elements:
IndexedDistance xDistanceElement;
for (int i = 0; i < xPointList.size(); i++)
{
dSqrDistance = xPointList.at(i).sqrDistance(xTestPoint);
xDistanceElement.iIndex = i;
xDistanceElement.dSqrDistance = dSqrDistance;
xDistanceVector.push_back(xDistanceElement);
}
std::sort(xDistanceVector.begin(), xDistanceVector.end(), compareIndexedDistance);
xDistanceVector.resize(3);
In this way, I found what I need. I don't know if it's the best way, but it seems to work.
Binary space partitioning may provide algorithms complexity of O(log n * log n).
Determine bounds of your point set. Infinum and supremum points will give you an axis-aligned square containing all the points in set.
Split the bounding square in two by any of axis. Make a separate list of contained points for each square. Link each of bounding squares to the parent square.
Repeat splitting bounding squares (step 2) until corresponding lists of containing points will be reasonably small to utilize exhaustive search.
Now you will be able to use tree search to localize space around your point of interest and therefore greatly reduce number of distance tests.
The tricky part is that you must scan all the neighbour bounding squares around the point of interest because the closest point may lie in any of them.

Resources