Suppose I've some points on a mesh (2+) that can be anywhere on the mesh, suppose for example these (ignore the small points, just consider the sphere):
http://i.stack.imgur.com/nDzW3.png
(sorry can't put directly the image)
But note that they can be everywhere
How can I get a closed ring of points that goes around the mesh and include the given points?
I have access to both neighbours and neighbouring faces for each point on the mesh.
Any idea?
I suppose that ring goes on existing mesh edges. Than mesh edges can be seen as a graph and problem is similar to Travelling salesman problem on given vertices.
TSP is hard (slow) to solve. I suppose that points positions approximate circle, than it is probably enough to use simpler algorithm. Start from one point and find closest of input points (Dijkstra's). Than start from that point and find closest of not visited points. Repeat that until path returns to starting point.
Related
I am working on an asteroids clone. Everything is 2D, and written in C++.
For the asteroids, I am generating random N-sided polygons. I have guaranteed that they are Convex. I then rotate them, give them a rotspeed, and have them fly through space. It all works, and is very pretty.
For collision, I'm using an Algorithm I thought of myself. This is probably a bad idea, and if push comes to shove, I'll probably scrap the whole thing and find a tutorial on the internet.
I've written and implemented everything, and the collision detection works alright.... most of the time. It will randomly fail when there's obviously a collision on screen, and sometimes indicate collision when nothing is touching. Either I have flubbed my implementation somewhere, or my algorithm is horrible. Due to the size/scope of my implementation (over several source files) I didn't want to bother you with that, and just wanted someone to check that my algorithm is, in fact, sound. At that point I can go on a big bug hunt.
Algorithm:
For each Asteroid, I have a function that outputs where each vertex should be when drawing the asteroid. For each pair of adjacent Vertices, I generate the Formula for the line that they sit on, y=mx+b format. I then start with one of my ships vertices, testing that point to see whether it is inside the asteroid. I start by plugging in the X coordinate of the point, and comparing the output to the Actual Y value. This tells me if the point is above or below the line. I then do the same with the Center of the Asteroid, to determine which half of the line is considered "Inside" the asteroid. I then repeat for each pair of Vertices. IF I ever find a line for which my point is not on the same side as the center of the asteroid, I know there is no collision, and exit detection for that point. Since there are 3 points on my ship, I then have to test for the next point. If all 3 points exit early, then There are no collisions for any of the points on the ship, and we're done. If any point is bound on all sides by the lines made up by the asteroid, then it is inside the asteroid, and the collision flag is set.
The two Issues I've discovered with this algorithm is that:
it doesn't work on concave polygons, and
It has problems with an Edge case where the Slope is Undefined.
I have made sure all polygons are Convex, and have written code to handle the Undefined Slope issue (doubles SHOULD return NAN if we divide by 0, so it's pretty easy to test for that).
So, should this work?
The standard solution to this problem is using the separating axis theorem (SAT). Given two convex polygons, A and B, the algorithm basically goes like this:
for each normal N of the edges of A and B
intervalA = [min, max] of projecting A on N
intervalB = [min, max] of projecting B on N
if intervalA doesn't overlap intervalB
return did not collide
return collided
I did something similar to compute polygon intersections, namely finding if a vertex sits within a given polygon.
Your algorithm is sound, and indeed does not work for concave polys. The line representation you chose is also problematic at slopes approaching infinity. I chose to use a couple of vectors for mine, one for the line direction, and one for a reference point on the line. From these, I can easily derive a parameterized equation of the line, and use that in various ways to find intersections with other shapes.
P = S + t * D
Any point P of the line can be caracterized by its coordinate t on the the line, given the above relation, where S is the reference point, and D the direction vector.
This representation lets you easily define which parts of the plane is the positive and the negative one (ie. above and below the line), thanks to the direction orientation. Now, any region of the plane can be defined as an intersection of several lines' negative or positive subplanes. So your "point within polygon" algorithm could be slightly changed to use that representation, with the added constraint of all the direction pointing clockwise, and testing for the point being in the negative subplane of all the lines (so you don't need the centre of the polygon anymore).
The formula to compute the side of a point wrt a line I used is the following:
(xs - xp) * yd - (ys - yp) * xd
The slope issue appears here when point P is close to S.
That representation can be computed using the edge vertices, but in order to have correct subplanes, you must keep your vertices in your polygon in condecutive orders.
For concave polygons, the problem is a bit more complicated: briefly, you have to test that the point is between two consecutive convex edges. This can be achieved by checking the coordinate of the point on the edge when projected on it, and ensuring it stands between 0 and length(edge) (assuming that the direction is normalized). Note that it boils down to check if the point belongs to a triangle within the polygon.
I have two concave polygons on input represented as two vectors of points. I want to do some polygon operation on it - union, intersection and difference. I found intersection points between these polygons and insert them into the right place in each polygon. Then I give an information about its position (Inner - it is inside the other polygon, Outer - it is outside the other polygon, Intersection - point, where two edges of polygons intersects) to each vertex. Now I know which points create the union of these polygons (Outer and Intersection) etc., but I need to know how to sort them to the right order. In case of the intersection operation I need to divide these sorted points into the right number of sets, because the result of intersection could be more than one polygon.
I am using C++, but I don't need necessarily the code, I only want to need how to sort these final polygon points. And I don't want to use any library for these operations because I already have my own functions and want to use them.
I looked at this question How to intersect two polygons? and also some others but none of them is solving final sorting of points.
I also read this article http://www.gvu.gatech.edu/~jarek/graphics/papers/04PolygonBooleansMargalit.pdf , but I probably don't get it.
Any help would be appreciated.
If you follow all my recommendations from my comments:
Distinguish between intersection and touching points
Keep a link between the two equivalents of the intersection points in the two polygons
The solution for the union will be:
Consider only outer, touching and intersection points
Make sure the points in the two polygons are ordered in different direction (one of the sets is in clockwise direction, the other one in counter-clockwise)
Start from random point in any of the two polygons.
For every vertex in any of the two polygons keep if you have visited it
Every time you encounter an intersection point keep on traversing from the next to follow point in the other polygon after the equivalent of the intersection point.
If you come back to the point you started from this closes one of the components of the join of the two polygons. If not all vertices were traversed repeat the whole of it from any unvisited vertex.
In the end calculate the area of all the polygons you have found. The largest in area will be the real union. The rest will be holes in the union.
The solution for the join will be:
Consider only inner and intersection points
Make sure the points in the two polygons are ordered in the same direction
Start from random point in any of the two polygons.
For every vertex in any of the two polygons keep if you have visited it
Every time you encounter an intersection point keep on traversing from the next to follow point in the other polygon after the equivalent of the intersection point.
If you come back to the point you started from this closes one of the components of the join of the two polygons. If not all vertices were traversed repeat the whole of it from any unvisited vertex.
EDIT: As I already mentioned, I have the god feeling my approach with the polygon orientation needs to be revised. However, when searching through the web I found a description of algorithm that might do the work for you: The Vatti clipping algorithm
EDIT2 One more article describing such clipping algorithm.
Im trying to define if a point is inside a polygon. Only the coordinates of the corners are given. After some research I found the Ray casting algorithm but it looks like i need a vector filled with the coordinates of the polygons side. I tried to calculate these coordinates as well, but it doesn't look like this is the solution.
Maybe I'm interpreting the algorithm wrong so it would be nice if someone could push me into the right direction.
I am assuming you are trying to do this for any kind of polygon.
Check this out to get a handle on the techniques for solving complicated polygons. This is actually what you probably want and it is the ray casting algorithm you mentioned before.
http://alienryderflex.com/polygon/
A short explanation of that is you have a polygon, you know its points. Construct connections between the points (vectors). Cast a ray across the entire polygon through the point you are trying to test.
At each intersection of the ray with one of the polygon vectors increment a counter by 1 starting from 0. If you intersect the point and that counter is even it is not in the polygon. If the counter is odd then that point is inside the polygon.
I have a set of non-overlapping polygons. These polygons can share nodes, edges, but strictly no overlapping.
Now, I am going to mesh them using Constrainted Delaunay Triangulation (CDT) technique. I can get the mesh without problem.
My problem is, after the mesh, I want to know which mesh element belongs to which original polygon. MY current approach is to compute the centroid for each mesh element, and check which of the original polygon this centroid falls into. But I don't like this approach as it is very computationally intensive.
Is there any efficient ways to do this ( in terms of Big O the runtime)? My projects involve tens of thousands of polygons and I don't want the speed to slow down.
Edit: Make sure that all the vertices in a mesh element share a common face is not going to work, because there are cases where the all the vertices can have more than one common face, as below ( the dotted line forms a mesh element whose vertices have 2 common faces):
I can think of two options, both somehow mentioned :
Maintain the information in your points/vertices. See this other related question.
Recompute the information the way you did, locating each mesh element centroid in the original polygon, but this can be optimized by using a spatial_sort, and locating them sequentially in your input polygon (using the previous result as hint for starting the next point location).
What about labeling each of your original vertices with a polygon id (or several, I guess, since polys can share vertices). Then, if I understand DT correctly, you can look at the three verts in a given triangle in the mesh and see if they share a common label, if so, that mesh came from the labeled polygon.
As Mikeb says label all your original vertices with a polygon id.
Since you want the one that's inside the polygon, just make sure you only go clockwise around the polygons, this makes sure that if the points overlap for two polygons you get the one facing the correct direction.
I would expect this approach to remain close to O(n) where n represents number of points as each triangle can at only have one or two polygons that overlap all three points.
Create a new graph G(V,E) in the following way. For every mesh create a node in V. For every dashed edge create an edge in E that connects the two corresponding meshes. Don't map solid edges into edges in E.
Run ConnectedComponents(G).
Every mesh will be labeled with a label (with 1-to-1 correspondence to polygons.)
Maybe you can call CDT separately for each polygon, and label the triangles with their polygon after each call.
Hey so i was told in a previous answer that to make concave shapes out of multiple convex ones i do the following:
If you don't have a convex hull, perform a package wrapping algorithm
to get a convex border that encompasses all your points (again quite
fast). en.wikipedia.org/wiki/Gift_wrapping_algorithm
Choose a point that is on the boarder as a starter point for the algorithm.
Now, itterate through the following points that are on your shape,
but aren't on the convex border.
When one is found, create a new shape with the vertices from
the starter point to the found non-border point.
Finally set the starter point to be the the found off-border point
Recursion is now your friend: do the exact same process on each new
sub-shape you make.
I'm confused on one thing though. What do you do when two vertices in a row are off-border? After reaching the first one you connect the starter point to it, but then you immediatly run into another off-border point after you start itterating again, leaving you with only 2 vertices to work with: the starter point and new off-border point. What am i missing?
To illustrate my problem, here's a shape pertaining to this issue: It would be great if someone could draw all over it and walk through the steps of the algorithm using this. And using point 1 as the starting point.
Thanks!
Assuming you really want to take a convex polygon (as you've illustrated) and decompose it into convex parts without introducing new vertices, the usual approach is called "ear clipping" and is described in this Wikipedia article, Polygon triangulation. In this approach the convex pieces are triangles, which are necessarily convex.
This problem has been discussed in connection with the CGAL computational geometry software here in Stackoverflow, C++ 2D tessellation library.