I'm looking at the Partition_2 section of the manual and examples to see if CGAL can handle convex partitioning of a polygon with holes. All of the examples appear to use Polygons without any holes. Does anyone know if this is supported by any of the CGAL partitioning algorithms?
https://github.com/CGAL/cgal/blob/master/Partition_2/include/CGAL/partition_2.h
https://doc.cgal.org/latest/Partition_2/index.html
Thanks,
Josh.
From the documentation:
All the partitioning functions present the same interface to the user.
That is, the user provides a pair of input iterators, first and
beyond, an output iterator result, and a traits class traits. The
points in the range [first, beyond) are assumed to define a simple
polygon whose vertices are in counterclockwise order.
Simple means no holes and no self intersection.
Handling polygons with holes is not hard to achieve since CGAL also provides boolean operations on polygons. Just create the partition and subtract the holes. This may not be an ideal solution if your use case is performance critical (directly partitioning a polygon with holes can be faster).
Right, the "2D Polygon Partitioning" package supports only polygons without holes (as far as I know). You can always triangulate a polygon with holes using the edges (on the outer and inner CCBs) as constraints. Another option is to use vertical decomposition. It is directly provided by the "2D Minkowski Sums" package; see Polygon_vertical_decomposition_2. It is based on the decompose(arr, oi) free function that accepts as input a 2D arrangement; see CGAL::decompose(). The output is a collection of pseudo trapezoids (a pseudo trapezoid can be a triangle in degenerate cases), so it's a bit "better" than pure triangles and extremely efficient, especially if you have the underlying arrangement at hand.
Related
I followed the example reported here: https://doc.cgal.org/latest/Mesh_2/index.html (at paragraph "1.3 Example: Making a Triangulation Conforming Delaunay and Then Conforming Gabriel") to create a conforming constrained Delaunay triangulation using CGAL.
Making the triangulation conforming may introduce in the triangulation itself some Steiner vertexes that are not present among the original input vertexes. Is it possible to know to which original constrained edge a Steiner vertex belongs?
That is, when performing constrained triangulation, we can insert more than one CGAL::Polygon_2 into the triangulation as a constraint (it is done for example at this link from the CGAL manual: https://doc.cgal.org/latest/Triangulation_2/index.html); so, in other words, I would like to know if I can understand to which of the original constrained edges (or, if not possible, to which polygon) a specific Steiner vertex belongs to, is it possible? and how could I achieve this?
If you use the Constrained_triangulation_plus_2 with your current triangulation as base triangulation, you will have a notion of subconstraints that will give you access to vertices in the middle of original constraints. However, if you have intersection between your input constraints, the intersection vertices will also be reported as inside a constraint.
In this example you have an example of iteration over input constraints and look at vertices on the constraints.
For a polygon defined as a sequence of (x,y) points, how can I detect whether it is complex or not? A complex polygon has intersections with itself, as shown:
Is there a better solution than checking every pair which would have a time complexity of O(N2)?
There are sweep methods which can determine this much faster than a brute force approach. In addition, they can be used to break a non-simple polygon into multiple simple polygons.
For details, see this article, in particular, this code to test for a simple polygon.
See Bentley Ottmann Algorithm for a sweep based O((N + I)log N) method for this.
Where N is the number of line segments and I is number of intersection points.
In fact, this can be done in linear time use Chazelle's triangulation algorithm. It either triangulates the polygon or find out the polygon is not simple.
I would like to apply Data-Oriented Design (based on e.g. this article) to my simple physics engine. And I'm focused on optimizing the collision testing as it is the most expensive part of it.
I've organized the bounding spheres that may collide with player into single vector:
struct Sphere{ //I don't split sphere into parts,
//as I usually access both position and radius in my calculations
Point3D position;
float radius;
};
std::vector<BoudingSphere> spheres;
and I test collisions with them inside single function/method. Everything looks clear to me to that point.
The problem is, I also have some more general structures like:
struct Polygon{ //it may e.g. represents the area or be used for more precise tests
std::vector<Point2D> points;
};
I guess it won't be a good practise to just create std::vector<Polygon> the same way, as nested vector (points) will take a lot of place in memory (reserving it).
On the other hand, I cannot assume that there are always 2,3,4 or 10 points (it differs a lot, with the maximum of about 20, but it's usually much less).
And I do not want to switch from Polygon general structure to e.g. series of triangles (as it is faster then separated triangles in many calculations).
What should I do then? I want to go with the spirit of Data-Oriented Design and use the memory/cache efficiently with my Polygon.
Do I have to get rid of the inner vector (points)? How if so?
There can't be a definitive answer to this question as it would require knowledge about the way you access the data in terms of when is it initialized, can it be changed after the initialization stage and many others. However, if your data is relatively stable and you are accessing your polygons in a consistent manner just iterating over all polygons or polygons belonging to one particular object, one approach may be to put the points of your polygons into a separate vector and just have the polygons store the beginning and the end indices to that array.
This way, there are a couple of things that needs to be accessed during traversal. First, the indices stored in the polygons. Second, the points themselves. Both of these accesses are likely to be cache-friendly if the polygons are also laid out in a vector. Similar approach can be applied to polygon sets - just store the polygons in a vector and have a (begin, end) pair in your game objects.
I'm new in using C++ boost library in particularly the boost graph library which a needed to try coding some algorithms where i commonly check the adjacency of two vertices and dealing with other graph concepts like computing graph invariants.
What i know is that we can iterate through adjacent vertices with the function : adjacent_vertices(u, g) but i'm searching for an efficient way to test if two vertices u, v are adjacent or not without doing linear search
The AdjacencyMatrix concept gives a complexity guarantee that the edge() function must return in constant time.
To check if two vertices v and w are adjacent in G, you write edge(v, w, G).second, since the function returns a pair where the second value indicates if the edge exists.
The edge() function is implemented for other graph representations as well. Here is a graph that shows how different representations compare with regard to performance of checking vertex adjacency:
Here is the code used to generate the data for this plot. Each data point is 100 random graphs of medium density, with 100 random edge checks per each graph. Note the logarithmic y axis.
What is the best choice will eventually depend on your particular application, because for other operations the ordering of structures by speed is different. In other words, avoid premature optimization.
BGL is a highly generic library. You can adapt most any datastructure for use with its algorithms.
You can vary the edge container. You don't mention it, but I'm assuming you've been looking at the interface/complexity guarantees for boost::adjacency_list.
Indeed the edge membership test will be O(n) even if you use setS for the edge container selector. This is mostly because adjacency lists store outgoing edges are per vertex. So in worst case, each vertex contains at most one outgoing edge and the search is practically O(n) [1]
In this case you simply want to select another graph implementation.
The documentation page on Graph Concepts is a good starting point to find out about which concepts are expected. As well as, which models supply those concepts.
In the worst case you can adapt your data structure for use with Boost Graph algorithms. E.g. you could store all edges in a simple std::[unordered_]set<std::pair<VID, VID> > and adapt it to model the EdgeListGraph concept.
That way you will have performant lookups.
[1] of course this also means, in best case the search is whatever your set implementation affords: O(log n) because all edges could originate from the same vertex...
If we have K sets of potentially overlapping triangles, what is a computationally efficient way of computing a new, non-overlapping set of triangles?
For example, consider this problem:
Here we have 3 triangle sets A, B, C, with some mutual overlap, and wish to obtain the non-overlapping sets A', B', C', AB, AC, BC, ABC, where for example the triangles in AC would contain the surfaces where there is exclusive overlap among A and C; and A' would contain the surfaces of A which do not overlap any other set.
I (also) propose a two step approach.
1. Find the intersection points of all triangle sides.
As pointed out in the comments, this is a well-researched problem, typically approached with line sweep methods. Here is a very nice overview, look especially at the Bentley-Ottmann algorithm.
2. Triangulate with Constrained Delaunay.
I think Polygon Triangulation as suggested by #Claudiu cannot solve your problem as it cannot guarantee that all original edges are included. Therefore, I suggest you look at Constrained Delaunay triangulations. These allow you to specify edges that must be included in your triangulation, even if they would not be included in an unconstrained Delaunay or polygon triangulation. Furthermore, there are implementations that allow you to specify a non-convex border of your triangulation outside of which no triangles are generated. This also seems to be a requirement in your case.
Implementing Constrained Delaunay is non-trivial. There is however, a somewhat dated but very nice C implementation of available from a CMU researcher (including a command line tool). See here for the theory of this specific algorithm. This algorithm also supports specification of a border. Note that the linked algorithm can do more than just Constrained Delaunay (namely quality mesh generation), but it can be configured not to add new points, which amounts to Constrained Delaunay.
Edit See comments for another implementation.
If you want something a bit more straight forward, faster to implement, and significantly less code... I'd recommend just doing some simple polygon clipping like the old software rendering algorithms used to do (especially since you're only dealing with triangles as your input). As briefly mentioned by a couple of other people, it involves splitting each triangle at the point where every other segment intersects it.
Triangles are easy, because splitting a triangle at a given plane always results in just 1 or 2 new ones (2 or 3 total). If your data set is rather large, you could introduce a quad-tree or other form of spacial organization in order to find the intersecting triangles faster as the new ones get added.
Granted, this would generate more polygons than the suggested Constrained Delaunay algorithm. But many of those algorithms don't do well with overlapping shapes and would require you to know your silhouette segments, so you'd be doing much of the same work anyhow.
And if fewer resulting triangles is a requirement, you can always do a merging pass at the end (adding neighbor information during the clipping to speed that portion up).
Anyway, good luck!
Your example is a special case of what computational geometers call "an arrangement." The CGAL Library has extensive and efficent arrangement handling routines. If you check this part of the documentation, you'll see that you can declare an empty arrangement, then insert triangles to divide the 2d plane into disjoint faces. As others have said, you'll then need to triangulate the faces that aren't already triangles. Happily CGAL also provides the routines to do this. This example of constrained Delaunay triangulation is a good place to start.
CGAL attempts to use the most efficient algorithms available that are practical to implement. In this case it looks like you can achieve O((n + k) log n) for an arrangment with n edges (3 times the number of triangles in your case) with k intersection. The algorithm uses a general technique called "sweep line". A vertical line is swept left-to-right with "events" computed and processed along the way. Events are edge endpoints and intersections. As each event is processed, a cell of the arrangement is updated.
Delaunay algorithms are typically O(n log n) for n vertices. There are several common algorithms, easily looked up or found in the CGAL references.
Even if you can't use CGAL in your work (e.g. for licensing reasons), the documentation is full of sources on the underlying algorithms: arrangements and constrained Delaunay algorithms.
Beware however that both arrangments and triangulations are notoriously hard to implement correctly due to floating point error. Robust versions often depend on rational arithmetic (available in CGAL).
To expand a bit on the comment from Ted Hopp, this should be possible by first computing a planar subdivision in which each bounded face of the output is associated with one of the sets A', B', C', AB, AC, BC, ABC, or "none". The second phase is then to triangulate the (possibly non-convex) faces in each set.
Step 1 could be performed in O((N + K) log N) time using a variation of the Bentley-Ottmann sweep line algorithm in which the current set is maintained as part of the algorithm's state. This can be determined from the line segments that have already been crossed and their direction.
Once that's done, the disjoint polygons for each set can then be broken into monotone pieces in O(N log N) time which in turn can be triangulated in O(N) time.
If you haven't already, pick up a copy of "Computational Geometry: Algorithms and Applications" by de Berg et al.
I can think of two approaches.
A more general approach is treating your input as just a set of lines and splitting the problem in two:
Polygon Detection. Take the set of lines your initial triangles make and get a set of non-overlapping polygons. This paper offers an O((N + M)^4) approach, were N is the number of line segments and M the number of intersections, which does seem a bit slow unfortunately...
Polygon Triangulation. Take each polygon from step 1 and triangulate it. This takes O(n log* n) which is practically O(n).
Another approach is to do do a custom algorithm. Solve the problem for intersecting two triangles, apply it to the first two input triangles, then for each new triangle, apply the algorithm to all the current triangles with the new one. It seems even for two triangles this isn't that straightforward, though, as there are several cases (might not be exhaustive):
No points of the triangle are in any other trianle.
No intersection
Jewish star
Two perpendicular spikes
One point of one triangle is contained in the other
Each triangle contains one point of the other
Two points of one triangle are in the other
Three points of one are in the other - one is fully contained
etc... no, it doesn't seem like that is the right approach. Leaving it here anyway for posterity.