Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/Routines2D.cs
===================================================================
diff -u -r1974 -r3079
--- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/Routines2D.cs (.../Routines2D.cs) (revision 1974)
+++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/Routines2D.cs (.../Routines2D.cs) (revision 3079)
@@ -21,6 +21,8 @@
using System;
using System.Collections.Generic;
+using System.Linq;
+using Deltares.DamEngine.Data.Standard;
namespace Deltares.DamEngine.Data.Geometry
{
@@ -63,6 +65,17 @@
}
///
+ /// Enum for the clockwise options
+ ///
+ public enum Clockwise
+ {
+ IsClockwise = 0,
+ AntiClockwise = 1,
+ NotEnoughUniquePoints = 2,
+ PointsOnLine = 3
+ }
+
+ ///
/// Static class Routines2D
///
public static class Routines2D
@@ -74,7 +87,7 @@
public double Z;
}
- private const double cEpsilon = 1.0e-4;
+ private const double CEpsilon = 1.0e-4;
///
/// Checks if the 2D Lines strictly intersect. Strictly means that the intersection point must be part of both lines so
@@ -99,12 +112,51 @@
double point3X, double point3Z, double point4X, double point4Z, out Point2D intersectionPoint)
{
return DetermineIf2DLinesIntersectStrickly(point1X, point1Z, point2X, point2Z, point3X, point3Z, point4X, point4Z,
- out intersectionPoint, cEpsilon);
+ out intersectionPoint, CEpsilon);
}
+ ///
+ /// Determines the point (aResultX, aResultY) on the line (aLine1X, aLine1Y, aLine2X, aLine2Y) with the
+ /// shortest possible distance to a point (aPointX, aPointY).
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void GetPointOnLineClosestTo(double aPointX, double aPointY, double aLine1X, double aLine1Y, double aLine2X, double aLine2Y, out double aResultX, out double aResultY)
+ {
+
+ var lAb = Compute2DDistance(aLine1X, aLine1Y, aLine2X, aLine2Y);
+ var lAc = Compute2DDistance(aLine1X, aLine1Y, aPointX, aPointY);
+ var lBc = Compute2DDistance(aLine2X, aLine2Y, aPointX, aPointY);
+ var lAClose = (Math.Pow(lAc, 2) - Math.Pow(lBc, 2) + Math.Pow(lAb, 2)) / (2 * lAb);
+ if (lAClose <= 0)
+ {
+ aResultX = aLine1X;
+ aResultY = aLine1Y;
+ }
+ else
+ {
+ if (lAClose >= lAb)
+ {
+ aResultX = aLine2X;
+ aResultY = aLine2Y;
+ }
+ else
+ {
+ aResultX = aLine1X + ((lAClose / lAb) * (aLine2X - aLine1X));
+ aResultY = aLine1Y + ((lAClose / lAb) * (aLine2Y - aLine1Y));
+ }
+ }
+ }
+
///
- /// Doeses the point exist in line.
+ /// Does the point exist in line.
///
/// The line point1 x.
/// The line point1 z.
@@ -164,6 +216,41 @@
}
///
+ /// To check if the points of the polygon are clock-wise
+ ///
+ ///
+ ///
+ public static Clockwise IsClockWise(IEnumerable aPolygon)
+ {
+ var distinctPoints = aPolygon.Distinct().ToArray();
+ if (distinctPoints.Length < 3)
+ {
+ return Clockwise.NotEnoughUniquePoints;
+ }
+
+ double sumClockwise = 0;
+ double clockwise;
+ for (int ii = 0; ii < distinctPoints.Length - 1; ii++)
+ {
+ clockwise = (distinctPoints[ii + 1].X - distinctPoints[ii].X) *
+ (distinctPoints[ii + 1].Z + distinctPoints[ii].Z);
+ sumClockwise += clockwise;
+ }
+ clockwise = (distinctPoints[0].X - distinctPoints[distinctPoints.Length - 1].X) *
+ (distinctPoints[0].Z + distinctPoints[distinctPoints.Length - 1].Z);
+
+ sumClockwise += clockwise;
+ var result = Math.Sign(sumClockwise);
+
+ if (result == 0)
+ {
+ return Clockwise.PointsOnLine;
+ }
+
+ return result > 0.0 ? Clockwise.IsClockwise : Clockwise.AntiClockwise;
+ }
+
+ ///
/// Find if points Ax,ay are between a boundary polygon.
///
/// The polygon.
@@ -321,8 +408,38 @@
return result;
}
-
///
+ /// Determines angle between 2 lines.
+ /// Clockwise Input: point1, commonpoint, point2, commonpoint, normalvect(ex <0,0,-1>), validate
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static double FindAngle(Point2D line1Point1, Point2D line1Point2, Point2D line2Point1,
+ Point2D line2Point2)
+ {
+ var x1 = line1Point2.X - line1Point1.X;
+ var z1 = line1Point2.Z - line1Point1.Z;
+
+ var x2 = line2Point2.X - line2Point1.X;
+ var z2 = line2Point2.Z - line2Point1.Z;
+
+ var angle1 = GeneralMathRoutines.RadianToDegree(Math.Atan2(z1, x1));
+ var angle2 = GeneralMathRoutines.RadianToDegree(Math.Atan2(z2, x2));
+
+ var angle = angle2 - angle1;
+
+ if (angle < 0)
+ {
+ angle += 360;
+ }
+
+ return angle;
+ }
+
+ ///
/// Checks if values are equal
///
///
@@ -382,7 +499,16 @@
}
- public static LineIntersection DetermineIf2DLinesIntersectWithExtrapolation(Point2D aPoint1, Point2D aPoint2, Point2D aPoint3, Point2D aPoint4, ref Point2D aIntersectionPoint)
+ ///
+ /// Determines the if 2D lines intersect using extrapolation when needed.
+ ///
+ /// a point1.
+ /// a point2.
+ /// a point3.
+ /// a point4.
+ /// a intersection point.
+ ///
+ public static LineIntersection DetermineIf2DLinesIntersectWithExtrapolation(Point2D aPoint1, Point2D aPoint2, Point2D aPoint3, Point2D aPoint4, out Point2D aIntersectionPoint)
{
var lLineConstant1 = CalculateNormalLineConstants(aPoint1.X, aPoint1.Z, aPoint2.X, aPoint2.Z);
var lLineConstant2 = CalculateNormalLineConstants(aPoint3.X, aPoint3.Z, aPoint4.X, aPoint4.Z);
@@ -412,7 +538,7 @@
var lB2 = aLine2Constant.Y;
var lC2 = aLine2Constant.Z;
- if (AreLinesParallel(lA1, lA2, lB1, lB2, cEpsilon))
+ if (AreLinesParallel(lA1, lA2, lB1, lB2, CEpsilon))
{
aIntersectionPoint = null;
return LineIntersection.Parallel;
@@ -594,7 +720,7 @@
{
double q = Math.Sqrt(pointX * pointX + pointY * pointY);
- if (q != 0)
+ if (!q.AlmostEquals(0, 1e-8))
{
pointX = pointX / q;
pointY = pointY / q;
@@ -610,7 +736,7 @@
/// The point2 z.
/// The tolerance.
///
- private static bool DetermineIfPointsCoincide(double point1X, double point1Z, double point2X, double point2Z, double tolerance)
+ public static bool DetermineIfPointsCoincide(double point1X, double point1Z, double point2X, double point2Z, double tolerance)
{
if ((Math.Abs(point1X - point2X)) < tolerance && Math.Abs(point1Z - point2Z) < tolerance)
{