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:
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user