diff --git a/Triangle.NET/Triangle/Geometry/Contour.cs b/Triangle.NET/Triangle/Geometry/Contour.cs
index 7ddb23d..fe7e35c 100644
--- a/Triangle.NET/Triangle/Geometry/Contour.cs
+++ b/Triangle.NET/Triangle/Geometry/Contour.cs
@@ -8,33 +8,72 @@ namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
-
+
public class Contour
{
int marker;
+ bool convex;
+
+ ///
+ /// Gets or sets the list of points making up the contour.
+ ///
public List Points { get; set; }
///
/// Initializes a new instance of the class.
///
- public Contour(IEnumerable points, int marker)
+ /// The points that make up the contour.
+ public Contour(IEnumerable points)
+ : this(points, 0, false)
{
- this.Points = new List(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)
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The points that make up the contour.
+ /// Contour marker.
+ public Contour(IEnumerable points, int marker)
+ : this(points, marker, false)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The points that make up the contour.
+ /// Contour marker.
+ /// The hole is convex.
+ public Contour(IEnumerable points, int marker, bool convex)
+ {
+ AddPoints(points);
+
+ this.marker = marker;
+ this.convex = convex;
+ }
+
+ public List GetSegments()
+ {
+ var segments = new List();
+
+ 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 GetSegments()
+ private void AddPoints(IEnumerable points)
{
- var segments = new List();
+ this.Points = new List(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 contour)
diff --git a/Triangle.NET/Triangle/Geometry/IPolygon.cs b/Triangle.NET/Triangle/Geometry/IPolygon.cs
index 19475db..e420586 100644
--- a/Triangle.NET/Triangle/Geometry/IPolygon.cs
+++ b/Triangle.NET/Triangle/Geometry/IPolygon.cs
@@ -6,8 +6,8 @@
namespace TriangleNet.Geometry
{
+ using System;
using System.Collections.Generic;
- using TriangleNet.Topology;
///
/// Polygon interface.
@@ -44,21 +44,10 @@ namespace TriangleNet.Geometry
///
bool HasSegmentMarkers { get; set; }
- ///
- /// Adds a contour to the polygon.
- ///
- /// Points making up the contour.
- /// Contour marker.
- /// Treat contour as a hole (interior boundary).
- /// The hole is convex.
+ [Obsolete("Use polygon.Add(contour) method instead.")]
void AddContour(IEnumerable points, int marker, bool hole, bool convex);
- ///
- /// Adds a contour to the polygon.
- ///
- /// Points making up the contour.
- /// Contour marker.
- /// Point inside the contour, making it a hole.
+ [Obsolete("Use polygon.Add(contour) method instead.")]
void AddContour(IEnumerable points, int marker, Point hole);
///
@@ -66,5 +55,45 @@ namespace TriangleNet.Geometry
///
/// Rectangle defining an axis-aligned bounding box.
Rectangle Bounds();
+
+ ///
+ /// Add a vertex to the polygon.
+ ///
+ /// The vertex to insert.
+ void Add(Vertex vertex);
+
+ ///
+ /// Add a segment to the polygon.
+ ///
+ /// The segment to insert.
+ void Add(ISegment segment);
+
+ ///
+ /// Add a segment to the polygon.
+ ///
+ /// The segment to insert.
+ /// If true, both endpoints will be added to the points list.
+ void Add(ISegment segment, bool insert);
+
+ ///
+ /// Add a segment to the polygon.
+ ///
+ /// The segment to insert.
+ /// The index of the segment endpoint to add to the points list (must be 0 or 1).
+ void Add(ISegment segment, int index);
+
+ ///
+ /// Add a contour to the polygon.
+ ///
+ /// The contour to insert.
+ /// Treat contour as a hole.
+ void Add(Contour contour, bool hole = false);
+
+ ///
+ /// Add a contour to the polygon.
+ ///
+ /// The contour to insert.
+ /// Point inside the contour, making it a hole.
+ void Add(Contour contour, Point hole);
}
}
diff --git a/Triangle.NET/Triangle/Geometry/Polygon.cs b/Triangle.NET/Triangle/Geometry/Polygon.cs
index 3c2f955..82447ab 100644
--- a/Triangle.NET/Triangle/Geometry/Polygon.cs
+++ b/Triangle.NET/Triangle/Geometry/Polygon.cs
@@ -8,7 +8,6 @@ namespace TriangleNet.Geometry
{
using System;
using System.Collections.Generic;
- using TriangleNet.Topology;
///
/// A polygon represented as a planar straight line graph.
@@ -21,37 +20,37 @@ namespace TriangleNet.Geometry
List segments;
- ///
+ ///
public List Points
{
get { return points; }
}
- ///
+ ///
public List Holes
{
get { return holes; }
}
- ///
+ ///
public List Regions
{
get { return regions; }
}
- ///
+ ///
public List Segments
{
get { return segments; }
}
- ///
+ ///
public bool HasPointMarkers { get; set; }
- ///
+ ///
public bool HasSegmentMarkers { get; set; }
- ///
+ ///
public int Count
{
get { return points.Count; }
@@ -91,35 +90,20 @@ namespace TriangleNet.Geometry
HasSegmentMarkers = markers;
}
- ///
+ [Obsolete("Use polygon.Add(contour) method instead.")]
public void AddContour(IEnumerable 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);
}
- ///
+ [Obsolete("Use polygon.Add(contour) method instead.")]
public void AddContour(IEnumerable 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);
}
- ///
+ ///
public Rectangle Bounds()
{
var bounds = new Rectangle();
@@ -131,6 +115,7 @@ namespace TriangleNet.Geometry
///
/// Add a vertex to the polygon.
///
+ /// The vertex to insert.
public void Add(Vertex vertex)
{
this.points.Add(vertex);
@@ -139,9 +124,69 @@ namespace TriangleNet.Geometry
///
/// Add a segment to the polygon.
///
+ /// The segment to insert.
public void Add(ISegment segment)
{
this.segments.Add(segment);
}
+
+ ///
+ /// Add a segment to the polygon.
+ ///
+ /// The segment to insert.
+ /// If true, both endpoints will be added to the points list.
+ 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));
+ }
+ }
+
+ ///
+ /// Add a segment to the polygon.
+ ///
+ /// The segment to insert.
+ /// The index of the segment endpoint to add to the points list (must be 0 or 1).
+ public void Add(ISegment segment, int index)
+ {
+ this.segments.Add(segment);
+
+ this.points.Add(segment.GetVertex(index));
+ }
+
+ ///
+ /// Add a contour to the polygon.
+ ///
+ /// The contour to insert.
+ /// Treat contour as a hole.
+ 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());
+ }
+ }
+
+ ///
+ /// Add a contour to the polygon.
+ ///
+ /// The contour to insert.
+ /// Point inside the contour, making it a hole.
+ public void Add(Contour contour, Point hole)
+ {
+ this.points.AddRange(contour.Points);
+ this.segments.AddRange(contour.GetSegments());
+
+ this.holes.Add(hole);
+ }
}
}
diff --git a/Triangle.NET/Triangle/Mesh.cs b/Triangle.NET/Triangle/Mesh.cs
index 39a359b..8b1b46e 100644
--- a/Triangle.NET/Triangle/Mesh.cs
+++ b/Triangle.NET/Triangle/Mesh.cs
@@ -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.
diff --git a/Triangle.NET/Triangle/Meshing/QualityMesher.cs b/Triangle.NET/Triangle/Meshing/QualityMesher.cs
index d566463..4cb967b 100644
--- a/Triangle.NET/Triangle/Meshing/QualityMesher.cs
+++ b/Triangle.NET/Triangle/Meshing/QualityMesher.cs
@@ -30,6 +30,10 @@ namespace TriangleNet.Meshing
ILog 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();
}
///
@@ -683,6 +689,54 @@ namespace TriangleNet.Meshing
}
}
+ ///
+ /// Linear interpolation of vertex attributes.
+ ///
+ ///
+ 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]);
+ }
+ }
+
///
/// 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)
diff --git a/Triangle.NET/Triangle/Smoothing/SimpleSmoother.cs b/Triangle.NET/Triangle/Smoothing/SimpleSmoother.cs
index c47f4c5..67a4e9c 100644
--- a/Triangle.NET/Triangle/Smoothing/SimpleSmoother.cs
+++ b/Triangle.NET/Triangle/Smoothing/SimpleSmoother.cs
@@ -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;