Changed IPolygon interface;

Fix #10971

git-svn-id: https://triangle.svn.codeplex.com/svn@77342 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5
This commit is contained in:
SND\wo80_cp
2015-09-27 20:19:51 +00:00
parent 66522893b0
commit 14ee9120bd
6 changed files with 250 additions and 81 deletions
+60 -28
View File
@@ -8,33 +8,72 @@ namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
public class Contour
{
int marker;
bool convex;
/// <summary>
/// Gets or sets the list of points making up the contour.
/// </summary>
public List<Vertex> Points { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="Contour" /> class.
/// </summary>
public Contour(IEnumerable<Vertex> points, int marker)
/// <param name="points">The points that make up the contour.</param>
public Contour(IEnumerable<Vertex> points)
: this(points, 0, false)
{
this.Points = new List<Vertex>(points);
int count = Points.Count;
// Check if first vertex equals last vertex.
if (Points[0] == Points[count - 1])
{
count--;
Points.RemoveAt(count);
}
this.marker = marker;
}
public Point FindInteriorPoint(bool convex)
/// <summary>
/// Initializes a new instance of the <see cref="Contour" /> class.
/// </summary>
/// <param name="points">The points that make up the contour.</param>
/// <param name="marker">Contour marker.</param>
public Contour(IEnumerable<Vertex> points, int marker)
: this(points, marker, false)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Contour" /> class.
/// </summary>
/// <param name="points">The points that make up the contour.</param>
/// <param name="marker">Contour marker.</param>
/// <param name="convex">The hole is convex.</param>
public Contour(IEnumerable<Vertex> points, int marker, bool convex)
{
AddPoints(points);
this.marker = marker;
this.convex = convex;
}
public List<ISegment> GetSegments()
{
var segments = new List<ISegment>();
var p = this.Points;
int count = p.Count - 1;
for (int i = 0; i < count; i++)
{
// Add segments to polygon.
segments.Add(new Segment(p[i], p[i + 1], marker));
}
// Close the contour.
segments.Add(new Segment(p[count], p[0], marker));
return segments;
}
public Point FindInteriorPoint()
{
if (convex)
{
@@ -58,24 +97,17 @@ namespace TriangleNet.Geometry
return FindPointInPolygon(this.Points);
}
public List<ISegment> GetSegments()
private void AddPoints(IEnumerable<Vertex> points)
{
var segments = new List<ISegment>();
this.Points = new List<Vertex>(points);
var p = this.Points;
int count = Points.Count - 1;
int count = p.Count - 1;
for (int i = 0; i < count; i++)
// Check if first vertex equals last vertex.
if (Points[0] == Points[count])
{
// Add segments to polygon.
segments.Add(new Segment(p[i], p[i + 1], marker));
Points.RemoveAt(count);
}
// Close the contour.
segments.Add(new Segment(p[count], p[0], marker));
return segments;
}
private static Point FindPointInPolygon(List<Vertex> contour)
+43 -14
View File
@@ -6,8 +6,8 @@
namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
using TriangleNet.Topology;
/// <summary>
/// Polygon interface.
@@ -44,21 +44,10 @@ namespace TriangleNet.Geometry
/// </summary>
bool HasSegmentMarkers { get; set; }
/// <summary>
/// Adds a contour to the polygon.
/// </summary>
/// <param name="points">Points making up the contour.</param>
/// <param name="marker">Contour marker.</param>
/// <param name="hole">Treat contour as a hole (interior boundary).</param>
/// <param name="convex">The hole is convex.</param>
[Obsolete("Use polygon.Add(contour) method instead.")]
void AddContour(IEnumerable<Vertex> points, int marker, bool hole, bool convex);
/// <summary>
/// Adds a contour to the polygon.
/// </summary>
/// <param name="points">Points making up the contour.</param>
/// <param name="marker">Contour marker.</param>
/// <param name="hole">Point inside the contour, making it a hole.</param>
[Obsolete("Use polygon.Add(contour) method instead.")]
void AddContour(IEnumerable<Vertex> points, int marker, Point hole);
/// <summary>
@@ -66,5 +55,45 @@ namespace TriangleNet.Geometry
/// </summary>
/// <returns>Rectangle defining an axis-aligned bounding box.</returns>
Rectangle Bounds();
/// <summary>
/// Add a vertex to the polygon.
/// </summary>
/// <param name="vertex">The vertex to insert.</param>
void Add(Vertex vertex);
/// <summary>
/// Add a segment to the polygon.
/// </summary>
/// <param name="segment">The segment to insert.</param>
void Add(ISegment segment);
/// <summary>
/// Add a segment to the polygon.
/// </summary>
/// <param name="segment">The segment to insert.</param>
/// <param name="insert">If true, both endpoints will be added to the points list.</param>
void Add(ISegment segment, bool insert);
/// <summary>
/// Add a segment to the polygon.
/// </summary>
/// <param name="segment">The segment to insert.</param>
/// <param name="index">The index of the segment endpoint to add to the points list (must be 0 or 1).</param>
void Add(ISegment segment, int index);
/// <summary>
/// Add a contour to the polygon.
/// </summary>
/// <param name="contour">The contour to insert.</param>
/// <param name="hole">Treat contour as a hole.</param>
void Add(Contour contour, bool hole = false);
/// <summary>
/// Add a contour to the polygon.
/// </summary>
/// <param name="contour">The contour to insert.</param>
/// <param name="hole">Point inside the contour, making it a hole.</param>
void Add(Contour contour, Point hole);
}
}
+73 -28
View File
@@ -8,7 +8,6 @@ namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
using TriangleNet.Topology;
/// <summary>
/// A polygon represented as a planar straight line graph.
@@ -21,37 +20,37 @@ namespace TriangleNet.Geometry
List<ISegment> segments;
/// <inherit />
/// <inheritdoc />
public List<Vertex> Points
{
get { return points; }
}
/// <inherit />
/// <inheritdoc />
public List<Point> Holes
{
get { return holes; }
}
/// <inherit />
/// <inheritdoc />
public List<RegionPointer> Regions
{
get { return regions; }
}
/// <inherit />
/// <inheritdoc />
public List<ISegment> Segments
{
get { return segments; }
}
/// <inherit />
/// <inheritdoc />
public bool HasPointMarkers { get; set; }
/// <inherit />
/// <inheritdoc />
public bool HasSegmentMarkers { get; set; }
/// <inherit />
/// <inheritdoc />
public int Count
{
get { return points.Count; }
@@ -91,35 +90,20 @@ namespace TriangleNet.Geometry
HasSegmentMarkers = markers;
}
/// <inherit />
[Obsolete("Use polygon.Add(contour) method instead.")]
public void AddContour(IEnumerable<Vertex> points, int marker = 0,
bool hole = false, bool convex = false)
{
var c = new Contour(points, marker);
this.points.AddRange(c.Points);
this.segments.AddRange(c.GetSegments());
if (hole)
{
this.holes.Add(c.FindInteriorPoint(convex));
}
this.Add(new Contour(points, marker, convex), hole);
}
/// <inherit />
[Obsolete("Use polygon.Add(contour) method instead.")]
public void AddContour(IEnumerable<Vertex> points, int marker, Point hole)
{
var c = new Contour(points, marker);
this.points.AddRange(c.Points);
this.segments.AddRange(c.GetSegments());
this.holes.Add(hole);
this.Add(new Contour(points, marker), hole);
}
/// <inherit />
/// <inheritdoc />
public Rectangle Bounds()
{
var bounds = new Rectangle();
@@ -131,6 +115,7 @@ namespace TriangleNet.Geometry
/// <summary>
/// Add a vertex to the polygon.
/// </summary>
/// <param name="vertex">The vertex to insert.</param>
public void Add(Vertex vertex)
{
this.points.Add(vertex);
@@ -139,9 +124,69 @@ namespace TriangleNet.Geometry
/// <summary>
/// Add a segment to the polygon.
/// </summary>
/// <param name="segment">The segment to insert.</param>
public void Add(ISegment segment)
{
this.segments.Add(segment);
}
/// <summary>
/// Add a segment to the polygon.
/// </summary>
/// <param name="segment">The segment to insert.</param>
/// <param name="insert">If true, both endpoints will be added to the points list.</param>
public void Add(ISegment segment, bool insert)
{
this.segments.Add(segment);
if (insert)
{
this.points.Add(segment.GetVertex(0));
this.points.Add(segment.GetVertex(1));
}
}
/// <summary>
/// Add a segment to the polygon.
/// </summary>
/// <param name="segment">The segment to insert.</param>
/// <param name="index">The index of the segment endpoint to add to the points list (must be 0 or 1).</param>
public void Add(ISegment segment, int index)
{
this.segments.Add(segment);
this.points.Add(segment.GetVertex(index));
}
/// <summary>
/// Add a contour to the polygon.
/// </summary>
/// <param name="contour">The contour to insert.</param>
/// <param name="hole">Treat contour as a hole.</param>
public void Add(Contour contour, bool hole = false)
{
if (hole)
{
this.Add(contour, contour.FindInteriorPoint());
}
else
{
this.points.AddRange(contour.Points);
this.segments.AddRange(contour.GetSegments());
}
}
/// <summary>
/// Add a contour to the polygon.
/// </summary>
/// <param name="contour">The contour to insert.</param>
/// <param name="hole">Point inside the contour, making it a hole.</param>
public void Add(Contour contour, Point hole)
{
this.points.AddRange(contour.Points);
this.segments.AddRange(contour.GetSegments());
this.holes.Add(hole);
}
}
}
+9
View File
@@ -884,6 +884,15 @@ namespace TriangleNet
// The insertion is successful by default, unless an encroached
// subsegment is found.
success = InsertVertexResult.Successful;
if (newvertex.tri.tri != null)
{
// Store the coordinates of the triangle that contains newvertex.
newvertex.tri.SetOrg(rightvertex);
newvertex.tri.SetDest(leftvertex);
newvertex.tri.SetApex(botvertex);
}
// Circle around the newly inserted vertex, checking each edge opposite it
// for the Delaunay property. Non-Delaunay edges are flipped. 'horiz' is
// always the edge being checked. 'first' marks where to stop circling.
+62 -8
View File
@@ -30,6 +30,10 @@ namespace TriangleNet.Meshing
ILog<LogItem> logger;
// Stores the vertices of the triangle that contains newvertex
// in SplitTriangle method.
Triangle newvertex_tri;
public QualityMesher(Mesh mesh, IPredicates predicates)
{
logger = Log.Instance;
@@ -43,6 +47,8 @@ namespace TriangleNet.Meshing
this.behavior = mesh.behavior;
newLocation = new NewLocation(mesh, predicates);
newvertex_tri = new Triangle();
}
/// <summary>
@@ -683,6 +689,54 @@ namespace TriangleNet.Meshing
}
}
/// <summary>
/// Linear interpolation of vertex attributes.
/// </summary>
/// <param name="newvertex"></param>
private void InterpolateAttribs(Vertex newvertex)
{
Vertex org = newvertex_tri.vertices[0];
Vertex dest = newvertex_tri.vertices[1];
Vertex apex = newvertex_tri.vertices[2];
double xdo, ydo, xao, yao;
double denominator;
double dx, dy;
double xi, eta;
int nextras = mesh.nextras;
// Compute the circumcenter of the triangle.
xdo = dest.x - org.x;
ydo = dest.y - org.y;
xao = apex.x - org.x;
yao = apex.y - org.y;
denominator = 0.5 / (xdo * yao - xao * ydo);
//dx = (yao * dodist - ydo * aodist) * denominator;
//dy = (xdo * aodist - xao * dodist) * denominator;
dx = newvertex.x - org.x;
dy = newvertex.y - org.y;
// To interpolate vertex attributes for the new vertex inserted at
// the circumcenter, define a coordinate system with a xi-axis,
// directed from the triangle's origin to its destination, and
// an eta-axis, directed from its origin to its apex.
// Calculate the xi and eta coordinates of the circumcenter.
xi = (yao * dx - xao * dy) * (2.0 * denominator);
eta = (xdo * dy - ydo * dx) * (2.0 * denominator);
for (int i = 0; i < nextras; i++)
{
// Interpolate the vertex attributes.
newvertex.attributes[i] = org.attributes[i]
+ xi * (dest.attributes[i] - org.attributes[i])
+ eta * (apex.attributes[i] - org.attributes[i]);
}
}
/// <summary>
/// Inserts a vertex at the circumcenter of a triangle. Deletes
/// the newly inserted vertex if it encroaches upon a segment.
@@ -742,14 +796,6 @@ namespace TriangleNet.Meshing
Vertex newvertex = new Vertex(newloc.x, newloc.y, 0, mesh.nextras);
newvertex.type = VertexType.FreeVertex;
for (int i = 0; i < mesh.nextras; i++)
{
// Interpolate the vertex attributes at the circumcenter.
newvertex.attributes[i] = borg.attributes[i]
+ xi * (bdest.attributes[i] - borg.attributes[i])
+ eta * (bapex.attributes[i] - borg.attributes[i]);
}
// Ensure that the handle 'badotri' does not represent the longest
// edge of the triangle. This ensures that the circumcenter must
// fall to the left of this edge, so point location will work.
@@ -762,6 +808,9 @@ namespace TriangleNet.Meshing
badotri.Lprev();
}
// Assign triangle for attributes interpolation.
newvertex.tri.tri = newvertex_tri;
// Insert the circumcenter, searching from the edge of the triangle,
// and maintain the Delaunay property of the triangulation.
Osub tmp = default(Osub);
@@ -772,6 +821,11 @@ namespace TriangleNet.Meshing
newvertex.hash = mesh.hash_vtx++;
newvertex.id = newvertex.hash;
if (mesh.nextras > 0)
{
InterpolateAttribs(newvertex);
}
mesh.vertices.Add(newvertex.hash, newvertex);
if (mesh.steinerleft > 0)
@@ -110,10 +110,10 @@ namespace TriangleNet.Smoothing
p = edge.Origin;
q = edge.Twin.Origin;
ai = p.X * q.Y - q.X * p.Y;
ai = p.x * q.y - q.x * p.y;
atmp += ai;
xtmp += (q.X + p.X) * ai;
ytmp += (q.Y + p.Y) * ai;
xtmp += (q.x + p.x) * ai;
ytmp += (q.y + p.y) * ai;
edge = edge.Next;