How to avoid the polygon to be complex when optimizing its vertices? - graphics

Suppose there's a set of 2D points to represent an initial simple polygon. Now I want to optimize the positions of each point according to some cost function. But this could make the polygon complex, i.e. the polygon intersects with itself. How can I avoid this? Thanks!

If the polygon could be presumed to be convex, then it is simple. Simply compute the angles between each side and the next side. Each angle must be between 0 and 180 degrees for a convex polygon. The sum of those angles is well known for a closed polygon with N sides. This will result in a simple constrained optimization. (Actually, you can write those constraints in a "simpler" form than computing the angles with a trigonometric function. Cross products will suffice.)
If the polygon need not be convex, then you need to worry about edges crossing, or other degeneracies.

Related

Circle triangulation

I am currently experimenting with openGL, and I'm drawing a lot of circles that I have to break down to triangles (triangulate a circle).
I've been calculating the vertices of the triangles by having an angle that is incremented, and using cos() and sin() to get the x and y values for one vertex.
I searched a bit on the internet about the best and most efficient way of doing this, and even though there's not much information avaliable realized that thin and long triangles (my approach) are not very good. A better approach would be to start with an equilateral triangle and then repeatedly add triangles that cover the larges possible area that's not yet covered.
left - my method; right - new method
I am wondering if this is the most efficient way of doing this, and if yes, how would that be implemented in actual code.
The website where I found the method: link
both triangulations has their pros and cons
The Triangle FAN has equal sized triangles which sometimes looks better with textures (and other interpolated stuff) and the code to generate is simple for loop with parametric circle equation.
The increasing detail mesh has less triangles and can easily support LOD which might be faster. However number of points is not arbitrary (3,6,12,24,48,...). The code is slightly more complicated you could:
start with equilateral triangle remembering circumference edges
so add triangle (p0,p1,p2) to mesh and edges (p0,p1),(p1,p2),(p2,p0) to circumference.
for each edge (p0,p1) of circumference
compute:
p2 = 0.5*(p0+p1); // mid point
p2 = r*p2/|p2|; // normalize it to circle circumference assuming (0,0) is center
add triangle (p0,p1,p2) to mesh and replace p0,p1 edge with (p0,p2),(p2,p1) edges
note that r/|p2| will be the same for all edges in current detail level so no need to compute expensive |p2| over and over again.
goto #2 until you have enough dense triangulation
so 2 for loops and few dynamic lists (points,triangles,circumference_edges,and some temps if not doing this inplace). Also this method does not need goniometrics at all (can be modified to generate the triangle fan too).
Here similar stuff:
sphere triangulation using similar technique

