diff --git a/Triangle.NET/Triangle/Geometry/Rectangle.cs b/Triangle.NET/Triangle/Geometry/Rectangle.cs
index 37df152..44ea007 100644
--- a/Triangle.NET/Triangle/Geometry/Rectangle.cs
+++ b/Triangle.NET/Triangle/Geometry/Rectangle.cs
@@ -95,7 +95,7 @@ namespace TriangleNet.Geometry
}
///
- /// Scale bounds.
+ /// Update bounds.
///
/// Add dx to left and right bounds.
/// Add dy to top and bottom bounds.
diff --git a/Triangle.NET/Triangle/Tools/IntersectionHelper.cs b/Triangle.NET/Triangle/Tools/IntersectionHelper.cs
index afb4aeb..fa70936 100644
--- a/Triangle.NET/Triangle/Tools/IntersectionHelper.cs
+++ b/Triangle.NET/Triangle/Tools/IntersectionHelper.cs
@@ -113,11 +113,42 @@ namespace TriangleNet.Tools
/// Returns false, if startpoint is outside the box.
public static bool BoxRayIntersection(Rectangle rect, Point p0, Point p1, ref Point c1)
{
- double x = p0.X;
- double y = p0.Y;
+ return BoxRayIntersection(rect, p0, p1.x - p0.x, p1.y - p0.y, ref c1);
+ }
- double dx = p1.x - x;
- double dy = p1.y - y;
+ ///
+ /// Intersect a ray with a bounding box.
+ ///
+ /// The clip rectangle.
+ /// The ray startpoint (inside the box).
+ /// X direction.
+ /// Y direction.
+ /// Returns false, if startpoint is outside the box.
+ public static Point BoxRayIntersection(Rectangle rect, Point p, double dx, double dy)
+ {
+ var intersection = new Point();
+
+ if (BoxRayIntersection(rect, p, dx, dy, ref intersection))
+ {
+ return intersection;
+ }
+
+ return null;
+ }
+
+ ///
+ /// Intersect a ray with a bounding box.
+ ///
+ /// The clip rectangle.
+ /// The ray startpoint (inside the box).
+ /// X direction.
+ /// Y direction.
+ /// The intersection point.
+ /// Returns false, if startpoint is outside the box.
+ public static bool BoxRayIntersection(Rectangle rect, Point p, double dx, double dy, ref Point c)
+ {
+ double x = p.X;
+ double y = p.Y;
double t1, x1, y1, t2, x2, y2;
@@ -179,13 +210,13 @@ namespace TriangleNet.Tools
if (t1 < t2)
{
- c1.x = x1;
- c1.y = y1;
+ c.x = x1;
+ c.y = y1;
}
else
{
- c1.x = x2;
- c1.y = y2;
+ c.x = x2;
+ c.y = y2;
}
return true;
diff --git a/Triangle.NET/Triangle/Tools/QualityMeasure.cs b/Triangle.NET/Triangle/Tools/QualityMeasure.cs
index 50abfe8..fc7bdc6 100644
--- a/Triangle.NET/Triangle/Tools/QualityMeasure.cs
+++ b/Triangle.NET/Triangle/Tools/QualityMeasure.cs
@@ -8,9 +8,6 @@
namespace TriangleNet.Tools
{
using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
using TriangleNet.Geometry;
///
diff --git a/Triangle.NET/Triangle/Tools/Statistic.cs b/Triangle.NET/Triangle/Tools/Statistic.cs
index 1f8c8a3..a530f8c 100644
--- a/Triangle.NET/Triangle/Tools/Statistic.cs
+++ b/Triangle.NET/Triangle/Tools/Statistic.cs
@@ -136,8 +136,8 @@ namespace TriangleNet.Tools
double[] ratiotable;
aspecttable = new int[16];
- ratiotable = new double[] {
- 1.5, 2.0, 2.5, 3.0, 4.0, 6.0, 10.0, 15.0, 25.0, 50.0,
+ ratiotable = new double[] {
+ 1.5, 2.0, 2.5, 3.0, 4.0, 6.0, 10.0, 15.0, 25.0, 50.0,
100.0, 300.0, 1000.0, 10000.0, 100000.0, 0.0 };
@@ -442,5 +442,87 @@ namespace TriangleNet.Tools
}
}
}
+
+ ///
+ /// Compute angle information for given triangle.
+ ///
+ /// The triangle to check.
+ /// Array of doubles (length 6).
+ ///
+ /// On return, the squared cosines of the minimum and maximum angle will
+ /// be stored at position data[0] and data[1] respectively.
+ /// If the triangle was obtuse, data[2] will be set to -1 and maximum angle
+ /// is computed as (pi - acos(sqrt(data[1]))).
+ ///
+ public static void ComputeAngles(ITriangle triangle, double[] data)
+ {
+ double min = 0.0;
+ double max = 1.0;
+
+ var va = triangle.GetVertex(0);
+ var vb = triangle.GetVertex(1);
+ var vc = triangle.GetVertex(2);
+
+ double dxa = vb.x - vc.x;
+ double dya = vb.y - vc.y;
+ double lena = dxa * dxa + dya * dya;
+
+ double dxb = vc.x - va.x;
+ double dyb = vc.y - va.y;
+ double lenb = dxb * dxb + dyb * dyb;
+
+ double dxc = va.x - vb.x;
+ double dyc = va.y - vb.y;
+ double lenc = dxc * dxc + dyc * dyc;
+
+ // Dot products.
+ double dota = data[0] = dxb * dxc + dyb * dyc;
+ double dotb = data[1] = dxc * dxa + dyc * dya;
+ double dotc = data[2] = dxa * dxb + dya * dyb;
+
+ // Squared cosines.
+ data[3] = (dota * dota) / (lenb * lenc);
+ data[4] = (dotb * dotb) / (lenc * lena);
+ data[5] = (dotc * dotc) / (lena * lenb);
+
+ // The sign of the dot product will tell us, if the angle is
+ // acute (value < 0) or obtuse (value > 0).
+
+ bool acute = true;
+
+ double cos, dot;
+
+ for (int i = 0; i < 3; i++)
+ {
+ dot = data[i];
+ cos = data[3 + i];
+
+ if (dot <= 0.0)
+ {
+ if (cos > min)
+ {
+ min = cos;
+ }
+
+ if (acute && (cos < max))
+ {
+ max = cos;
+ }
+ }
+ else
+ {
+ // Update max angle for (possibly non-acute) triangle
+ if (acute || (cos > max))
+ {
+ max = cos;
+ acute = false;
+ }
+ }
+ }
+
+ data[0] = min;
+ data[1] = max;
+ data[2] = acute ? 1.0 : -1.0;
+ }
}
}
diff --git a/Triangle.NET/Triangle/Voronoi/Legacy/SimpleVoronoi.cs b/Triangle.NET/Triangle/Voronoi/Legacy/SimpleVoronoi.cs
index c65ffa0..59375b5 100644
--- a/Triangle.NET/Triangle/Voronoi/Legacy/SimpleVoronoi.cs
+++ b/Triangle.NET/Triangle/Voronoi/Legacy/SimpleVoronoi.cs
@@ -11,6 +11,7 @@ namespace TriangleNet.Voronoi.Legacy
using System.Collections.Generic;
using TriangleNet.Topology;
using TriangleNet.Geometry;
+ using TriangleNet.Tools;
///
/// The Voronoi Diagram is the dual of a pointset triangulation.
@@ -131,7 +132,7 @@ namespace TriangleNet.Voronoi.Legacy
}
double ds = Math.Max(bounds.Width, bounds.Height);
- bounds.Resize(ds, ds);
+ bounds.Resize(ds / 10, ds / 10);
}
///
@@ -211,7 +212,7 @@ namespace TriangleNet.Voronoi.Legacy
{
torg = f.Org();
tapex = f.Apex();
- BoxRayIntersection(points[f.tri.id], torg.y - tapex.y, tapex.x - torg.x, out intersection);
+ intersection = IntersectionHelper.BoxRayIntersection(bounds, points[f.tri.id], torg.y - tapex.y, tapex.x - torg.x);
// Set the correct id for the vertex
intersection.id = n + rayIndex;
@@ -249,7 +250,7 @@ namespace TriangleNet.Voronoi.Legacy
torg = f.Org();
tdest = f.Dest();
- BoxRayIntersection(points[f.tri.id], tdest.y - torg.y, torg.x - tdest.x, out intersection);
+ intersection = IntersectionHelper.BoxRayIntersection(bounds, points[f.tri.id], tdest.y - torg.y, torg.x - tdest.x);
// Set the correct id for the vertex
intersection.id = n + rayIndex;
@@ -268,82 +269,6 @@ namespace TriangleNet.Voronoi.Legacy
region.Add(vpoints);
}
- private bool BoxRayIntersection(Point pt, double dx, double dy, out Point intersect)
- {
- double x = pt.x;
- double y = pt.y;
-
- double t1, x1, y1, t2, x2, y2;
-
- // Bounding box
- double minX = bounds.Left;
- double maxX = bounds.Right;
- double minY = bounds.Bottom;
- double maxY = bounds.Top;
-
- // Check if point is inside the bounds
- if (x < minX || x > maxX || y < minY || y > maxY)
- {
- intersect = null;
- return false;
- }
-
- // Calculate the cut through the vertical boundaries
- if (dx < 0)
- {
- // Line going to the left: intersect with x = minX
- t1 = (minX - x) / dx;
- x1 = minX;
- y1 = y + t1 * dy;
- }
- else if (dx > 0)
- {
- // Line going to the right: intersect with x = maxX
- t1 = (maxX - x) / dx;
- x1 = maxX;
- y1 = y + t1 * dy;
- }
- else
- {
- // Line going straight up or down: no intersection possible
- t1 = double.MaxValue;
- x1 = y1 = 0;
- }
-
- // Calculate the cut through upper and lower boundaries
- if (dy < 0)
- {
- // Line going downwards: intersect with y = minY
- t2 = (minY - y) / dy;
- x2 = x + t2 * dx;
- y2 = minY;
- }
- else if (dy > 0)
- {
- // Line going upwards: intersect with y = maxY
- t2 = (maxY - y) / dy;
- x2 = x + t2 * dx;
- y2 = maxY;
- }
- else
- {
- // Horizontal line: no intersection possible
- t2 = double.MaxValue;
- x2 = y2 = 0;
- }
-
- if (t1 < t2)
- {
- intersect = new Point(x1, y1);
- }
- else
- {
- intersect = new Point(x2, y2);
- }
-
- return true;
- }
-
// TODO: Voronoi enumerate edges
private IEnumerable EnumerateEdges()
@@ -353,25 +278,23 @@ namespace TriangleNet.Voronoi.Legacy
var edges = new List(this.Regions.Count * 2);
foreach (var region in this.Regions)
{
- first = null;
- last = null;
+ var ve = region.Vertices.GetEnumerator();
- foreach (var pt in region.Vertices)
+ ve.MoveNext();
+
+ first = last = ve.Current;
+
+ while (ve.MoveNext())
{
- if (first == null)
+ if (region.ID < region.GetNeighbor(last).ID)
{
- first = pt;
- last = pt;
+ edges.Add(new Edge(last.id, ve.Current.id));
}
- else
- {
- edges.Add(new Edge(last.id, pt.id));
- last = pt;
- }
+ last = ve.Current;
}
- if (region.Bounded && first != null)
+ if (region.Bounded && region.ID < region.GetNeighbor(last).ID)
{
edges.Add(new Edge(last.id, first.id));
}