本文整理汇总了C#中TriangleNet.Data.Otri.Onext方法的典型用法代码示例。如果您正苦于以下问题:C# Otri.Onext方法的具体用法?C# Otri.Onext怎么用?C# Otri.Onext使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类TriangleNet.Data.Otri
的用法示例。
在下文中一共展示了Otri.Onext方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: TriangulatePolygon
/// <summary>
/// Find the Delaunay triangulation of a polygon that has a certain "nice" shape.
/// This includes the polygons that result from deletion of a vertex or insertion
/// of a segment.
/// </summary>
/// <param name="firstedge">The primary edge of the first triangle.</param>
/// <param name="lastedge">The primary edge of the last triangle.</param>
/// <param name="edgecount">The number of sides of the polygon, including its
/// base.</param>
/// <param name="doflip">A flag, wether to perform the last flip.</param>
/// <param name="triflaws">A flag that determines whether the new triangles should
/// be tested for quality, and enqueued if they are bad.</param>
/// <remarks>
// This is a conceptually difficult routine. The starting assumption is
// that we have a polygon with n sides. n - 1 of these sides are currently
// represented as edges in the mesh. One side, called the "base", need not
// be.
//
// Inside the polygon is a structure I call a "fan", consisting of n - 1
// triangles that share a common origin. For each of these triangles, the
// edge opposite the origin is one of the sides of the polygon. The
// primary edge of each triangle is the edge directed from the origin to
// the destination; note that this is not the same edge that is a side of
// the polygon. 'firstedge' is the primary edge of the first triangle.
// From there, the triangles follow in counterclockwise order about the
// polygon, until 'lastedge', the primary edge of the last triangle.
// 'firstedge' and 'lastedge' are probably connected to other triangles
// beyond the extremes of the fan, but their identity is not important, as
// long as the fan remains connected to them.
//
// Imagine the polygon oriented so that its base is at the bottom. This
// puts 'firstedge' on the far right, and 'lastedge' on the far left.
// The right vertex of the base is the destination of 'firstedge', and the
// left vertex of the base is the apex of 'lastedge'.
//
// The challenge now is to find the right sequence of edge flips to
// transform the fan into a Delaunay triangulation of the polygon. Each
// edge flip effectively removes one triangle from the fan, committing it
// to the polygon. The resulting polygon has one fewer edge. If 'doflip'
// is set, the final flip will be performed, resulting in a fan of one
// (useless?) triangle. If 'doflip' is not set, the final flip is not
// performed, resulting in a fan of two triangles, and an unfinished
// triangular polygon that is not yet filled out with a single triangle.
// On completion of the routine, 'lastedge' is the last remaining triangle,
// or the leftmost of the last two.
//
// Although the flips are performed in the order described above, the
// decisions about what flips to perform are made in precisely the reverse
// order. The recursive triangulatepolygon() procedure makes a decision,
// uses up to two recursive calls to triangulate the "subproblems"
// (polygons with fewer edges), and then performs an edge flip.
//
// The "decision" it makes is which vertex of the polygon should be
// connected to the base. This decision is made by testing every possible
// vertex. Once the best vertex is found, the two edges that connect this
// vertex to the base become the bases for two smaller polygons. These
// are triangulated recursively. Unfortunately, this approach can take
// O(n^2) time not only in the worst case, but in many common cases. It's
// rarely a big deal for vertex deletion, where n is rarely larger than
// ten, but it could be a big deal for segment insertion, especially if
// there's a lot of long segments that each cut many triangles. I ought to
// code a faster algorithm some day.
/// </remarks>
private void TriangulatePolygon(Otri firstedge, Otri lastedge,
int edgecount, bool doflip, bool triflaws)
{
Otri testtri = default(Otri);
Otri besttri = default(Otri);
Otri tempedge = default(Otri);
Vertex leftbasevertex, rightbasevertex;
Vertex testvertex;
Vertex bestvertex;
int bestnumber = 1;
// Identify the base vertices.
leftbasevertex = lastedge.Apex();
rightbasevertex = firstedge.Dest();
// Find the best vertex to connect the base to.
firstedge.Onext(ref besttri);
bestvertex = besttri.Dest();
besttri.Copy(ref testtri);
for (int i = 2; i <= edgecount - 2; i++)
{
testtri.OnextSelf();
testvertex = testtri.Dest();
// Is this a better vertex?
if (Primitives.InCircle(leftbasevertex, rightbasevertex, bestvertex, testvertex) > 0.0)
{
testtri.Copy(ref besttri);
bestvertex = testvertex;
bestnumber = i;
}
}
if (bestnumber > 1)
{
// Recursively triangulate the smaller polygon on the right.
//.........这里部分代码省略.........
示例2: DeleteVertex
/// <summary>
/// Delete a vertex from a Delaunay triangulation, ensuring that the
/// triangulation remains Delaunay.
/// </summary>
/// <param name="deltri"></param>
/// <remarks>The origin of 'deltri' is deleted. The union of the triangles
/// adjacent to this vertex is a polygon, for which the Delaunay triangulation
/// is found. Two triangles are removed from the mesh.
///
/// Only interior vertices that do not lie on segments or boundaries
/// may be deleted.
/// </remarks>
internal void DeleteVertex(ref Otri deltri)
{
Otri countingtri = default(Otri);
Otri firstedge = default(Otri), lastedge = default(Otri);
Otri deltriright = default(Otri);
Otri lefttri = default(Otri), righttri = default(Otri);
Otri leftcasing = default(Otri), rightcasing = default(Otri);
Osub leftsubseg = default(Osub), rightsubseg = default(Osub);
Vertex delvertex;
Vertex neworg;
int edgecount;
delvertex = deltri.Org();
VertexDealloc(delvertex);
// Count the degree of the vertex being deleted.
deltri.Onext(ref countingtri);
edgecount = 1;
while (!deltri.Equal(countingtri))
{
edgecount++;
countingtri.OnextSelf();
}
if (edgecount > 3)
{
// Triangulate the polygon defined by the union of all triangles
// adjacent to the vertex being deleted. Check the quality of
// the resulting triangles.
deltri.Onext(ref firstedge);
deltri.Oprev(ref lastedge);
TriangulatePolygon(firstedge, lastedge, edgecount, false, behavior.NoBisect == 0);
}
// Splice out two triangles.
deltri.Lprev(ref deltriright);
deltri.Dnext(ref lefttri);
lefttri.Sym(ref leftcasing);
deltriright.Oprev(ref righttri);
righttri.Sym(ref rightcasing);
deltri.Bond(ref leftcasing);
deltriright.Bond(ref rightcasing);
lefttri.SegPivot(ref leftsubseg);
if (leftsubseg.seg != Mesh.dummysub)
{
deltri.SegBond(ref leftsubseg);
}
righttri.SegPivot(ref rightsubseg);
if (rightsubseg.seg != Mesh.dummysub)
{
deltriright.SegBond(ref rightsubseg);
}
// Set the new origin of 'deltri' and check its quality.
neworg = lefttri.Org();
deltri.SetOrg(neworg);
if (behavior.NoBisect == 0)
{
quality.TestTriangle(ref deltri);
}
// Delete the two spliced-out triangles.
TriangleDealloc(lefttri.triangle);
TriangleDealloc(righttri.triangle);
}
示例3: FindDirection
/// <summary>
/// Find the first triangle on the path from one point to another.
/// </summary>
/// <param name="searchtri"></param>
/// <param name="searchpoint"></param>
/// <returns>
/// The return value notes whether the destination or apex of the found
/// triangle is collinear with the two points in question.</returns>
/// <remarks>
/// Finds the triangle that intersects a line segment drawn from the
/// origin of 'searchtri' to the point 'searchpoint', and returns the result
/// in 'searchtri'. The origin of 'searchtri' does not change, even though
/// the triangle returned may differ from the one passed in. This routine
/// is used to find the direction to move in to get from one point to
/// another.
/// </remarks>
private FindDirectionResult FindDirection(ref Otri searchtri, Vertex searchpoint)
{
Otri checktri = default(Otri);
Vertex startvertex;
Vertex leftvertex, rightvertex;
double leftccw, rightccw;
bool leftflag, rightflag;
startvertex = searchtri.Org();
rightvertex = searchtri.Dest();
leftvertex = searchtri.Apex();
// Is 'searchpoint' to the left?
leftccw = Primitives.CounterClockwise(searchpoint, startvertex, leftvertex);
leftflag = leftccw > 0.0;
// Is 'searchpoint' to the right?
rightccw = Primitives.CounterClockwise(startvertex, searchpoint, rightvertex);
rightflag = rightccw > 0.0;
if (leftflag && rightflag)
{
// 'searchtri' faces directly away from 'searchpoint'. We could go left
// or right. Ask whether it's a triangle or a boundary on the left.
searchtri.Onext(ref checktri);
if (checktri.triangle == Mesh.dummytri)
{
leftflag = false;
}
else
{
rightflag = false;
}
}
while (leftflag)
{
// Turn left until satisfied.
searchtri.OnextSelf();
if (searchtri.triangle == Mesh.dummytri)
{
logger.Error("Unable to find a triangle on path.", "Mesh.FindDirection().1");
throw new Exception("Unable to find a triangle on path.");
}
leftvertex = searchtri.Apex();
rightccw = leftccw;
leftccw = Primitives.CounterClockwise(searchpoint, startvertex, leftvertex);
leftflag = leftccw > 0.0;
}
while (rightflag)
{
// Turn right until satisfied.
searchtri.OprevSelf();
if (searchtri.triangle == Mesh.dummytri)
{
logger.Error("Unable to find a triangle on path.", "Mesh.FindDirection().2");
throw new Exception("Unable to find a triangle on path.");
}
rightvertex = searchtri.Dest();
leftccw = rightccw;
rightccw = Primitives.CounterClockwise(startvertex, searchpoint, rightvertex);
rightflag = rightccw > 0.0;
}
if (leftccw == 0.0)
{
return FindDirectionResult.Leftcollinear;
}
else if (rightccw == 0.0)
{
return FindDirectionResult.Rightcollinear;
}
else
{
return FindDirectionResult.Within;
}
}