How to find out if vertex is merge/split? (polygon triangulation, c#)

I'm doing triangulation of polygon in C#.
I wrote code for triangulating monotone polygon, but I can't find a way to break polygon in monotone parts.
I found many algorithms, for example ( http://research.engineering.wustl.edu/~pless/546/lectures/l7.html ), plane sweep method where events are vertices of polygon, and depending if vertex is start, end, regular, split or merge, I do different things with it.
I understand how algorithm works, but I don't know how to check if vertex is split/merge or just start/end?
It looks like you have to know which side of an edge is inside/outside or the case is indeed ambiguous. If this is given by the winding/order of the vertices, it's easy - always take the angle clockwise or counter clockwise from the first to the second edge (or adjacent vertices) hence the 180 degrees mentioned. If vertex order is arbitrary, I can only assume you have to keep track of the inside/outside direction explicitly which might require an initial classification pass.

Given an irregular polygon's vertex list, how to create internal triangles to build a flat 3D mesh efficiently?

I'm using Unity, but the solution should be generic.
I will get user input from mouse clicks, which define the vertex list of a closed irregular polygon.
That vertices will define the outer edges of a flat 3D mesh.
To procedurally generate a mesh in Unity, I have to specify all the vertices and how they are connected to form triangles.
So, for convex polygons it's trivial, I'd just make triangles with vertices 1,2,3 then 1,3,4 etc. forming something like a Peacock tail.
But for concave polygons it's not so simple.
Is there an efficient algorithm to find the internal triangles?
You could make use of a constrained Delaunay triangulation (which is not trivial to implement!). Good library implementations are available within Triangle and CGAL, providing efficient O(n*log(n)) implementations.
If the vertex set is small, the ear-clipping algorithm is also a possibility, although it wont necessarily give you a Delaunay triangulation (it will typically produce sub-optimal triangles) and runs in O(n^2). It is pretty easy to implement yourself though.
Since the input vertices exist on a flat plane in 3d space, you could obtain a 2d problem by projecting onto the plane, computing the triangulation in 2d and then applying the same mesh topology to your 3d vertex set.
I've implemented the ear clipping algorithm as follows:
Iterate over the vertices until a convex vertex, v is found
Check whether any point on the polygon lies within the triangle (v-1,v,v+1). If there are, then you need to partition the polygon along the vertices v, and the point which is farthest away from the line (v-1, v+1). Recursively evaluate both partitions.
If the triangle around vertex v contains no other vertices, add the triangle to your output list and remove vertex v, repeat until done.
Notes:
This is inherently a 2D operation even when working on 3D faces. To consider the problem in 2D, simply ignore the vector coordinate of the face's normal which has the largest absolute value. (This is how you "project" the 3D face into 2D coordinates). For example, if the face had normal (0,1,0), you would ignore the y coordinate and work in the x,z plane.
To determine which vertices are convex, you first need to know the polygon's winding. You can determine this by finding the leftmost (smallest x coordinate) vertex in the polygon (break ties by finding the smallest y). Such a vertex is always convex, so the winding of this vertex gives you the winding of the polygon.
You determine winding and/or convexity with the signed triangle area equation. See: http://softsurfer.com/Archive/algorithm_0101/algorithm_0101.htm. Depending on your polygon's winding, all convex triangles with either have positive area (counterclockwise winding), or negative area (clockwise winding).
The point-in-triangle formula is constructed from the signed-triangle-area formula. See: How to determine if a point is in a 2D triangle?.
In step 2 where you need to determine which vertex (v) is farthest away from the line, you can do so by forming the triangles (L0, v, L1), and checking which one has the largest area (absolute value, unless you're assuming a specific winding direction)
This algorithm is not well defined for self-intersecting polygons, and due to the nature of floating point precision, you will likely encounter such a case. Some safeguards can be implemented for stability: - A point should not be considered to be inside your triangle unless it is a concave point. (Such a case indicates self-intersection and you should not partition your set along this vertex). You may encounter a situation where a partition is entirely concave (i.e. it's wound differently to the original polygon's winding). This partition should be discarded.
Because the algorithm is cyclic and involves partitioning the sets, it is highly efficient to use a bidirectional link list structure with an array for storage. You can then partition the sets in 0(1), however the algorithm still has an average O(n^2) runtime. The best case running time is actually a set where you need to partition many times, as this rapidly reduces the number of comparisons.
There is a community script for triangulating concave polygons but I've not personally used it. The author claims it works on 3D points as well as 2D.
One hack I've used in the past if I want to constrain the problem to 2D is to use principal component analysis to find the 2 axes of greatest change in my 3D data and making these my "X" and "Y".

polygon vertices - clockwise or counterclockwise

I came across this link http://www.mathopenref.com/coordpolygonarea2.html
It explains how to calculate the area of a polygon and helps to identify whether the polygon vertices we entered is clockwise or counter clockwise.
If area value is +ve, it is clockwise, if it is -nv then it is in counterclockwise.
My requirement is to identify only whether it is clockwise or counterclockwise. Is this rule will work correctly (though there are limitations as mentioned in the link). I have only regular polygons (not complicated, no self intersections) but the vertices are more.
I am not interested in the area value accuracy, just to know the ring rotation.
Any other thought on this.
For convex polygons:
Select two edges with a common vertex.
Lets say, edge1 is between vertex A and B. Edge2 is between vertex B and C.
Define to vectors: vect1: A----->B
vect2: B----->C
Cross product vect1 and vect2.
If the result is positive, the sequence A-->B-->C is Counter-clockwise.
If the result is negative, the sequence A-->B-->C is clockwise.
If you have only convex polygons (and all regular polygons are convex), and if your points are all organized consistently--either all counterclockwise or all clockwise--then you can determine which by just computing the (signed) area of one triangle determined by any three consecutive points. This is essentially computing the cross product of the two vectors along the two edges.

How to determine a diagonal is in or out of a concave polygon?

The diagonal (a diagonal is a segment connecting nonadjacent vertices) of a concave (non-convex) polygon can be completely in or out of the polygon(or can intersect with the edges of polygon). How to determine whether it is completely in the polygon?(a method without point-in-polygon test).
If the diagonal has at least one intersection with the edges, it is partially in and partially out of the polygon, however, If the diagonal has no intersection with them, there are only two states: it is compeletely in or completely out of the polygon.
To determine whether it is in or out of the polygon:
Suppose polygon's vertices are sorted counterclockwise. Consider one of the endpoints of the diagonal which lies on the vertex named P[i] (the other endpoint is p[j]). Then, Make three vectors whose first points are p[i] :
V1 : p[i+1] - p[i]
V2 : p[i-1] - p[i]
V3 : p[j] - p[i]
The diagonal is completely in the polygon if and only if V3 is between V1 and V2 when we move around counterclockwise from V1 to V2.
How to determine whether V3 is between V1 and V2 when we go from V1 to V2 counterclockwise? go to here.
I've written a program using this method and it works effectively .
How to determine whether it is completely in the polygon?
If you want to determine whether a diagonal never leaves the polygon's boundary, just determine whether or not it intersects any lines between two adjacent vertices.
If it does, it's partially in and partially out of the polygon.
If not, it's either completely in or completely out of the polygon. From there, the simplest method is to use the point-in-polygon on any point on the diagonal, but if you don't want to do that, use the winding algorithm.
I believe John's answer misses an important case: when the diagonal is completely outside the polygon from the get-go. Imagine making the diagonal "bridge" the two towers of his "u" shaped polygon.
I had to solve this several years ago, so please forgive if my recollection is a bit spotty.
The way I solved this was to perform line intersection tests of the diagonal against every edge in the polygon. You then have two possible cases: you either had at least one intersection, or you had no intersections. If you get any intersections, the diagonal is not inside the polygon.
If you don't get any intersections, you need to determine whether the diagonal is completely inside or completely outside the polygon. Let's say the diagonal is joining p[i] to p[j], that i < j and you have a polygon with clockwise winding. You can work out if the diagonal is outside the polygon by looking at the edge joining p[i] to p[i+1]. Work out the 2D angle of this edge (using, say, the x-axis as the baseline.) Rotate your diagonal so that the p[i]-p[i+1] edge is its baseline and compute its 2D angle.
Once you've done this, the 2D angle of the diagonal will be positive if the diagonal is outside the polygon, or negative if it's inside the polygon.
I understand this question was answered many years ago, but I have a new approach which is easy to implement.
As suggested in previous answers, you should first compute for all edges of the polygon if any of them intersect with the diagonal line segment. The code to compute intersection and determine if one even exists is described here.
If all edges (excluding those that share vertices with diagonal) do not have an intersection with diagonal then you know that the diagonal is either completely inside or completely outside of the polygon meaning that the midpoint of the diagonal is also completely inside or completely outside respectively. The midpoint is the average of the diagonal's two endpoints.
We now have transformed the problem to computing whether the diagonal is inside or outside the polygon to whether the midpoint is inside or outside the polygon. Working with a single point is easier than with a line.
The way to determine if a point is within a polygon is described here and can be summarized by counting the amount of intersection of horizontal ray starting at the point and seeing how many polygon edges this ray intersects. If the ray intersects an odd amount of times then the point is inside the polygon and otherwise outside the polygon.
The reason why this implementation is easy to implement is while you iterate through all the edges to check for intersection with diagonal you can now also count if the diagonal's midpoint's ray intersects with the current edge being processed. If your for loop returns with no intersection between diagonal and edges then you can see the even/odd count to determine if diagonal is inside or outside.
With regard to checking for intersections between line segments (which is the first step you would likely have to do), I found the explanations on SoftSurfer to be helpful. You would have to check for an intersection between the diagonal and any of the edges of the polygon. If you are using MATLAB, you should be able to find an efficient way to check intersections for all the edges simultaneously using matrix and vector operations (I've dealt with computing intersection points in this way for ray-triangle intersections).
John's answer is spot on:
If you want to determine whether a diagonal never leaves the polygon's boundary, just determine whether or not it intersects any lines between two adjacent vertices. If so, it's left the polygon.
A efficient way to do this check is to run the Bentley-Ottman sweepline algorithm on the data. It's easy to implement but hard to make numerical stable. If you have less than ... say ... 20 edges in your polygons a brute force search will most likely be faster.

Resources