Minor updates.
git-svn-id: https://triangle.svn.codeplex.com/svn@79801 0e2699bc-83d4-4a8f-98e7-55e24ab8c7a5
This commit is contained in:
@@ -95,7 +95,7 @@ namespace TriangleNet.Geometry
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scale bounds.
|
||||
/// Update bounds.
|
||||
/// </summary>
|
||||
/// <param name="dx">Add dx to left and right bounds.</param>
|
||||
/// <param name="dy">Add dy to top and bottom bounds.</param>
|
||||
|
||||
@@ -113,11 +113,42 @@ namespace TriangleNet.Tools
|
||||
/// <returns>Returns false, if startpoint is outside the box.</returns>
|
||||
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;
|
||||
/// <summary>
|
||||
/// Intersect a ray with a bounding box.
|
||||
/// </summary>
|
||||
/// <param name="rect">The clip rectangle.</param>
|
||||
/// <param name="p">The ray startpoint (inside the box).</param>
|
||||
/// <param name="dx">X direction.</param>
|
||||
/// <param name="dy">Y direction.</param>
|
||||
/// <returns>Returns false, if startpoint is outside the box.</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intersect a ray with a bounding box.
|
||||
/// </summary>
|
||||
/// <param name="rect">The clip rectangle.</param>
|
||||
/// <param name="p">The ray startpoint (inside the box).</param>
|
||||
/// <param name="dx">X direction.</param>
|
||||
/// <param name="dy">Y direction.</param>
|
||||
/// <param name="c">The intersection point.</param>
|
||||
/// <returns>Returns false, if startpoint is outside the box.</returns>
|
||||
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;
|
||||
|
||||
@@ -8,9 +8,6 @@
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Compute angle information for given triangle.
|
||||
/// </summary>
|
||||
/// <param name="triangle">The triangle to check.</param>
|
||||
/// <param name="data">Array of doubles (length 6).</param>
|
||||
/// <remarks>
|
||||
/// 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]))).
|
||||
/// </remarks>
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace TriangleNet.Voronoi.Legacy
|
||||
using System.Collections.Generic;
|
||||
using TriangleNet.Topology;
|
||||
using TriangleNet.Geometry;
|
||||
using TriangleNet.Tools;
|
||||
|
||||
/// <summary>
|
||||
/// 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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<IEdge> EnumerateEdges()
|
||||
@@ -353,25 +278,23 @@ namespace TriangleNet.Voronoi.Legacy
|
||||
var edges = new List<IEdge>(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));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user