How to form Concave shapes from convex pieces Confusion - c++

Hey so i was told in a previous answer that to make concave shapes out of multiple convex ones i do the following:
If you don't have a convex hull, perform a package wrapping algorithm
to get a convex border that encompasses all your points (again quite
fast). en.wikipedia.org/wiki/Gift_wrapping_algorithm
Choose a point that is on the boarder as a starter point for the algorithm.
Now, itterate through the following points that are on your shape,
but aren't on the convex border.
When one is found, create a new shape with the vertices from
the starter point to the found non-border point.
Finally set the starter point to be the the found off-border point
Recursion is now your friend: do the exact same process on each new
sub-shape you make.
I'm confused on one thing though. What do you do when two vertices in a row are off-border? After reaching the first one you connect the starter point to it, but then you immediatly run into another off-border point after you start itterating again, leaving you with only 2 vertices to work with: the starter point and new off-border point. What am i missing?
To illustrate my problem, here's a shape pertaining to this issue: It would be great if someone could draw all over it and walk through the steps of the algorithm using this. And using point 1 as the starting point.
Thanks!

Assuming you really want to take a convex polygon (as you've illustrated) and decompose it into convex parts without introducing new vertices, the usual approach is called "ear clipping" and is described in this Wikipedia article, Polygon triangulation. In this approach the convex pieces are triangles, which are necessarily convex.
This problem has been discussed in connection with the CGAL computational geometry software here in Stackoverflow, C++ 2D tessellation library.

Related

How to mesh a 2D point cloud in C++

I have a set of 2D points of a known density I want to mesh by taking the holes in account. Basically, given the following input:
I want something link this:
I tried PCL ConcaveHull, but it doens't handle the holes and splitted mesh very well.
I looked at CGAL Alpha shapes, which seems to go in the right direction (creating a polygon from a point cloud), but I don't know how to get triangles after that.
I though of passing the resulting polygons to a constrained triangulation algorithm and mark domains, but I didn't find how to get a list of polygons.
The resulting triangulated polygon is about a two step process at the least. First you need to triangulate your 2D points (using something like a Delaunay2D algorithm). There you can set the maximum length for the triangles and get the the desired shape. Then you can decimate the point cloud and re-triangulate. Another option is to use the convex hull to get the outside polygon, then extract the inside polygon through a TriangulationCDT algorithm, the apply some PolygonBooleanOperations, obtain the desired polygon, and finaly re-triangulate.
I suggest you look into the Geometric Tools library and specifically the Geometric Samples. I think everything you need is in there, and is much less library and path heavy than CGAL (the algorithms are not free for this type of work unless is a school project) or the PCL (I really like the library for segmentation, but their triangulation breaks often and is slow).
If this solves your problem, please mark it as your answer. Thank you!

How to get curve from intersection of point cloud and arbitrary plane?

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.

How to form a Concave shape out of Convex shapes?

i'm trying to get around the rule of only being able to form convex shapes in the SFML c++ library.
To do this I'm planning on testing given vertices, and if concave,
splitting the vertices into groups, testing each groups' concaveness,
and repeating until a full set of concave shapes results that look
just like the original shape when put together
What I would like to know is...
What the equation for testing a shapes concaveness is: What is it and how does it work?
How would i split up the vertices of the concave shape so in the end the shape is formed out of as few convex shapes as possible?
Whats the best practice for achieving my goal?
Thanks!
You can test for a shape being a convex hull by going round all the edges and checking the next edge is always moving in the same direction (left/right handed). This is a quick and cheap algorithm. There is an implementation of this here: en.wikipedia.org/wiki/Graham_scan
If you don't have a convex hull, perform a package wrapping algorithm to get a convex hull that encompasses all your points (again quite fast). en.wikipedia.org/wiki/Gift_wrapping_algorithm
Now, look for points that are on your shape, but aren't on the convex hull. For each run of these points, create a new shape from these points (plus the 2 either side on the convex hull).
Recursion is now your friend: do the exact same process on each of the sub-shapes you have just made.
I have used this techniques to test for a point being contained inside an arbitrary shape: i.e. the point must be inside the convex hull (easy to test), but not any of the sub-shapes, or their sub-shapes, or their sub-shapes....
The Boost Geometry library that was published yesterday, has an implementation of Convex Hull algorithm. A picture says more than a thousand words:
Although this constructs a 'new' shape that is non-concave (i.e. convex); This may or may not be precisely what you want. However, in the process the algorithm is bound to be able to classify shape a concave/convex, so you'd likely be interested in the library nonetheless.
General information on convex hull algorithm:
http://en.wikipedia.org/wiki/Convex_hull
http://en.wikipedia.org/wiki/Convex_hull_algorithms
Since Adrian Japon more or less suggested that 'hit testing' (containment test) is of a usual reason to care about convex/concave geometries, without further ado, I'll highlight the corresponding Boost Geometry algorithm for that: within.
Again, really because the picture is so pretty. Note that though the picture suggests querying for a point against a polygon, the algorithms are fully generic and can be used to test complete containment on n-dimensional polygons in another
Alright, just to mash all the info together:
To test polygon Concaveness, look at this page given by Adrian
Taylor
One way to accomplish my goal is to use Monotone Decomposition and Triangulation
You can learn about Monotone Decomposition at this lovely site: (summary of it below)
Finally, triangulate the now Monotone shapes using the information in this Powerpoint:
Push u1 and u2 on the stack.
j = 3 /* j is index of current vertex */
u = uj
Case (i): u is adjacent to v1 but not vi.
add diagonals uv2, uv3, …, uvi.
pop vi, vi-1, …, v1 from stack.
push vi, u on stack.
Case (ii): u is adjacent to vi but not v1.
while i > 1 and angle uvivi-1 < 
add diagonal uvi-1
pop vi from stack
endwhile
push u
Case (iii): u adjacent to both v1 and vi.
add diagonals uv2, uv3, …, uvi-1.
exit
j = j + 1
Go to step 3.
**Note:**
By “adjacent” we mean connected by an edge in P.
Recall that v1 is the bottom of the stack, vi is the top.
By “Push” we mean push the item(s) to the back of the list
Hope this helps someone... but I'm still looking for any better/faster solutions.
Some things to think about:
Left-handed and right-handed corners (the sign of the cross-product is an easy way to distinguish). All corners in a convex shape are the same handed-ness.
Extending an edge and adding a new vertex may give you better results than adding edges between existing vertices.
I assume you have your polygon as a list of point, a very simple way would be to go around your polygon and consider the sequence of triplet of consecutive points (A,B,C).
Then you just check that at one point det(AB,BC) changes its sign, where
det(AB,AC) = (x_a-x_b)(yc-yb) - (x_c-x_b)(y_a-y_b)

GJK collision detection implementation from 2D to 3D

I apologize for the length of this question and give a pre-emptive thanks for anyone who reads through this!
So i've spent the last few days going over the GJK algorithm. I understand the general concepts behind it, and understand the most of the nitty gritties of its implementation in 2D thanks to the wonderful article by William Bittle at http://www.codezealot.org/archives/88 .
I've implemented his pseudo code (found at the end of the article) into my own c++ project, however i want to make a 3D implementation. My weakness comes into using the dot products to test the voronoi regions and the tripleProducts to get perpandicular lines. But im trying to read up more on that.
My problem comes down to the containsOrigin function. Im having trouble visualizing and accounting for the new voronoi regions that the z axis adds. I just can't seem to wrap my head around how to determine which regions contains the origin. I assume there is 4 I have to account for, each extending from the triangular planes that the comprise the 4 faces of the tetrahedron simplex. If the origin is not within any of those regions, then it is contained, and we have a collision.
How do i go about testing if it is contained in a particular voronoi region/ which triangular face is pointing in the direction of the origin?
The current 2D algorithm checks if a triangle is made, if not, then the simplex is a line and it finds the 3rd point. I assume the 3D algorithm with check if a tetrahedron is made, if not, then it will check for a triangle, if true then it will to find a 4th point to make a tetrahedron(how would i get this? using a normal in direction of origin?). If i trangle isnt made, it will find a 3rd point to make a triangle (do i still use triple product for this like in 2D?).
Any suggestions, outlines, resources, code augmentations, comments are much appretiated.
Depending on what result you expect from the GJK algorithm you might want to look at this nice tutorial from Molly Rocket: https://mollyrocket.com/849
Be aware though that his implementation only outputs intersection? yes/no. But it might be a nice start.

C++ 2D tessellation library?

I've got some convex polygons stored as an STL vector of points (more or less). I want to tessellate them really quickly, preferably into fairly evenly sized pieces, and with no "slivers".
I'm going to use it to explode some objects into little pieces. Does anyone know of a nice library to tessellate polygons (partition them into a mesh of smaller convex polygons or triangles)?
I've looked at a few I've found online already, but I can't even get them to compile. These academic type don't give much regard for ease of use.
CGAL has packages to solve this problem. The best would be probably to use the 2D Polygon Partitioning package. For example you could generate y-monotone partition of a polygon (works for non-convex polygons, as well) and you would get something like this:
The runnning time is O(n log n).
In terms of ease of use this is a small example code generating a random polygon and partitioning it (based on this manual example):
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
typedef CGAL::Partition_traits_2<K> Traits;
typedef Traits::Point_2 Point_2;
typedef Traits::Polygon_2 Polygon_2;
typedef std::list<Polygon_2> Polygon_list;
typedef CGAL::Creator_uniform_2<int, Point_2> Creator;
typedef CGAL::Random_points_in_square_2<Point_2, Creator> Point_generator;
int main( )
{
Polygon_2 polygon;
Polygon_list partition_polys;
CGAL::random_polygon_2(50, std::back_inserter(polygon),
Point_generator(100));
CGAL::y_monotone_partition_2(polygon.vertices_begin(),
polygon.vertices_end(),
std::back_inserter(partition_polys));
// at this point partition_polys contains the partition of the input polygons
return 0;
}
To install cgal, if you are on windows you can use the installer to get the precompiled library, and there are installations guides for every platform on this page. It might not be the simplest to install but you get the most used and robust computational geometry library there is out there, and the cgal mailing list is very helpful to answer questions...
poly2tri looks like a really nice lightweight C++ library for 2D Delaunay triangulation.
As balint.miklos mentioned in a comment above, the Shewchuk's triangle package is quite good. I have used it myself many times; it integrates nicely into projects and there is the triangle++ C++ interface. If you want to avoid slivers, then allow triangle to add (interior) Steiner points, so that you generate a quality mesh (usually a constrained conforming delaunay triangulation).
If you don't want to build the whole of GCAL into your app - this is probably simpler to implement.
http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml
I've just begun looking into this same problem and I'm considering voronoi tessellation. The original polygon will get a scattering of semi random points that will be the centers of the voronoi cells, the more evenly distributed they are the more regularly sized the cells will be, but they shouldn't be in a perfect grid otherwise the interior polygons will all look the same. So the first thing is to be able to generate those cell center points- generating them over the bounding box of the source polygon and a interior/exterior test shouldn't be too hard.
The voronoi edges are the dotted lines in this picture, and are sort of the complement of the delaunay triangulation. All the sharp triangle points become blunted:
Boost has some voronoi functionality:
http://www.boost.org/doc/libs/1_55_0/libs/polygon/doc/voronoi_basic_tutorial.htm
The next step is creating the voronoi polygons. Voro++ http://math.lbl.gov/voro++/ is 3D oriented but it is suggested elsewhere that approximately 2d structure will work, but be much slower than software oriented towards 2D voronoi. The other package that looks to be a lot better than a random academic homepage orphan project is https://github.com/aewallin/openvoronoi.
It looks like OpenCV used to support do something along these lines, but it has been deprecated (but the c-api still works?). cv::distTransform is still maintained but operates on pixels and generates pixel output, not vertices and edge polygon data structures, but may be sufficient for my needs if not yours.
I'll update this once I've learned more.
A bit more detail on your desired input and output might be helpful.
For example, if you're just trying to get the polygons into triangles, a triangle fan would probably work. If you're trying to cut a polygon into little pieces, you could implement some kind of marching squares.
Okay, I made a bad assumption - I assumed that marching squares would be more similar to marching cubes. Turns out it's quite different, and not what I meant at all.. :|
In any case, to directly answer your question, I don't know of any simple library that does what you're looking for. I agree about the usability of CGAL.
The algorithm I was thinking of was basically splitting polygons with lines, where the lines are a grid, so you mostly get quads. If you had a polygon-line intersection, the implementation would be simple. Another way to pose this problem is treating the 2d polygon like a function, and overlaying a grid of points. Then you just do something similar to marching cubes.. if all 4 points are in the polygon, make a quad, if 3 are in make a triangle, 2 are in make a rectangle, etc. Probably overkill. If you wanted slightly irregular-looking polygons you could randomize the locations of the grid points.
On the other hand, you could do a catmull-clark style subdivision, but omit the smoothing. The algorithm is basically you add a point at the centroid and at the midpoint of each edge. Then for each corner of the original polygon you make a new smaller polygon that connects the edge midpoint previous to the corner, the corner, the next edge midpoint, and the centroid. This tiles the space, and will have angles similar to your input polygon.
So, lots of options, and I like brainstorming solutions, but I still have no idea what you're planning on using this for. Is this to create destructible meshes? Are you doing some kind of mesh processing that requires smaller elements? Trying to avoid Gouraud shading artifacts? Is this something that runs as a pre-process or realtime? How important is exactness? More information would result in better suggestions.
If you have convex polygons, and you're not too hung up on quality, then this is really simple - just do ear clipping. Don't worry, it's not O(n^2) for convex polygons. If you do this naively (i.e., you clip the ears as you find them), then you'll get a triangle fan, which is a bit of a drag if you're trying to avoid slivers. Two trivial heuristics that can improve the triangulation are to
Sort the ears, or if that's too slow
Choose an ear at random.
If you want a more robust triangulator based on ear clipping, check out FIST.