⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alg-outline

📁 mesa-6.5-minigui源码
💻
字号:
/*** $Header: /cvs/mesa/Mesa/src/glu/sgi/libtess/alg-outline,v 1.1 2001/03/17 00:25:41 brianp Exp $*/This is only a very brief overview.  There is quite a bit ofadditional documentation in the source code itself.Goals of robust tesselation---------------------------The tesselation algorithm is fundamentally a 2D algorithm.  Weinitially project all data into a plane; our goal is to robustlytesselate the projected data.  The same topological tesselation isthen applied to the input data.Topologically, the output should always be a tesselation.  If theinput is even slightly non-planar, then some triangles willnecessarily be back-facing when viewed from some angles, but the goalis to minimize this effect.The algorithm needs some capability of cleaning up the input data aswell as the numerical errors in its own calculations.  One way to dothis is to specify a tolerance as defined above, and clean up theinput and output during the line sweep process.  At the very least,the algorithm must handle coincident vertices, vertices incident to anedge, and coincident edges.Phases of the algorithm-----------------------1. Find the polygon normal N.2. Project the vertex data onto a plane.  It does not need to be   perpendicular to the normal, eg. we can project onto the plane   perpendicular to the coordinate axis whose dot product with N   is largest.3. Using a line-sweep algorithm, partition the plane into x-monotone   regions.  Any vertical line intersects an x-monotone region in   at most one interval.4. Triangulate the x-monotone regions.5. Group the triangles into strips and fans.Finding the normal vector-------------------------A common way to find a polygon normal is to compute the signed areawhen the polygon is projected along the three coordinate axes.  Wecan't do this, since contours can have zero area without beingdegenerate (eg. a bowtie).We fit a plane to the vertex data, ignoring how they are connectedinto contours.  Ideally this would be a least-squares fit; however forour purpose the accuracy of the normal is not important.  Instead wefind three vertices which are widely separated, and compute the normalto the triangle they form.  The vertices are chosen so that thetriangle has an area at least 1/sqrt(3) times the largest area of anytriangle formed using the input vertices.  The contours do affect the orientation of the normal; after computingthe normal, we check that the sum of the signed contour areas isnon-negative, and reverse the normal if necessary.Projecting the vertices-----------------------We project the vertices onto a plane perpendicular to one of the threecoordinate axes.  This helps numerical accuracy by removing atransformation step between the original input data and the dataprocessed by the algorithm.  The projection also compresses the inputdata; the 2D distance between vertices after projection may be smallerthan the original 2D distance.  However by choosing the coordinateaxis whose dot product with the normal is greatest, the compressionfactor is at most 1/sqrt(3).Even though the *accuracy* of the normal is not that important (sincewe are projecting perpendicular to a coordinate axis anyway), the*robustness* of the computation is important.  For example, if thereare many vertices which lie almost along a line, and one vertex Vwhich is well-separated from the line, then our normal computationshould involve V otherwise the results will be garbage.The advantage of projecting perpendicular to the polygon normal isthat computed intersection points will be as close as possible totheir ideal locations.  To get this behavior, define TRUE_PROJECT.The Line Sweep--------------There are three data structures: the mesh, the event queue, and theedge dictionary.The mesh is a "quad-edge" data structure which records the topology ofthe current decomposition; for details see the include file "mesh.h".The event queue simply holds all vertices (both original and computedones), organized so that we can quickly extract the vertex with theminimum x-coord (and among those, the one with the minimum y-coord).The edge dictionary describes the current intersection of the sweepline with the regions of the polygon.  This is just an ordering of theedges which intersect the sweep line, sorted by their current order ofintersection.  For each pair of edges, we store some information aboutthe monotone region between them -- these are call "active regions"(since they are crossed by the current sweep line).The basic algorithm is to sweep from left to right, processing eachvertex.  The processed portion of the mesh (left of the sweep line) isa planar decomposition.  As we cross each vertex, we update the meshand the edge dictionary, then we check any newly adjacent pairs ofedges to see if they intersect.A vertex can have any number of edges.  Vertices with many edges canbe created as vertices are merged and intersection points arecomputed.  For unprocessed vertices (right of the sweep line), theseedges are in no particular order around the vertex; for processedvertices, the topological ordering should match the geometric ordering.The vertex processing happens in two phases: first we process are theleft-going edges (all these edges are currently in the edgedictionary).  This involves: - deleting the left-going edges from the dictionary; - relinking the mesh if necessary, so that the order of these edges around   the event vertex matches the order in the dictionary; - marking any terminated regions (regions which lie between two left-going   edges) as either "inside" or "outside" according to their winding number.When there are no left-going edges, and the event vertex is in an"interior" region, we need to add an edge (to split the region intomonotone pieces).  To do this we simply join the event vertex to therightmost left endpoint of the upper or lower edge of the containingregion.Then we process the right-going edges.  This involves: - inserting the edges in the edge dictionary; - computing the winding number of any newly created active regions.   We can compute this incrementally using the winding of each edge   that we cross as we walk through the dictionary. - relinking the mesh if necessary, so that the order of these edges around   the event vertex matches the order in the dictionary; - checking any newly adjacent edges for intersection and/or merging.If there are no right-going edges, again we need to add one to splitthe containing region into monotone pieces.  In our case it is mostconvenient to add an edge to the leftmost right endpoint of eithercontaining edge; however we may need to change this later (see thecode for details).Invariants----------These are the most important invariants maintained during the sweep.We define a function VertLeq(v1,v2) which defines the order in whichvertices cross the sweep line, and a function EdgeLeq(e1,e2; loc)which says whether e1 is below e2 at the sweep event location "loc".This function is defined only at sweep event locations which liebetween the rightmost left endpoint of {e1,e2}, and the leftmost rightendpoint of {e1,e2}.Invariants for the Edge Dictionary. - Each pair of adjacent edges e2=Succ(e1) satisfies EdgeLeq(e1,e2)   at any valid location of the sweep event. - If EdgeLeq(e2,e1) as well (at any valid sweep event), then e1 and e2   share a common endpoint. - For each e in the dictionary, e->Dst has been processed but not e->Org. - Each edge e satisfies VertLeq(e->Dst,event) && VertLeq(event,e->Org)   where "event" is the current sweep line event. - No edge e has zero length. - No two edges have identical left and right endpoints. Invariants for the Mesh (the processed portion). - The portion of the mesh left of the sweep line is a planar graph,   ie. there is *some* way to embed it in the plane. - No processed edge has zero length. - No two processed vertices have identical coordinates. - Each "inside" region is monotone, ie. can be broken into two chains   of monotonically increasing vertices according to VertLeq(v1,v2)   - a non-invariant: these chains may intersect (slightly) due to     numerical errors, but this does not affect the algorithm's operation.Invariants for the Sweep. - If a vertex has any left-going edges, then these must be in the edge   dictionary at the time the vertex is processed. - If an edge is marked "fixUpperEdge" (it is a temporary edge introduced   by ConnectRightVertex), then it is the only right-going edge from   its associated vertex.  (This says that these edges exist only   when it is necessary.)Robustness----------The key to the robustness of the algorithm is maintaining theinvariants above, especially the correct ordering of the edgedictionary.  We achieve this by:  1. Writing the numerical computations for maximum precision rather     than maximum speed.       2. Making no assumptions at all about the results of the edge     intersection calculations -- for sufficiently degenerate inputs,     the computed location is not much better than a random number.       3. When numerical errors violate the invariants, restore them     by making *topological* changes when necessary (ie. relinking     the mesh structure).          Triangulation and Grouping--------------------------We finish the line sweep before doing any triangulation.  This isbecause even after a monotone region is complete, there can be furtherchanges to its vertex data because of further vertex merging.After triangulating all monotone regions, we want to group thetriangles into fans and strips.  We do this using a greedy approach.The triangulation itself is not optimized to reduce the number ofprimitives; we just try to get a reasonable decomposition of thecomputed triangulation.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -