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.
Related
I have a set of 3d points that lie in a plane. Somewhere on the plane, there will be a hole (which is represented by the lack of points), as in this picture:
I am trying to find the contour of this hole. Other solutions out there involve finding convex/concave hulls but those apply to the outer boundaries, rather than an inner one.
Is there an algorithm that does this?
If you know the plane (which you could determine by PCA), you can project all points into this plane and continue with the 2D coordinates. Thus, your problem reduces to finding boundary points in a 2D data set.
Your data looks as if it might be uniformly sampled (independently per axis). Then, a very simple check might be sufficient: Calculate the centroid of the - let's say 30 - nearest neighbors of a point. If the centroid is very far away from the original point, you are very likely on a boundary.
A second approach might be recording the directions in which you have neighbors. I.e. keep something like a bit field for the discretized directions (e.g. angles in 10° steps, which will give you 36 entries). Then, for every neighbor, calculate its direction and mark that direction, including a few of the adjacent directions, as occupied. E.g. if your neighbor is in the direction of 27.4°, you could mark the direction bits 1, 2, and 3 as occupied. This additional surrounding space will influence how fine-grained the result will be. You might also want to make it depend on the distance of the neighbor (i.e. treat the neighbors as circles and find the angular range that is spanned by the circle). Finally, check if all directions are occupied. If not, you are on a boundary.
Alpha shapes can give you both the inner and outer boundaries.
convert to 2D by projecting the points onto your plane
see related QA dealing with this:
C++ plane interpolation from a set of points
find holes in 2D point set
simply apply this related QA:
Finding holes in 2d point sets?
project found holes back to 3D
again see the link in #1
Sorry for almost link only answer but booth links are here on SO/SE and deals exactly with your issue when combined. I was struggling first to flag your question as duplicate and leave this in a comment but this is more readable.
I have a convex triangulated mesh. I am able to numerically calculate geodesics between points on the surface; however, I am having trouble tackling the following problem:
Imagine a net being placed over the mesh. The outside boundary of the net coincides with the boundary of the mesh, but the nodes of the net corresponding to the interior of the net are allowed to move freely. I'm interested in finding the configuration that would have the least stress (I know the distances for the at rest state of the net).
Doing this on a smooth surface is simple enough as I could solve for the stresses in terms of the positions of the nodes of the net; however, I don't see a way of calculating the stresses in terms of the position of the net nodes because I don't know that a formula exists for geodesics on a convex triangulated surface.
I'm hoping there is an alternative method to solving this such as a fixed point argument.
Hint:
If I am right, as long as a node remains inside a face, the equations are linear (just as if the node was on a plane). Assuming some node/face correspondence, you can solve for the equilibrium, as if the nodes did belong to the respective planes of support, unconstrained by the face boundaries.
Then for the nodes which are found to lie outside the face, you can project them on the surface and obtain a better face assignment. Hopefully this process might converge to a stable solution.
The picture shows a solution after a first tentative node/face assignment, then a second one after projection/reassignment.
On second thoughts, the problem is even harder as the computation involves geodesic distances between the nodes, which depend on the faces that are traversed. So the domain in which linearity holds when moving a single node is even smaller than a face, it is also limited by "wedges" emanating from the lined nodes and containing no other vertex.
Then you may have to compute the domains where the geodesic distances to a linked neighbor is a linear function of the coordinates and project onto this partition of the surface. Looks like an endeavor.
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.
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.
I have a collection of 2D coordinate sets (on the scale of a 100K-500K points in each set) and I am looking for the most efficient way to measure the similarity of 1 set to the other. I know of the usuals: Cosine, Jaccard/Tanimoto, etc. However I am hoping for some suggestions on any fast/efficient ones to measure similarity, especially ones that can cluster by similarity.
Edit 1: The image shows what I need to do. I need to cluster all the reds, blues and greens by their shape/orientatoin, etc.
alt text http://img402.imageshack.us/img402/8121/curves.png
It seems that the first step of any solution is going to be to find the centroid, or other reference point, of each shape, so that they can be compared regardless of absolute position.
One algorithm that comes to mind would be to start at the point nearest the centroid and walk to its nearest neighbors. Compare the offsets of those neighbors (from the centroid) between the sets being compared. Keep walking to the next-nearest neighbors of the centroid, or the nearest not-already-compared neighbors of the ones previously compared, and keep track of the aggregate difference (perhaps RMS?) between the two shapes. Also, at each step of this process calculate the rotational offset that would bring the two shapes into closest alignment [and whether mirroring affects it as well?]. When you are finished you will have three values for every pair of sets, including their direct similarity, their relative rotational offset (mostly only useful if they are close matches after rotation), and their similarity after rotation.
Try K-means algorithm. It dynamically calculated the centroid of each cluster and calculates distance to all the pointers and associates them to the nearest cluster.
Since your clustering is based on a nearness-to-shape metric, perhaps you need some form of connected component labeling. UNION-FIND can give you a fast basic set primitive.
For union-only, start every point in a different set, and merge them if they meet some criterion of nearness, influenced by local colinearity since that seems important to you. Then keep merging until you pass some over-threshold condition for how difficult your merge is. If you treat it like line-growing (only join things at their ends) then some data structures become simpler. Are all your clusters open lines and curves? No closed curves, like circles?
The crossing lines are trickier to get right, you either have to find some way merge then split, or you set your merge criteria to extremely favor colinearity and you luck out on the crossing lines.