Most of the times, I determine contour orientation generating 2D points and computing the closed polygon area. Depending on the area value sign I can understand if the contour is oriented clockwise or not (see How to determine if a list of polygon points are in clockwise order?).
Would it be possible to do the same computations without generating 2D points? I mean, relying only on geometric curve properties?
We are interested in determining the orientation of contours like these ones without sampling them with 2D points.
EDIT: Some interesting solutions can be found here:
https://math.stackexchange.com/questions/423718/general-way-to-find-out-whether-a-curve-is-positively-oriented
Scientific paper: Determining the orientation of closed planar curves, DJ Filip (1990)
How are those geometric curves defined?
Do you have an angle for them? The radius doesn't matter, only the difference between entry-angle and exit-angle of each curve.
In that case, a trivial idea crossing my mind is to just sum up all the angles. If the result is positive, you know you had more curves towards the right meaning it's a clockwise contour. If it was negative, then more curves were leftwards -> anti-clockwise contour. (assuming that positive angels determine a right-curve and vica versa)
After thinking about this for awhile, for polygons that contain arcs I think there are three ways to do this.
One, is to break the arcs into line segments and then use the area formula as described above. The success of this approach seems to be tied to how close the interpolation of the arcs is as this could cause the polygon to intersect itself.
A quicker way than the above would be to do the interpolation of the arcs and then find a vertex in the corner (minimal Y, if tie minimal X) and use the sign of the cross product for that vertex. Positive CCW, negative CW. Again, this is still tied to the accuracy of the interpolation.
I think a better approach would be to find the midpoint of the arc and create two line segments, one from the beginning of the arc to the midpoint and another from the midpoint to the end of the arc and replace the arc with these line segments. Now you have a polygon with only line segments. Then you can add up all the normalized cross products of all the vertices. The sign will tell you the direction. Positive is counter-clockwise, negative is clockwise. In this case it doesn't matter if the polygon self-intersects.
Shown Figure (1) is a typical Delaunay triangulation (blue) and it has a boundary line (black rectangle).
Each vertex in the Delaunay triangulation has a height value. So I can calculate the height inside convex hull. I am figuring out a method to calculate the height up to the boundary line (some sort of extrapolation).
There are two things associated with this task
Triangulate up to the boundary point
Figuring out the height at newly created triangle vertices
Anybody come across this issue?
Figure 1:
I'd project the convex hull points of the triangulation to the visible box segments and then insert the 4 box corners and the projected points into the triangulation.
There is no unique correct way to assign heights to the new points. One easy and stable method would be to assign to each new point the height of the closest visible convex hull vertex. Be careful with extrapolation: Triangles of the convex hull tend to have unstable slopes, see the large triangles in front of the below terrain image. Their projection to the xy plane has almost 0 area but due to the height difference they are large and almost 90 degrees to the xy plane.
I've had some luck with the following approach:
Find the segment on the convex hull that is closet to the extrapolation point
If I can drop a perpendicular onto the segment, interpolate between the two vertices of the segment.
If I can not construct the perpendicular, just use the closest vertex
This approach results in a continuous surface, but does not provide 1st derivative continuity.
You can find some code that might be helpful at TriangularFacetInterpolator.java. Look for the interpolateWithExteriorSupport method.
I am working on image segmentation and I thought the convex hull can provide me with a simple solution to my problem. Currently I have polygons with for sides (see image below). Due to image processing issues, the shape does not have clean straight sides and hence when I use the standard convex hull (in Matlab) I may get more than the four main corners to define it.
My goal is to force the convex hull algorithm to find the best 4 vertices that will enclose my polygons (i.e. 4 best enclosing vertices per polygon). Is this possible? An example code will be appreciated.
Thanks
The problem of the minimum area bounding polygon is briefly mentioned in "Geometric applications of a matrix-searching algorithm" (see Applications section). It is not simple and is probably not the way for you.
For an easier (but approximate) answer to your question, you can consider the four cardinal directions and find the farthest points in these, which define a quadrilateral. (Also consider the four intermediate directions, which are more appropriate for an axis-aligned rectangle.)
If you insist having an enclosing quadrilateral, you can translate the four edges to the farthest points in the respective perpendicular directions, and find the pairwise intersections.
If you insist having a rectangle, compute the convex hull and find the minimum area or minimum perimeter bounding rectangle by the Rotating Calipers method. https://geidav.wordpress.com/tag/rotating-calipers/
The picture below shows a triangular surface mesh. Its vertices are exactly on the surface of the original 3D object but the straight edges and faces have of course some geometric error where the original surface bends and I need some algorithm to estimate the smooth original surface.
Details: I have a height field of (a projectable part of) this surface (a 2.5D triangulation where each x,y pair has a unique height z) and I need to compute the height z of arbitrary x,y pairs. For example the z-value of the point in the image where the cursor points to.
If it was a 2D problem, I would use cubic splines but for surfaces I'm not sure what is the best solution.
As commented by #Darren what you need are patches.
It can be bi-linear patches or bi-quadratic or Coon's patches or other.
I have found no much reference doing a quick search but this links:
provide an overview: http://www.cs.cornell.edu/Courses/cs4620/2013fa/lectures/17surfaces.pdf
while this is more technical: https://www.doc.ic.ac.uk/~dfg/graphics/graphics2010/GraphicsHandout05.pdf
The concept is that you calculate splines along the edges (height function with respect to the straight edge segment itself) and then make a blending inside the surface delimited by the edges.
The patch os responsible for the blending meaning that inside any face you have an height which is a function of the point position coordinates inside the face and the values of the spline ssegments which are defined on the edges of the same face.
As per my knowledge it is quite easy to use this approach on a quadrilateral mesh (because it becomes easy to define on which edges sequence to do the splines) while I am not sure how to apply if you are forced to go for an actual triangulation.
I have a convex polygon in 3D. For simplicity, let it be a square with vertices, (0,0,0),(1,1,0),(1,1,1),(0,0,1).. I need to arrange these vertices in counter clockwise order. I found a solution here. It is suggested to determine the angle at the center of the polygon and sort them. I am not clear how is that going to work. Does anyone have a solution? I need a solution which is robust and even works when the vertices get very close.
A sample MATLAB code would be much appreciated!
This is actually quite a tedious problem so instead of actually doing it I am just going to explain how I would do it. First find the equation of the plane (you only need to use 3 points for this) and then find your rotation matrix. Then find your vectors in your new rotated space. After that is all said and done find which quadrant your point is in and if n > 1 in a particular quadrant then you must find the angle of each point (theta = arctan(y/x)). Then simply sort each quadrant by their angle (arguably you can just do separation by pi instead of quadrants (sort the points into when the y-component (post-rotation) is greater than zero).
Sorry I don't have time to actually test this but give it a go and feel free to post your code and I can help debug it if you like.
Luckily you have a convex polygon, so you can use the angle trick: find a point in the interior (e.g., find the midpoint of two non-adjacent points), and draw vectors to all the vertices. Choose one vector as a base, calculate the angles to the other vectors and order them. You can calculate the angles using the dot product: A · B = A B cos θ = |A||B| cos θ.
Below are the steps I followed.
The 3D planar polygon can be rotated to 2D plane using the known formulas. Use the one under the section Rotation matrix from axis and angle.
Then as indicated by #Glenn, an internal points needs to be calculated to find the angles. I take that internal point as the mean of the vertex locations.
Using the x-axis as the reference axis, the angle, on a 0 to 2pi scale, for each vertex can be calculated using atan2 function as explained here.
The non-negative angle measured counterclockwise from vector a to vector b, in the range [0,2pi], if a = [x1,y1] and b = [x2,y2], is given by:
angle = mod(atan2(y2-y1,x2-x1),2*pi);
Finally, sort the angles, [~,XI] = sort(angle);.
It's a long time since I used this, so I might be wrong, but I believe the command convhull does what you need - it returns the convex hull of a set of points (which, since you say your points are a convex set, should be the set of points themselves), arranged in counter-clockwise order.
Note that MathWorks recently delivered a new class DelaunayTri which is intended to superseded the functionality of convhull and other older computational geometry stuff. I believe it's more accurate, especially when the points get very close together. However I haven't tried it.
Hope that helps!
So here's another answer if you want to use convhull. Easily project your polygon into an axes plane by setting one coordinate zero. For example, in (0,0,0),(1,1,0),(1,1,1),(0,0,1) set y=0 to get (0,0),(1,0),(1,1),(0,1). Now your problem is 2D.
You might have to do some work to pick the right coordinate if your polygon's plane is orthogonal to some axis, if it is, pick that axis. The criterion is to make sure that your projected points don't end up on a line.