I have a tetrahedral mesh of a 3d region. The mesh is defined by two files with extensions .node and .ele which contain data related to nodes and elements (this is the format of output files from tetgen, the 3d Delaunay tetrahedralization program). The .node file contains in each line the node number and the x,y,z co-ordinates of that node. The .ele file contains the element number and node numbers corresponding to its four vertices. Now, given any point (x1,y1,z1), what is the easiest algorithm to decide which element this point belongs to?
If you know the orientation of the faces of your tetrahedra, then you only need to compute the volume of tetrahedra formed by your point p=(x1,y1,z1) and each face of the tetrahedra. Point p is inside a tetrahedron if and only if it makes a positive volume with respect to each face.
Snippet from Computational Geometry in C.
Related
I am working with several convex polygons that overlap each other and I need to combine them back together to form one single polygon that may be convex or concave.
The problem is always as follows:
1) The polygons that I need to merge together are always convex.
2) The vertices of each polygon are defined in clockwise order.
3) The polygons are never in any specific order.
4) The final polygon can only be simple convex or concave polygon, i.e. no self-intersection, no duplicate vertices or holes in the shape.
Here is an example of the kind of polygons that I am working with.
![overlapping convex polygons]"image removed")
My current approach is to start from the first polygon and vertex by vertex I loop through all vertices of all of the polygons to find overlap. If there is no overlap, I store the vertex for the final outline and continue.
Upon finding overlapping vertices, I determine which polygon to continue to by measuring the angles of the possible paths and by choosing the one that leads towards the outside of the shape.
This method works until I encounter polygons that do not have vertices overlapping each other, but instead one polygon's vertex is overlapping another polygon's side, as is the case with the rectangle in the image.
I am currently planning on solving these situations by running line intersect checks for all shapes that I have not yet processed, but I am convinced that this cannot be the easiest or the best method in terms of performance.
Does someone know how I should approach this problem in a more efficient manner and/or universal manner?
I solved this issue and I'm posting the answer here in case someone else runs into this issue as well.
My first step was to implement a pre-processing loop based on trincot's suggestions.
I calculated the minimum and maximum x and y bounds for each individual shape.
I used these values to determine all overlapping shapes and I stored a simple array for each shape that I could later use to only look at shapes that can overlap each other.
Then, for the actual loop that determines the outline of the final polygon:
I start from the first shape and simply compare its vertices to those of the nearby shapes. If there is at least one vertex that isn't shared by another vertex, it must be on the outer edge and the loop starts from there. If there are only overlapping vertices, then I add the first shape to a table for all checked shapes and repeat this process with another shape until I find a vertex that is on the outer edge.
Once the starting vertex is found, the main loop will check the vertices of the starting shape one by one and measure how far from the given vertex is from every nearby shapes' edges. If the distance is zero, then the vertex either overlaps with another shape's vertex or the vertex lies on the side of another shape.
Upon finding the aforementioned type of vertex, I add the previous shape's number to the table of checked shapes so that it isn't checked again. Then, I check if there are other shapes that share this particular vertex. If there are, then I determine the outermost shape and continue from there, starting back from step 2.
Once all shapes have been checked, I check that all non-overlapping vertices from the starting shape were indeed added to the outline. If they weren't, I add them at the end.
There may be computationally faster methods, but I found this one to be simple to write, that it meets all of my requirements and it is fast enough for my needs.
Given a vertex, you could speed up the search of an "overlapping" vertex or edge as follows:
Finding vertices
Assuming that the coordinates are exact, in the sense that if two vertices overlap, they have exactly the same x and y coordinates, without any "error" of imprecision, then it would be good to first create a hash by x-coordinate, and then for each x-entry you would have a hash by y-coordinate. The value of that inner hash would be a list of polygons that have that vertex.
That structure can be built in O(n) time, and will allow you to find a matching vertex in constant time.
Only if that gives no match, you would go to the next algorithm:
Finding edges
In a pre-processing step (only once), create a segment tree for these polygons where a "segment" corresponds to a min/max x-coordinate range for a particular polygon.
Given a vertex, use the segment tree to find the polygons that are in the right x-coordinate range, i.e. where the x-coordinate of the vertex is within the min/max range of x-coordinates of the polygon.
Iterate those polygons, and eliminate those that do not have an y-coordinate range that has the y-coordinate of the vertex.
If no polygons remain, the vertex does not participate in any edge of another polygon.
You cannot get more than one polygon here, since that would mean another polygon shares the vertex, which is a case already covered by the hash-based algorithm.
If you get just one polygon, then continue your search by going through the edges of that polygon to find a match -- which is what you already planned on doing (line intersect check), but now you would only need to do it for one polygon.
You could speed that line intersect check up a little bit by first filtering the edges to those that have the right x-range. For convex polygons you would end up with at most two edges. At most one of those two will have the right y-range. If you get such an edge, check whether the vertex is really on that edge.
Given a general polyline and an orthogonal grid, I would like to compute a simpler polyline whose vertices lie on the grid edges/vertices. This can look like this:
Left: A dense polyline as input, Right: A coarser polyline whose vertices lie on the intersection of the input polyline with the grid edges/vertices
(Sorry about the link to the image, but stack overflow apparently doesn't allow me to embed pictures before getting 10 credit points).
The grid is always orthogonal but its vertices do not necessarily have integer coordinates as some x or y lines might have coordinates defined by a previous geometric intersection computation. The initial curve can be represented as a polyline (though it would be nice to have also bezier curve support), not necessarily x-monotone, and it might intersect the grid also along whole edges.
My first thought was to call CGAL::compute_subcurves(..) with the grid lines and the curve I'm adding. I was hoping to get back a list of polylines, each composed of maximal multiple segments inside a face of the original grid. In practice even if the input is composed of polylines and the output of monotone polylines, I get back a list of separated segments. These include also the grid segments and also the polyline segments, and these are not ordered by "walking on the curve segments" as needed to compute the ordered interesection points. If they would have been ordered, a solution would be to iteratively go over them and check which one intersects the original grid, and then save the points.
Another option I thought of is to start with an arrangement of the grid lines, incrementally add polyline segements and have a notification mechanism notifying me on new edges that are pairwise disjoint in their interior, but in the case an edge of the intersected polylines is an original edge of the grid I won't get a notification and I'll miss it. Incrementally adding segments and checking for collisions also doesn't seem to be straightforward as the arrangement API do_intersect(..) seems to return at most a single point, while a given segment of the input polyline might easily intersect two grid lines next to a corner or even lie entirely on a grid segment.
I'm probably missing some simple solution. Can someone give me a pointer, or some api call that might help here?
Edit: There might have been a confusion. The grid is orthogonal but not necessarily regular and might have coordinates that could not globally scale to integers such as here.
Use Arrangement_with_history_2 (instead of Arrangement_2); see https://doc.cgal.org/latest/Arrangement_on_surface_2/classCGAL_1_1Arrangement__with__history__2.html. After you compute the arrangement, you can use point location to locate the end points of your polylines in the arrangement. Then, for each one, you can easily follow the original curve. If you are concerned with performance, you can try inserting (at least) the grid lines incrementally. Another option is to extend the halfedge records and insert the grid lines and each polyline separately. With the appropriate observer, you can mark the generated halfedges that correspond to a given polyline uniquely. I think you can even save the extra point location, by locating one of the two end points of a polyline before inserting it, and then provide the resulting location to the (incremental) insertion function.
I've been working on a computational geometry problem and ran across the following problem (which is needed as a subroutine) but failed to find any good references or algorithms.
Given a simple (possibly concave) polygon P, the goal is to compute the center and radius of the smallest circle which is completely contained in P (empty circle) but touches the polygon in at least two places (point or edge). If the two "places" happen to be points of the polygon then there are no constraints. Also no constraints if we hit a point and an edge. But if we hit two edges then they should not be consecutive (assuming clockwise or counter-clockwise order).
I am aiming for an implementable algorithm running in order of n^3 or better. Any pointers, references, or ideas would be very helpful.
Thanks!
Amer
Since you're just looking for pointers or ideas, I'll be brief. The Medial Axis of a polygon is set of centers of the circles that touch the boundary in two or more locations (https://en.wikipedia.org/wiki/Topological_skeleton#Centers_of_bi-tangent_circles). Also known as a skeleton, the medial axis consists of a tree-like graph made of lines and parabolas. If you check the circles at the vertices of this graph (ignoring the graph vertices that coincide with polygon vertices), you can find both the largest and smallest circles. You'll have to fine tune to accommodate your "no consecutive edges" requirement.
Given a 3d solid box with points in it. Given a box meshed with tetraheda. The dimensions of both boxes are the same.
I need to find an algorithm, that maps points of the solid to respective tetrahedra in the mesh.
I used the next algorithm:
Refine solid with an octree
Iterate over tetrahedra in the mesh and check if it intersects with a branch or a leave of the octree. (Ratschek & Rockne's algorithm)
If it intersects, map the points from the octree to the tetrahedron.
But the algorithm is very slow, moreover I have huge problems checking the intersection between a box and a tetrahedron.
I could still stick with an octree, but I definitely need something reasonable to check the intersections. Any comment will be highly appreciated.
UPDATE: I have 2 million solid points and 200k tetrahedra
UPDATE 2: I am trying to implement Walking in a triangulation
One standard simplification would be to first compute approximate octree-tetrahedron intersections using axis-aligned bounding boxes. The resulting intersection tests are then very simple.
Then, once you've traversed to the leaf level of the tree, you can use an exact test to determine which points are contained within a given tetrahedron.
To summarise:
Form an octree T for your points X
for (all tetrahedrons ti in mesh M)
Form a minimal axis-aligned bounding-box Bi for tetrahedron ti
Traverse T from root, accumulating a list Li of all leaf nodes
that overlap with box Bi
for (all leaf nodes li in list L)
for (all points pi in leaf node li)
if (point pi is inside tetrahedron ti /*exact test*/ )
Associate point pi with tetrahedron ti
endif
endfor
endfor
endfor
This algorithm is efficient if: (i) the points X are well distributed within the mesh M, and (ii) the tetrahedrons in M have reasonable aspect ratios.
The key to achieving good performance is to ensure that the tree-traversal step is implemented as efficiently as possible.
A point-in-tetrahedron test can be done by checking whether a given point pi lies on the "inner" side of the 4 faces of a tetrahedron. Given a tetrahedron [i,j,k,l], the point pi is on the "inner" side of the face [i,j,k] if it lies on the same side of the plane [i,j,k] as the "opposing" vertex l.
These orientation tests can be performed robustly using adaptive precision arithmetic. Jonathan Shewchuk offers such an implementation here.
Assuming you know the vertices of the tetrahedrons, you can check if a point is inside a tetrahedron, by checking if it lies to the left or rightside of each of its planes, say left is the side pointed along the normal.
The math for determining if a point is to the left or right of a plane is straight forward.
There's another method I found, but looks like a variant of my answer.
Of course, if a point is inside a tet, it gets mapped to the tet. This method can be implemented as a vertex shader or as a OpenCL/CUDA kernel, and that'll make it highly parallel.
Is there a computationally efficient way to determine the points of intersection of a straight line with all the edges of a given Voronoi tessellation in a rectangular plane area?
Thanks
Once you have your first intersection point, the rest is easy.
Prepare a database of edges: for each edge, list both polygons it belongs to, or say it is the outer edge (and so belongs to one polygon only). In your picture, the lower side of the rectangle would contain 4 edges of 4 different polygons.
Draw your line, find your first intersection point ([0, 0.25] in your picture, not circled). Say it's polygon A. Then the next intersection point (the lowest one circled in your picture) also belongs to A. You find the relevant edge with a binary search through the list of edges of A.
Now you have found the second edge of A, find out which other polygon it belongs to. Then use binary search to find which other edge of that other polygon the line intersects. And so on until you exit your rectangle.