How do I distribute 5 points evenly onto an irregular shape? - algorithm

Here is a problem I am trying to solve:
I have an irregular shape. How would I go about evenly distributing 5 points on this shape so that the distance between each point is equal to each other?

David says this is impossible, but in fact there is an answer out of left field: just put all your points on top of each other! They'll all have the same distance to all the other points: zero.
In fact, that's the only algorithm that has a solution (i.e. all pairwise distances are the same) regardless of the input shape.
I know the question asks to put the points "evenly", but since that's not formally defined, I expect that was just an attempt to explain "all pairwise distances are the same", in which case my answer is "even".

this is mathematically impossible. It will only work for a small subset of base shapes.
There are however some solutions you might try:
Analytic approach. Start with a point P0, create a sphere around P0 and intersect it with the base shape, giving you a set of curves C0. Then create another point P1 somewhere on C0. Again, create a sphere around P1 and intersect it with C0, giving you a set of points C1, your third point P2 will be one of the points in C1. And so on and so forth. This approach guarantees distance constraints, but it also heavily depends on initial conditions.
Iterative approach. Essentially form-finding. You create some points on the object and you also create springs between the ones that share a distance constraint. Then you solve the spring forces and move your points accordingly. This will most likely push them away from the base shape, so you need to pull them back onto the base shape. Repeat until your points are no longer moving or until the distance constraint has been satisfied within tolerance.
Sampling approach. Convert your base geometry into a voxel space, and start scooping out all the voxels that are too close to a newly inserted point. This makes sure you never get two points too close together, but it also suffers from tolerance (and probably performance) issues.
If you can supply more information regarding the nature of your geometry and your constraints, a more specific answer becomes possible.

For folks stumbling across here in the future, check out Lloyd's algorithm.

The only way to position 5 points equally distant from one another (other than the trivial solution of putting them through the origin) is in the 4+ dimensional space. It is mathematically impossible to have 5 equally distanced object in 3D.
Four is the most you can have in 3D and that shape is a tetrahedron.

Related

Identifying Number of Events

