From ab3693fb04c8880fcb352f4cb23ed0eb6c13653f Mon Sep 17 00:00:00 2001 From: "SND\\wo80_cp" Date: Tue, 9 May 2017 09:18:28 +0000 Subject: [PATCH] Minor updates. git-svn-id: https://triangle.svn.codeplex.com/svn@79801 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5 --- Triangle.NET/Triangle/Geometry/Rectangle.cs | 2 +- .../Triangle/Tools/IntersectionHelper.cs | 47 ++++++-- Triangle.NET/Triangle/Tools/QualityMeasure.cs | 3 - Triangle.NET/Triangle/Tools/Statistic.cs | 86 +++++++++++++- .../Triangle/Voronoi/Legacy/SimpleVoronoi.cs | 105 +++--------------- 5 files changed, 138 insertions(+), 105 deletions(-) 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)); }