在一个给定范围(也就是,一个线段的集合和既不是线段交点也不是线段的端点的自由点)内我们可以迭代地用一条“捷径”线段替代邻近的线段进行简化(例如:用线段pr代替pq和qr线段)并且给定条件如下:
顶点的度q为2(例如:只有pq和qr有点q)。
线段pr不在集合范围内。
三角形pqr(不是位于p和r之间)。按照定义来说pq和qr上没有其他的点。
测试3——对于占位点(也就是在三角形PQR内或其边上的点)测试——是关键。如果PQR内有多余的点,那么就会产生一些岛型几何图形(或自由顶点)并且再简化之后就会出现在pqr不正确的那边,或者,几何图形与pr外的部分“连接”且pr会与图中线段相交。这两种情况下都不应该对网格进行简化。
鉴于此,我们可以构建一个迭代算法简化网格:把每个通过这些测试的基础后的顶点放到一个队列,测试基于移除该点会导致错误的原理。移除第一个顶点,基于变化的误差度量重新排列相邻顶点。请注意,如果其中的"占位点"从测试3此前已移除,一个以前被"困"的顶点现在可能是可移除的了。
Mesh Simplification Part II - Arrangement Simplification
In my previous post, I suggested that we can iteratively simplify an arrangement if we can test a node‘s degree, the pre-existence of the simplifying edge we want to replace it with, and confirm that there are no "squatting" vertices inside the triangle formed
by the two old edges and the one new one.
To simplify an arrangement, therefore, what we really need is a good spatial index to make searching for squatters fast.
Previously I had used a quadtree-like structure, but I seem to be getting better results using a Delaunay triangulation. (This idea is based on the CGAL point_set_2 class).
We insert every vertex of our arrangement into a Delaunay triangulation.
When we want to check for squatters, we find the minimum circle enclosing the triangle pqr (where pqr is the curve pair we want to simplify to pr) and search the triangulation for nodes inside the circle.
To search the Delaunay triangulation for nodes within a fixed distance of point P, we first insert P (if it isn‘t already present) and then do a search (depth or breadth-search) from P outward based on vertex adjacency. When done, we remove P if it wasn‘t already
part of the triangulation.
Implementation Details
For my implementation using arrangements, there are a few quirks:
I use my own point set; CGAL‘s point set uses a stack-based depth-first search that tends to flood the stack for large data sets.
I do not re-queue previously "blocked" points as squatters are removed. This would be a nice feature to add at some point (but is not easily added with a mere index).
I abuse CGAL‘s "merge_edge" routine to do the simplification. Edge merge was meant for collinear curves; in my case I pre-ensure that it is a safe operation. The advantage of using merge_edge vs. actually inserting the new edges and removing the old ones is
speed and stability: no faces are created or removed, thus face data stays stable, and no geometry tests are needed to determine what holes go in what face, etc.
Because I am edge-merging, I can‘t merge two edges that have opposite x-monotone "direction" - thus some details won‘t get simplified. This is a limitation of CGAL‘s arrangement interface.
Here‘s why the last point happens: CGAL caches the "direction" (left to right or right to left) of its X-Monotone curves on the half-edge itself. Since merge assumes that we aren‘t moving the point-set that is the curve, but rather glue-ing two curves together
in-place, it assumes that the merged half-edge direction cannot have changed. Thus it does not recalculate the direction flag.
Since the method recycles two of the four half-edges in the merge, if the first half of the curve points in the opposite direction of the merged curve, the merge is changing the half-edge‘s direction.
Could this case happen if the merged edge had the same path as the original two edges? No. In order for the direction to change, the two underlying curves cannot be summed to a single curve that is still x-monotone, which is a requirement for CGAL‘s arrangement.
Mesh Simplification Part III - Simplifying A Triangulation
Previously I suggested using a Delaunay triangulation as a spatial index to find "squatters" when simplifying an arrangement. If we want to simplify a triangulation itself, then the triangulation is the spatial index.
Consider a constrained Delaunay triangulation, where our arrangement edges have been replaced with triangulation constraints, and there are no free vertices (nor are there vertices in the triangulation that don‘t have at least one incident constraint).
We can now use an idea from the previously referenced paper: given a pair of constraints forming a curve pqr that we want to simplify into pr, if there exist any vertices that might be on the edge or in the interior of triangle pqr, then they must be adjacent
to q in the triangulation (and between pq and pr on the accute side of pqr).
This means that we can simply circulate vertex q to search for squatters. The triangulation is the index.
Why does this work? Well, consider the case where there exists a vertex X inside triangle PQR that is not adjacent to Q. You can‘t have free vertices in a triangulation; the act of triangulating out X is going to create at least one link between Q and X; the
only way that this will not happen is if there is already some other point inside PQR that is closer to Q than X (and in that case, we fail for that other point).
The triangulation also has the nice property that when we remove a vertex X, we can reconsider its adjacent vertices to see if X was a squatter of those other vertices. This works because if X is a squatter of Q and there are no other squatters (thus removing
X "unlocks" Q) then X and Q must be connected.
Implementation Notes
In my case I have one other implementation consideration besides the usual requirements: in my case, I have a many-to-many link between vertices in my original arrangement and vertices in my triangulation. Some triangulation vertices will not have original
nodes because they represent subdivision of the triangulation to improve elevation data. And some original arrangement vertices will not be in the triangulation due to simplification of the triangulation‘s constraints.
The problem is: how do we work backward from a triangulation triangle to an original arrangement face? Given a triangle with a constraint on one side, we need to figure out what arrangement halfedge(s) it links to.
In order to keep this "back-link" unambiguous, we cannot remove all of the degree 2 vertices from a poly-line of original edge segments. We need to leave at least one "poly-line interior" vertex in place to disambiguate two paths between vertices in the arrangement.
(This case happens a lot when we have closed loops.)
In practice, we could never remove the poly-line interior vertices from all paths anyway (because they would collapse to zero paths) but in practice, we don‘t want to remove them from any poly-line because it makes resolving the original arrangement face more
difficult.
原文地址:http://blog.csdn.net/giantchen547792075/article/details/24667567