I have many rays, all whose start points are on a sphere in 3D, and whose direction vectors point inwards. Some of the rays are pointing towards a point A, others are pointing towards a point B, etc, with some noise (i.e. the rays don't perfectly intersect each other at their corresponding point A, B, etc).
Is there an algorithm that will allow me to determine how many points A,B, etc there are? Or even better, where those points are located? I don't know the locations of points A, B, etc, only the start points and direction vectors of the rays.
For example, is a sample setup, but in 2D, and I don't know which rays are pointing to which point (i.e. I don’t know which rays are red or blue). How would I find the number of points they’re pointing towards (two, in this example) or the locations of the points they're pointing towards?
I’ve tried a few different algorithms suggested in my earlier question, but they all seem to lose accuracy in identifying the locations of the points when the points are located close to each other. My first priority is just identifying the number of points with a high degree of accuracy even when they are located close together. Would that be possible, even if I have to sacrifice accuracy in locations?
Edit: If we let the radius of the sphere be 1000 units, then the error in the direction vector is about 10-20 units, while the min distance that the points can be apart for the algorithm to work currently is around 50 units. I don’t think this seems insurmountable, but I may very well be wrong.
I suggest that you treat this as a changing variant of the point-clustering problem.
First, make a set of points. Choose an approach threshold: how close should two rays come before you suspect that they refer to the same point? For each pair of rays that satisfies this threshold, insert a point at the midpoint of the segment of their closest approach. This is simple (?) 3D linear algebra.
Now, use your favorite cluster-counting algorithm to determine the quantity of clusters you have among these points. Your approach threshold will be highly significant in discriminating nearby points (see my comment).
Edit: thanks for the update in your question. The 50-unit separation in your data, compared to the 10-20 unit error, should allow you to discriminate "near" centroids using a density-sensitive clustering algorithm. Perhaps one of the spectral clustering methods will do the job for you.
You now have `k' identified clusters. Adapt the k-means clustering algorithm.
Choose the midpoint of each cluster as the centroid.
Delete all the "closest approach" points you made in the previous iteration. Keep the centroids.
Determine the cluster to which each ray belongs: your distance function is the closest approach of the ray to each of the centroids.
As you classify each ray, add to that cluster the point of that ray's closest approach to the centroid.
Repeat steps 1-4 until you've converged according to whatever epsilon criterion you have. The centroids are your targe points (A, B, etc.)
If you have any outliers, suspect that you are short a centroid.
If the centroids are too close (by whatever nearness criterion you can extract), then merge them.

Find the point furthest away from n other points

I am trying to create an algorithm for 'fleeing' and would like to first find points which are 'safe'. That is to say, points where they are relatively distant from other points.
This is 2D (not that it matters much) and occurs within a fixed sized circle.
I'm guessing the sum of the squared distances would produce a good starting equation, whereby the highest score is the furthest away.
As for picking the points, I do not think it would be possible to solve for X,Y but approximation is sufficient.
I did some reading and determined that in order to cover the area of a circle, you would need 7 half-sized circles (with centers forming a hex, and a seventh at the center)
I could iterate through these, all of which are within the circle to begin with. As I choose the best scoring sphere, I could continue to divide them into 7 spheres. Of course, excluding any points which fall outside the original circle.
I could then iterate to a desired precision or a desired level.
To expand on the approach, the assumption is that it takes time to arrive at a location and while the location may be safe, the trip in between may not. How should I incorporate the distance in the equation so that I arrive at a good solution.
I suppose I could square the distance to the new point and multiply it by the score, and iterate from there. It would strongly favor a local spot, but I imagine that is a good behavior. It would try to resolve a safe spot close by and then upon re-calculating it could find 'outs' and continue to sneak to safety.
Any thoughts on this, or has this problem been done before? I wasn't able to find this problem specifically when I looked.
EDIT:
I've brought in the C# implementation of Fortune's Algorithm, and also added a few points around my points to create a pseudo circular constraint, as I don't understand the algorithm well enough to adjust it manually.
I realize now that the blue lines create a path between nodes. I can use the length of these and the distance between the surrounding points to compute a path (time to traverse and danger) and weigh that against the safety (the empty circle it is trying to get to) to determine what is the best course of action. By playing with how these interact, I can eliminate most of the work I would have had to do, simply by using the voronoi. Also my spawning algorithm will use this now, to determine the LEC and spawn at that spot.
You can take the convex hull of your set of locations - the vertices of the convex hull will give you the set of "most distant" points. Next, take the centroid of the points you're fleeing from, then determine which vertex of the convex hull is the most distant from the centroid. You may be able to speed this up by, for example, dividing the playing field into quadrants - you only need to test the vertices that are in the furthermost quadrant (e.g., if the centroid is in the positive-x positive-y quadrant, then you only need to check the vertices in the negative-x negative-y quadrant); if the playing field is an irregular shape then this may not be an option.
As an alternative to fleeing to the most distant point, if you have a starting point that you're fleeing from (e.g. the points you're fleeing from are enemies, and the player character is currently at point X which denotes its starting point), then rather than have the player flee to the most distant point you can instead have the player follow the trajectory that most quickly takes them from the centroid of the enemies - draw a ray from the enemies' centroid through the player's location, and that ray gives you the direction that the player should flee.
If the player character is surrounded then both of these algorithms will give nonsense results, but in that case the player character doesn't really have any viable options anyway.

How to find if a 3D object fits in another 3D object (the container)?

Given two 3d objects, how can I find if one fits inside the second (and find the location of the object in the container).
The object should be translated and rotated to fit the container - but not modified otherwise.
Additional complications:
The same situation - but look for the best fit solution, even if it's not a proper match (minimize the volume of the object that doesn't fit in the container)
Support for elastic objects - find the best fit while minimizing the "distortion" in the objects
This is a pretty general question - and I don't expect a complete solution.
Any pointers to relevant papers \ articles \ libraries \ tools would be useful
Here is one perhaps less than ideal method.
You could try fixing the position (in 3D space) of 1 shape. Placing the other shape on top of that shape. Then create links that connect one point in shape to a point in the other shape. Then simulate what happens when the links are pulled equally tight. Causing the point that isn't fixed to rotate and translate until it's stable.
If the fit is loose enough, you could use only 3 links (the bare minimum number of links for 3D) and try every possible combination. However, for tighter fit fits, you'll need more links, perhaps enough to place them on every point of the shape with the least number of points. Which means you'll some method to determine how to place the links, which is not trivial.
This seems like quite hard problem. Probable approach is to have some heuristic to suggest transformation and than check is it good one. If transformation moves object only slightly out of interior (e.g. on one part) than make slightly adjust to transformation and test it. If object is 'lot' out (e.g. on same/all axis on both sides) than make new heuristic guess.
Just an general idea for a heuristic. Make a rasterisation of an objects with same pixel size. It can be octree of an object volume. Make connectivity graph between pixels. Check subgraph isomorphism between graphs. If there is a subgraph than that position is for a testing.
This approach also supports 90deg rotation(s).
Some tests can be done even on graphs. If all volume neighbours of a subgraph are in larger graph, than object is in.
In general this is 'refined' boundary box approach.
Another solution is to project equal number of points on both objects and do a least squares best fit on the point sets. The point sets probably will not be ordered the same so iterating between the least squares best fit and a reordering of points so that the points on both objects are close to same order. The equation development for this is a lot of algebra but not conceptually complicated.
Consider one polygon(triangle) in the target object. For this polygon, find the equivalent polygon in the other geometry (source), ie. the length of the sides, angle between the edges, area should all be the same. If there's just one match, find the rigid transform matrix, that alters the vertices that way : X' = M*X. Since X' AND X are known for all the points on the matched polygons, this should be doable with linear algebra.
If you want a one-one mapping between the vertices of the polygon, traverse the edges of the polygons in the same order, and make a lookup table that maps each vertex one one poly to a vertex in another. If you have a half edge data structure of your 3d object that'll simplify this process a great deal.
If you find more than one matching polygon, traverse the source polygon from both the points, and keep matching their neighbouring polygons with the target polygons. Continue until one of them breaks, after which you can do the same steps as the one-match version.
There're more serious solutions that're listed here, but I think the method above will work as well.
What a juicy problem !. As is typical in computational geometry this problem
can be very complicated with a mismatched geometric abstraction. With all kinds of if-else cases etc.
But pick the right abstraction and the solution becomes trivial with few sub-cases.
Compute the Distance Transform of your shapes and Voilà! Your solution is trivial.
Allow me to elaborate.
The distance map of a shape on a grid (pixels) encodes the distance of the closest point on the
shape's border to that pixel. It can be computed in both directions outwards or inwards into the shape.
In this problem, the outward distance map suffices.
Step 1: Compute the distance map of both shapes D_S1, D_S2
Step 2: Subtract the distance maps. Diff = D_S1-D_S2
Step 3: if Diff has only positive values. Then your shapes can be contained in each other(+ve => S1 bigger than S2 -ve => S2 bigger than S1)
If the Diff has both positive and negative values, the shapes intersect.
There you have it. Enjoy !

Detect when 2 moving objects in 2d plane are close

Imagine we have a 2D sky (10000x10000 coordinates). Anywhere on this sky we can have an aircraft, identified by its position (x, y). Any aircraft can start moving to another coordinates (in straight line).
There is a single component that manages all this positioning and movement. When a aircraft wants to move, it send it a message in the form of (start_pos, speed, end_pos). How can I tell in the component, when one aircraft will move in the line of sight of another (each aircraft has this as a property as radius of sight) in order to notify it. Note that many aircrafts can be moving at the same time. Also, this algorithm is good to be effective sa it can handle ~1000 planes.
If there is some constraint, that is limiting your solution - it can probably be removed. The problem is not fixed.
Use a line to represent the flight path.
Convert each line to a rectangle embracing it. The width of the rectangle is determined by your definition of "close" (The bigger the safety distance is, the wider the rectangle should be).
For each new flight plan:
Check if the new rectangle intersects with another rectangle.
If so, calculate when will each plane reach the collision point. If the time difference is too small (and you should define too small according to the scenario), refuse the new flight plan.
If you want to deal with the temporal aspect (i.e. dealing with the fact that the aircraft move), then I think a potentially simplification is lifting the problem by the time dimension (adding one more dimension - hence, the original problem, being 2D, becomes a 3D problem).
Then, the problem becomes a matter of finding the point where a line intersects a (tilted) cylinder. Finding all possible intersections would then be n^2; not too sure if that is efficient enough.
See Wikipedia:Quadtree for a data structure that will make it easy to find which airplanes are close to a given airplane. It will save you from doing O(N^2) tests for closeness.
You have good answers, I'll comment only on one aspect and probably not correctly
you say that you aircrafts move in form (start_pos, speed, end_pos)
if all aircrafts have such, let's call them, flightplans then you should be able to calculate directly when and where they will be within certain distance from each other, or when will they be at closest point from each other or if the will collide/get too near
So, if they indeed move according to the flightplans and do not deviate from them your problem is deterministic - it boils down to solving a set of equations, which for ~1000 planes is not such a big task.
If you do need to solve these equations faster you can employ the techniques described in other answers
using efficient structures that can speedup calculating distances (quadtree, octree, kd-trees),
splitting the problem to solve the equations only for some relevant future timeslice
prioritize solving equations for pairs for which the distance changes most rapidly
Of course converting time to a third dimension turns the aircrafts from points into lines and you end up searching for the closest points between two 3d lines (here's some math)
I actually found an answer to this question.
It is in the book Real-Time Collision Detection, p. 223. It's better named, as well: Intersecting Moving Sphere Against Sphere, where a 2D sphere is a circle. It's not so simple (and I may also violate some rights) to explain it here, but the basic idea is to fix one of the circles as a point, adding its radius to the radius of the moving one. The new direction for the moving one is the sum of the two original vectors.

Is there an efficient algorithm to generate a 2D concave hull?

Having a set of (2D) points from a GIS file (a city map), I need to generate the polygon that defines the 'contour' for that map (its boundary). Its input parameters would be the points set and a 'maximum edge length'. It would then output the corresponding (probably non-convex) polygon.
The best solution I found so far was to generate the Delaunay triangles and then remove the external edges that are longer than the maximum edge length. After all the external edges are shorter than that, I simply remove the internal edges and get the polygon I want. The problem is, this is very time-consuming and I'm wondering if there's a better way.
One of the former students in our lab used some applicable techniques for his PhD thesis. I believe one of them is called "alpha shapes" and is referenced in the following paper:
http://www.cis.rit.edu/people/faculty/kerekes/pdfs/AIPR_2007_Gurram.pdf
That paper gives some further references you can follow.
This paper discusses the Efficient generation of simple polygons for characterizing the shape of a set of points in the plane and provides the algorithm. There's also a Java applet utilizing the same algorithm here.
The guys here claim to have developed a k nearest neighbors approach to determining the concave hull of a set of points which behaves "almost linearly on the number of points". Sadly their paper seems to be very well guarded and you'll have to ask them for it.
Here's a good set of references that includes the above and might lead you to find a better approach.
The answer may still be interesting for somebody else: One may apply a variation of the marching square algorithm, applied (1) within the concave hull, and (2) then on (e.g. 3) different scales that my depend on the average density of points. The scales need to be int multiples of each other, such you build a grid you can use for efficient sampling. This allows to quickly find empty samples=squares, samples that are completely within a "cluster/cloud" of points, and those, which are in between. The latter category then can be used to determine easily the poly-line that represents a part of the concave hull.
Everything is linear in this approach, no triangulation is needed, it does not use alpha shapes and it is different from the commercial/patented offering as described here ( http://www.concavehull.com/ )
A quick approximate solution (also useful for convex hulls) is to find the north and south bounds for each small element east-west.
Based on how much detail you want, create a fixed sized array of upper/lower bounds.
For each point calculate which E-W column it is in and then update the upper/lower bounds for that column. After you processed all the points you can interpolate the upper/lower points for those columns that missed.
It's also worth doing a quick check beforehand for very long thin shapes and deciding wether to bin NS or Ew.
A simple solution is to walk around the edge of the polygon. Given a current edge om the boundary connecting points P0 and P1, the next point on the boundary P2 will be the point with the smallest possible A, where
H01 = bearing from P0 to P1
H12 = bearing from P1 to P2
A = fmod( H12-H01+360, 360 )
|P2-P1| <= MaxEdgeLength
Then you set
P0 <- P1
P1 <- P2
and repeat until you get back where you started.
This is still O(N^2) so you'll want to sort your pointlist a little. You can limit the set of points you need to consider at each iteration if you sort points on, say, their bearing from the city's centroid.
Good question! I haven't tried this out at all, but my first shot would be this iterative method:
Create a set N ("not contained"), and add all points in your set to N.
Pick 3 points from N at random to form an initial polygon P. Remove them from N.
Use some point-in-polygon algorithm and look at points in N. For each point in N, if it is now contained by P, remove it from N. As soon as you find a point in N that is still not contained in P, continue to step 4. If N becomes empty, you're done.
Call the point you found A. Find the line in P closest to A, and add A in the middle of it.
Go back to step 3
I think it would work as long as it performs well enough — a good heuristic for your initial 3 points might help.
Good luck!
You can do it in QGIS with this plug in;
https://github.com/detlevn/QGIS-ConcaveHull-Plugin
Depending on how you need it to interact with your data, probably worth checking out how it was done here.
As a wildly adopted reference, PostGIS starts with a convexhull and then caves it in, you can see it here.
https://github.com/postgis/postgis/blob/380583da73227ca1a52da0e0b3413b92ae69af9d/postgis/postgis.sql.in#L5819
The Bing Maps V8 interactive SDK has a concave hull option within the advanced shape operations.
https://www.bing.com/mapspreview/sdkrelease/mapcontrol/isdk/advancedshapeoperations?toWww=1&redig=D53FACBB1A00423195C53D841EA0D14E#JS
Within ArcGIS 10.5.1, the 3D Analyst extension has a Minimum Bounding Volume tool with the geometry types of concave hull, sphere, envelope, or convex hull. It can be used at any license level.
There is a concave hull algorithm here: https://github.com/mapbox/concaveman

Resources