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.
Related
I have a Polygon object and I'm looking for an efficient way to find any point strictly inside it (not on its boundary). What is the best way to do so?
I had the following ideas, which I don't really like:
Triangulating the polygon and reporting a point on one of the triangulation edges (too expensive).
Checking the polygon's winding direction and reporting a point located in an epsilon-distance from one of the polygon's edges (doesn't work in edge-cases).
Given a polygon, you can find the first two points where the polygon crosses a line parallel to x axis and lies between the yMin & yMax of your polygon (0 & 1 in the image below).
Any point between these points will be inside your polygon. The basic idea comes from scan converting a polygon —i.e. these are the points you would fill. The part of the line after the second point has a winding of 0 or 2, depending on your polygon.
The first two crossings (or last) has to be taken, as the crossing points are sorted along the x-axis.
Some corner cases:
If you omit all points of the polygon which just touches the line, in some cases this can fail (image below).
If there are overlapping lines in your polygon, you have to resolve those.
To avoid the first issue, make sure to take the first point as a definite crossing and the next one can be either a crossing or a point where polygon just touches the line.
This can be easily implemented without using any special functions in most languages. Since I am not familiar with Boost methods, I am posting a sketch of the basic idea in javascript.
The drawing is done using paper.js —although, the code for the algorithm outlined here itself is self contained.
You can translate this to C++ as long as you can enumerate through all points in a Boost::polygon
Here is the demo.
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.
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.
I have various point clouds defining RT-STRUCTs called ROI from DICOM files. DICOM files are formed by tomographic scanners. Each ROI is formed by point cloud and it represents some 3D object.
The goal is to get 2D curve which is formed by plane, cutting ROI's cloud point. The problem is that I can't just use points which were intersected by plane. What I probably need is to intersect 3D concave hull with some plane and get resulting intersection contour.
Is there any libraries which have already implemented these operations? I've found PCL library and probably it should be able to solve my problem, but I can't figure out how to achieve it with PCL. In addition I can use Matlab as well - we use it through its runtime from C++.
Has anyone stumbled with this problem already?
P.S. As I've mentioned above, I need to use a solution from my C++ code - so it should be some library or matlab solution which I'll use through Matlab Runtime.
P.P.S. Accuracy in such kind of calculations is really important - it will be used in a medical software intended for work with brain tumors, so you can imagine consequences of an error (:
You first need to form a surface from the point set.
If it's possible to pick a 2d direction for the points (ie they form a convexhull in one view) you can use a simple 2D Delaunay triangluation in those 2 coordinates.
otherwise you need a full 3D surfacing function (marching cubes or Poisson)
Then once you have the triangles it's simple to calculate the contour line that a plane cuts them.
See links in Mesh generation from points with x, y and z coordinates
Perhaps you could just discard the points that are far from the plane and project the remaining ones onto the plane. You'll still need to reconstruct the curve in the plane but there are several good methods for that. See for instance http://www.cse.ohio-state.edu/~tamaldey/curverecon.htm and http://valis.cs.uiuc.edu/~sariel/research/CG/applets/Crust/Crust.html.