So I'll try to describe the problem in detail, and I'd like some critique on the validity and performance of the process I use to solve it. My main concern is the validity, which I cannot seem to prove.
The idea is that we have a 2D polygon in 3D space (which is described by all its hull points. Each point also has a normalvector which indicates an infinite extrusion. I apologize for using the misleading term 'normal', it's just a normalized vector that represents a normal in a broader context not relevant to this algorithm. To completely clarify, these vectors are neither perpendicular to the plane nor the same on each point. As can be seen in the following image, where the vectors are the red lines:
This means that the sides of this extrusion do not form a flat, but a skewed plane. One can look at its extrusion sides like a Skew polygon (http://en.wikipedia.org/wiki/Skew_polygon).
Anyway, I'd like to see if a point P is inside the extrusion or not. My current procedure is as follows:
Calculate normal N=(A-B)x(B-C) where A,B,C are any three clock-wise points on the 2D polygon. This gives me the 2D polygon plane normal.
Calculate the final plane variable D to get NxX+NyY+Nz*Z+D = 0. Do this by filling in point P in X,Y,Z. This gives the extruded plane.
Extrude the normals at all hull points to get the new hull on the extruded plane. Simply done by finding the intersection of the line they define and the plane.
Here comes the tricky part. Now I have a convex hull on a 3D plane where I know the point is coplanar. I have seen a lot of solutions already on stackoverflow concerning solving linear systems, etc... but they either do not consider 3D, lack a good implementation or look too expensive.
My approach is using an assumption that I think is both necessary and sufficient but I cannot prove that last part (the necessary part is obvious). I make the following claim:
For coplanar convex hull consisting of points A->Z and an additional coplanar point P. Then P is within the convex hull if and only if for all clock-wise sequential points A and B and some other third sequential point C the line C-P passes through P before passing through the line A-B.
In the example image above: A'-B' is crossed by D'-P going through P before A'-B', for B'-C' this is achieved by A', for C'-D' also by A' and for D'-A' by B'.
I implement this idea as two 3D parametric lines crossing eachother (A-B and P-C) and looking at the parameter's sign. The parameter in P-C should be non-positive because the crossing point should lie behind P for a parameter going to C.
In essence this would result in a O(n)O(n^2) algorithm with n being the #points of the polygon (which seems to beat all solutions I've seen so far). However, even though I cannot find a counterexample to the above assumption, I also cannot prove it.
Edit: I believe it is possible to prove that a sufficient condition is that for A and B, all other hull points need to satisfy the assumption (and not just C).
Edit2: Clarified claim.
Related
I'm looking for an algorithm that provides what I call a "shrunken convex hull" (as distinct from a "reduced convex hull") in 3D. I am defining the shrunken hull, H', as the volume of space that has, no less than D distance from some original convex hull, H.
Analytically, this can be formed by moving each plane of H inwards along its normal by D, then computing the convex hull (if it exists) of the resultant planes. The tricky bit is some planes might be trimmed or dropped, others may move past other planes, and get entirely "snipped" out due to normal reversal (if D is big enough). I’m a bit fuzzy on how to do the algorithm, but have some badly thought out ideas below.
I am doing this to to identify the subset of points in a dataset which are guaranteed to be no less than a given distance from the surface of the original point set (which is assumed to be convex, and I have this). This is to remove surface effects that are disrupting our signal in some calculations we are doing.
I'm really looking for a name, or examples of anyone doing this, or another way to compute this. Ideally some good-old open code would be great, but I think my problem is far too niche.
I found reduced convex hulls, but this seems to be a different idea. The current closest thing I can find is "Hausdorff Cores" - however this seems like the more complicated case of non-convex polygons, and is pretty damned dense.
Do not read beyond here, unless you really really want to.
Current, incomplete/badly thought out algorithm
The slow way (i.e. current way) of identifying the reduced point set it is to compute the signed distance for all points, and reject those that are less than a given distance. However, this is pretty damned slow, as the number of points can be up to 100M. I think operating on the original hull to generate the shrunken hull, and computing its AABB and spherical BB, then retaining only those inside the shrunken hull might be much faster (I hope -willing to accept comments saying this is stupid).
I think it should be possible, as I don't strictly need the full distance information for each point, just D_point > D. So once I know this I should be able to stop.
I can see how the shrunken hull might be done in 2D, where you look at each vertex, then use an analytical solution to a constant velocity Eikonal, then move the vertex along the vector derived from each corner.
However, the situation is more complex for the 3D version, afaics, as there are multiple facets (>2) for each vertex . My current plan is to look at each edge pair individually, then work from there to (somehow - create half spaces and union them?) to build this hull.
What your thinking of is downscaling the 3D convex hull, it works just like downscaling a 2D image, except for how the angle
Outline for the algorithm (in 2D) looks something like this:
1. Compute the convex hull.
2. For each point, P, in the convex hull:
3. Find the hull points before and after, P
4. Bisect the angle formed to obtain the angle, A, required.
5. Create a new point, P', along the angle A at a distance, D, from `P`.
7. Add P' to the scaled-down (shrunken) convex hull.
The only difference in 3D occurs in lines 3 and 4. In 3D, step 3 obtains 3 points. In step 4, a 3D angle is used. Thus you'll find a fair bit of benefit in using the 3D transforms in a graphics/geometry libary, as the math may be tricky.
If your objective is to remove surface effects, and it's not important that every surface of the convex hull be displaced by the same distance, you could instead
Identify a point known to be inside the hull (e.g. the centroid of the point cloud or the hull)
Scale the hull inward towards that point
Unless you scale infinitely (collapsing everything to a point), this operation should give an inwardly-displaced hull which has the same connectivity - no points added or removed.
I have a set of (x, y) points and I would like to interpolate from those points the value of any points "inside" this set of point. (The yellow area in the picture bellow).
The problem is that I have not find any good way to:
Find the polygon which would be the boundary of my interpolated points (green line)
Test if the point is inside the polygon or not. I found the Point in Polygon algorithm but I'm not sure that taking all the point in a certain range and testing if they belong in the polygone is a good idea. I would like to find a way that let me test a fewer number of points than (max(x)-min(x))*(max(y)-min(y)), ideally a way to know on which points to do my iteration.
Edit: In the 2nd part I'm iterating on all the points (pixels) in the image, what I'd like to do is only iterate on the points in the yellow field.
Do you have any lead?
Ps: I'm coding in C++ if it's of any help.
The green line that you're looking at is called the convex hull of the set of points and there are many good, efficient algorithms for computing it. The best of them run in time O(n log h), where h is the number of points found on the hull and n is the total number of points. As a totally shameless self-promotion, I have a C++ implementation of one of these algorithms available on my personal site.
As to your second question - once you have the convex hull, it's very easy to determine which points are purely inside the polygon as opposed to on the hull. Just make a hash table of all the points, then iterate over the convex hull and remove all points contained in the hull. What remains in the hash table is the set of points contained within the polygon but not on the boundary.
Hope this helps!
Suppose random points P1 to P20 scattered in a plane.
Then is there any way to sort those points in either clock-wise or anti-clock wise.
Here we can’t use degree because you can see from the image many points can have same degree.
E.g, here P4,P5 and P13 acquire the same degree.
If your picture has realistic distance between the points, you might get by with just choosing a point at random, say P1, and then always picking the nearest unvisited neighbour as your next point. Traveling Salesman, kind of.
Are you saying you want an ordered result P1, P2, ... P13?
If that's the case, you need to find the convex hull of the points. Walking around the circumference of the hull will then give you the order of the points that you need.
In a practical sense, have a look at OpenCV's documentation -- calling convexHull with clockwise=true gives you a vector of points in the order that you want. The link is for C++, but there are C and Python APIs there as well. Other packages like Matlab should have a similar function, as this is a common geometrical problem to solve.
EDIT
Once you get your convex hull, you could iteratively collapse it from the outside to get the remaining points. Your iterations would stop when there are no more pixels left inside the hull. You would have to set up your collapse function such that closer points are included first, i.e. such that you get:
and not:
In both diagrams, green is the original convex hull, the other colors are collapsed areas.
Find the right-most of those points (in O(n)) and sort by the angle relative to that point (O(nlog(n))).
It's the first step of graham's convex-hull algorithm, so it's a very common procedure.
Edit: Actually, it's just not possible, since the polygonal representation (i.e. the output-order) of your points is ambiguous. The algorithm above will only work for convex polygons, but it can be extended to work for star-shaped polygons too (you need to pick a different "reference-point").
You need to define the order you actually want more precisely.
I need to compute the area of the region of overlap between two triangles in the 2D plane. Oddly, I have written up code for the triangle-circle problem, and that works quite well and robustly, but I have trouble with the triangle-triangle problem.
I already first check to see if one entirely contains the other, or if the other contains the first, as well as obtain all the edge-wise intersection points. These intersection points (up to 6, as in the star of David), combined with the triangle vertices that are contained within the other triangle, are the vertices of the intersection region. These points must form a convex polygon.
The solution I seek is the answer to either of these questions:
Given a set of points known to all lie on the convex hull of the point set, compute the area of the convex hull. Note that they are in random order.
Given a set of half-planes, determine the intersecting area. This is equivalent to describing both triangles as the intersection of three half-planes, and computing the solution as the direct intersection of this description.
I have considered for question 1 simply adding up all areas of all possible triangles, and then dividing by the multiplicity in counting, but that seems dumb, and I'm not sure if it is correct. I feel like there is some kind of sweep-line algorithm that would do the trick. However, the solution must also be relatively numerically robust.
I simply have no idea how to solve question 2, but a general answer would be very useful, and providing code would make my day. This would allow for direct computation of intersection areas of convex polygons instead of having to perform a triangle decomposition on them.
Edit: I am aware of this article which describes the general case for finding the intersection polygon of two convex polygons. It seems rather involved for just triangles, and furthermore, I don't really need the resulting polygon itself. So maybe this question is just asked in laziness at this point.
Question 1: why are the points in a random order? If they are, you have to order them so that connecting consecutive points with straight lines yields a convex polygon. How to order them -- for example, by running a convex hull algorithm (though there are probably also simpler methods). Once you have ordered them, compute the area as described here.
--
Question 2 is simpler. Half-plane is defined by a single line having an implicit equation a*x+b*y+c=0 ; all points (x, y) for which a*x+b*y+c <= 0 (note the inequality) are "behind" the half-plane. Now, you need at least three planes so that the intersection of their negative half-spaces is closed (this is necessary, but not sufficient condition). If the intersection is closed, it will be a convex polygon.
I suggest that you maintain a linked list of vertices. The algorithm is initialized with THREE lines. Compute the three points (in general case) where the lines intersect; these are the starting vertices of your region (triangle). You must also check that each vertex is "behind" the half-plane defined by the line going through the other two vertices; this guarantees that the intersection actually IS a closed region.
These three vertices define also the the three edges of a triangle. When you intersect by a new half-plane, simply check for the intersection between the line defining the half-plane and each of the edges of the current region; in general you will get two intersection points, but you must watch out for degenerate cases where the line goes through a vertex of the region. (You can also end up with an empty set!)
The new intersection vertices define a line that splits the current region in TWO regions. Again, use orientation of the new half-plane to decide which of the two new regions to assign to the new "current region", and which one to discard.
The points in the list defining the edges of the current region will be correctly ordered so you can apply the formula in the above link to compute its area.
If this description is not detailed/understandable, the next-best advice I can give you is that you invest in a book on computational geometry and linear algebra.
I am programming an algorithm where I have broken up the surface of a sphere into grid points (for simplicity I have the grid lines parallel and perpendicular to the meridians). Given a point A, I would like to be able to efficiently take any grid "square" and determine the point B in the square with the least spherical coordinate distance AB. In the degenerate case the "squares" are actually "triangles".
I am actually only using it to bound which squares I am searching, so I can also accept a lower bound if it is only a tiny bit off. For this reason, I need the algorithm to be extremely quick otherwise it would be better to just take the loss of accuracy and search a few more squares.
I decided to repost this question to Math Overflow: https://mathoverflow.net/questions/854/closest-grid-square-to-a-point-in-spherical-coordinates. More progress has been made here
For points on a sphere, the points closest in the full 3D space will also be closest when measured along the surface of the sphere. The actual distances will be different, but if you're just after the closest point it's probably easiest to minimize the 3D distance rather than worry about great circle arcs, etc.
To find the actual great-circle distance between two (latitidude, longitude) points on the sphere, you can use the first formula in this link.
A few points, for clarity.
Unless you specifically wish these squares to be square (and hence to not fit exactly in this parallel and perpendicular layout with regards to the meridians), these are not exactly squares. This is particularly visible if the dimensions of the square are big.
The question speaks of a [perfect] sphere. Matters would be somewhat different if we were considering the Earth (or other planets) with its flattened poles.
Following is a "algorithm" that would fit the bill, I doubt it is optimal, but could offer a good basis. EDIT: see Tom10's suggestion to work with the plain 3D distance between the points rather than the corresponding great cirle distance (i.e. that of the cord rather than the arc), as this will greatly reduce the complexity of the formulas.
Problem layout: (A, B and Sq as defined in the OP's question)
A : a given point the the surface of the sphere
Sq : a given "square" from the grid
B : solution to problem : point located within Sq which has the shortest
distance to A.
C : point at the center of Sq
Tentative algorithm:
Using the formulas associated with [Great Circle][1], we can:
- find the equation of the circle that includes A and C
- find the distance between A and C. See the [formula here][2] (kindly lifted
from Tom10's reply).
- find the intersect of the Great Circle arc between these points, with the
arcs of parallel or meridian defining the Sq.
There should be only one such point, unless this finds a "corner" of Sq,
or -a rarer case- if the two points are on the same diameter (see
'antipodes' below).
Then comes the more algorithmic part of this procedure (so far formulas...):
- find, by dichotomy, the point on Sq's arc/seqment which is the closest from
point A. We're at B! QED.
Optimization:
It is probably possible make a good "guess" as to the location
of B, based on the relative position of A and C, hence cutting the number of
iterations for the binary search.
Also, if the distance A and C is past a certain threshold the intersection
of the cicles' arcs is probably a good enough estimate of B. Only when A
and C are relatively close will B be found a bit further on the median or
parallel arc in these cases, projection errors between A and C (or B) are
smaller and it may be ok to work with orthogonal coordinates and their
simpler formulas.
Another approach is to calculate the distance between A and each of the 4
corners of the square and to work the dichotomic search from two of these
points (not quite sure which; could be on the meridian or parallel...)
( * ) *Antipodes case*: When points A and C happen to be diametrically
opposite to one another, all great circle lines between A and C have the same
length, that of 1/2 the circonference of the sphere, which is the maximum any
two points on the surface of a sphere may be. In this case, the point B will
be the "square"'s corner that is the furthest from C.
I hope this helps...
The lazy lower bound method is to find the distance to the center of the square, then subtract the half diagonal distance and bound using the triangle inequality. Given these aren't real squares, there will actually be two diagonal distances - we will use the greater. I suppose that it will be reasonably accurate as well.
See Math Overflow: https://mathoverflow.net/questions/854/closest-grid-square-to-a-point-in-spherical-coordinates for an exact solution