Index: dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.UpliftLocationDeterminatorTests/Properties/AssemblyInfo.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.UpliftLocationDeterminatorTests/Properties/AssemblyInfo.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.UpliftLocationDeterminatorTests/Properties/AssemblyInfo.cs (revision 326) @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Deltares.DamPiping.UpliftLocationDeterminatorTests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Deltares.DamPiping.UpliftLocationDeterminatorTests")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("f6d70668-2cab-4d07-85b0-b4295d230a6a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Deltares.DamPiping.UpliftLocationDeterminator.csproj =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Deltares.DamPiping.UpliftLocationDeterminator.csproj (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Deltares.DamPiping.UpliftLocationDeterminator.csproj (revision 326) @@ -0,0 +1,81 @@ + + + + + Debug + x86 + {C73DEAE1-1269-4C22-A973-B25502AFD504} + Library + Properties + Deltares.DamPiping.UpliftLocationDeterminator + Deltares.DamPiping.UpliftLocationDeterminator + v4.5 + 512 + + + true + ..\bin\Debug\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + ..\bin\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + + + + + + + + + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + + "$(ProjectDir)..\..\utils\svn_insert_version.cmd" "$(ProjectDir)Properties" + + + \ No newline at end of file Index: dam failuremechanisms/damPiping/trunk/src/DamPiping.sln =================================================================== diff -u -r267 -r326 --- dam failuremechanisms/damPiping/trunk/src/DamPiping.sln (.../DamPiping.sln) (revision 267) +++ dam failuremechanisms/damPiping/trunk/src/DamPiping.sln (.../DamPiping.sln) (revision 326) @@ -26,6 +26,13 @@ {9C749AA4-CFBF-4906-9057-4F4C771788B2} = {9C749AA4-CFBF-4906-9057-4F4C771788B2} EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deltares.DamPiping.UpliftLocationDeterminator", "Deltares.DamPiping.UpliftLocationDeterminator\Deltares.DamPiping.UpliftLocationDeterminator.csproj", "{C73DEAE1-1269-4C22-A973-B25502AFD504}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Deltares.DamPiping.UpliftLocationDeterminatorTests", "Tests\Deltares.DamPiping.UpliftLocationDeterminatorTests\Deltares.DamPiping.UpliftLocationDeterminatorTests.csproj", "{F6D70668-2CAB-4D07-85B0-B4295D230A6A}" + ProjectSection(ProjectDependencies) = postProject + {C73DEAE1-1269-4C22-A973-B25502AFD504} = {C73DEAE1-1269-4C22-A973-B25502AFD504} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|x86 = Debug|x86 @@ -56,6 +63,14 @@ {D3CC9C90-ADF8-425C-8245-9CD0DF84D6A2}.Debug|x86.Build.0 = Debug|x86 {D3CC9C90-ADF8-425C-8245-9CD0DF84D6A2}.Release|x86.ActiveCfg = Release|x86 {D3CC9C90-ADF8-425C-8245-9CD0DF84D6A2}.Release|x86.Build.0 = Release|x86 + {C73DEAE1-1269-4C22-A973-B25502AFD504}.Debug|x86.ActiveCfg = Debug|x86 + {C73DEAE1-1269-4C22-A973-B25502AFD504}.Debug|x86.Build.0 = Debug|x86 + {C73DEAE1-1269-4C22-A973-B25502AFD504}.Release|x86.ActiveCfg = Release|x86 + {C73DEAE1-1269-4C22-A973-B25502AFD504}.Release|x86.Build.0 = Release|x86 + {F6D70668-2CAB-4D07-85B0-B4295D230A6A}.Debug|x86.ActiveCfg = Debug|x86 + {F6D70668-2CAB-4D07-85B0-B4295D230A6A}.Debug|x86.Build.0 = Debug|x86 + {F6D70668-2CAB-4D07-85B0-B4295D230A6A}.Release|x86.ActiveCfg = Release|x86 + {F6D70668-2CAB-4D07-85B0-B4295D230A6A}.Release|x86.Build.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -64,5 +79,6 @@ {8B92CBAF-286B-44B1-9165-5B7CFD320772} = {B8D0FE36-7979-498D-85B9-D8776EAE10BF} {EFBD172A-3AC6-47C9-AD59-1BAA3B523E29} = {B8D0FE36-7979-498D-85B9-D8776EAE10BF} {D3CC9C90-ADF8-425C-8245-9CD0DF84D6A2} = {B8D0FE36-7979-498D-85B9-D8776EAE10BF} + {F6D70668-2CAB-4D07-85B0-B4295D230A6A} = {B8D0FE36-7979-498D-85B9-D8776EAE10BF} EndGlobalSection EndGlobal Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/Resources.Designer.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/Resources.Designer.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/Resources.Designer.cs (revision 326) @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Deltares.DamPiping.UpliftLocationDeterminator.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Deltares.DamPiping.UpliftLocationDeterminator.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to CharacteristicPointXNotAscending. + /// + internal static string PipingSurfaceLine_Validate_CharacteristicPointXNotAscending { + get { + return ResourceManager.GetString("PipingSurfaceLine_Validate_CharacteristicPointXNotAscending", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DitchIncorrect. + /// + internal static string PipingSurfaceLine_Validate_DitchIncorrect { + get { + return ResourceManager.GetString("PipingSurfaceLine_Validate_DitchIncorrect", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to PointXNotAscending. + /// + internal static string PipingSurfaceLine_Validate_PointXNotAscending { + get { + return ResourceManager.GetString("PipingSurfaceLine_Validate_PointXNotAscending", resourceCulture); + } + } + } +} Index: dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.UpliftLocationDeterminatorTests/Deltares.DamPiping.UpliftLocationDeterminatorTests.csproj =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.UpliftLocationDeterminatorTests/Deltares.DamPiping.UpliftLocationDeterminatorTests.csproj (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.UpliftLocationDeterminatorTests/Deltares.DamPiping.UpliftLocationDeterminatorTests.csproj (revision 326) @@ -0,0 +1,65 @@ + + + + + Debug + x86 + {F6D70668-2CAB-4D07-85B0-B4295D230A6A} + Library + Properties + Deltares.DamPiping.UpliftLocationDeterminatorTests + Deltares.DamPiping.UpliftLocationDeterminatorTests + v4.5 + 512 + + + true + ..\..\bin\Debug\ + DEBUG;TRACE + full + x86 + prompt + MinimumRecommendedRules.ruleset + + + ..\..\bin\Release\ + TRACE + true + pdbonly + x86 + prompt + MinimumRecommendedRules.ruleset + + + + False + ..\..\..\lib\NUnit\nunit.framework.dll + + + + + + + + + + + + + + + + + {c73deae1-1269-4c22-a973-b25502afd504} + Deltares.DamPiping.UpliftLocationDeterminator + + + + + \ No newline at end of file Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/AssemblyInfo.cs.svn =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/AssemblyInfo.cs.svn (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/AssemblyInfo.cs.svn (revision 326) @@ -0,0 +1,8 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("c73deae1-1269-4c22-a973-b25502afd504")] + +[assembly: AssemblyVersion("17.1.0.SVNREV")] +[assembly: AssemblyFileVersion("17.1.0.SVNREV")] Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/GlobalAssemblyInfo.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/GlobalAssemblyInfo.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/GlobalAssemblyInfo.cs (revision 326) @@ -0,0 +1,21 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("UpliftLocationDeterminator")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Deltares")] +[assembly: AssemblyProduct("UpliftLocationDeterminator")] +[assembly: AssemblyCopyright("Copyright © Deltares 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Helper.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Helper.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Helper.cs (revision 326) @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Deltares.DamPiping +{ + public class Helper + { + public static string Translate(string textId, string id = "") + { + return textId + ": " + id; + } + + public static bool AlmostEquals(double double1, double double2, double precision) + { + if (Double.IsNaN(double1) && Double.IsNaN(double2)) + return true; + if (Double.IsNaN(double1) || Double.IsNaN(double2)) + return false; + return Math.Abs(double1 - double2) <= precision; + } + public static bool AlmostEquals(double double1, double double2) + { + return AlmostEquals(double1, double2, 1E-07); + } + + } +} Index: dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.UpliftLocationDeterminatorTests/DeterminatorUpliftLocationTests.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.UpliftLocationDeterminatorTests/DeterminatorUpliftLocationTests.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Tests/Deltares.DamPiping.UpliftLocationDeterminatorTests/DeterminatorUpliftLocationTests.cs (revision 326) @@ -0,0 +1,65 @@ +using Deltares.DamPiping.UpliftLocationDeterminator; +using NUnit.Framework; + +namespace Deltares.DamPiping.UpliftLocationDeterminatorTests +{ + public class DeterminatorUpliftLocationTests + { + + [Test] + public void GetLowestUpliftFactorCoordinateFromSimpleSurfaceLineAndOneSandLayerProfile() + { + const double cTolerance = 0.000001; + const double cExpectedXCoordinate = 59.5; + const double cExpectedZCoordinate = -2.0; + const double cExpectedUpliftFactor = 0.675781015; // Value taken from calculation itself + + // Set required upliftcalculator variables + const double cRiverlevel = 4; + PipingSurfaceLine surfaceLine = CreateSurfaceLineTutorial1(); +// SoilProfile1D soilProfile = FactoryForSoilProfileTests.CreateClaySandProfile(); +// PLLines plLines = CreatePLLines(surfaceLine, soilProfile, cRiverlevel, false); + + DeterminatorUpliftLocation upliftLocationDeterminator = new DeterminatorUpliftLocation() + { + SurfaceLine = surfaceLine, +// SoilProfile = soilProfile, +// PLLines = plLines + }; + Assert.AreEqual(10, surfaceLine.Points.Count); + + + // UpliftLocationAndResult upliftLocationAndResult = upliftLocationDeterminator.GetLocationAtWithLowestUpliftFactor(); + // + // Assert.AreEqual(cExpectedXCoordinate, upliftLocationAndResult.X, cTolerance); + // Assert.AreEqual(cExpectedZCoordinate, upliftLocationAndResult.Z, cTolerance); + // Assert.AreEqual(cExpectedUpliftFactor, upliftLocationAndResult.UpliftFactor.Value, cTolerance); + } + + public static PipingSurfaceLine CreateSurfaceLineTutorial1(bool includingTraffic = false) + { + PipingSurfaceLine surfaceLine = new PipingSurfaceLine(); + surfaceLine.Name = "Tutorial1"; + // surfaceLine.Geometry = new LocalizedGeometryPointString(); + // surfaceLine.CharacteristicPoints.GeometryMustContainPoint = true; + surfaceLine.Points.Add(new PipingPoint(0.0, 0.0, 0.0, PipingCharacteristicPointType.SurfaceLevelOutside)); + surfaceLine.Points.Add(new PipingPoint(10.0, 0.0, 0.0, PipingCharacteristicPointType.DikeToeAtRiver)); + surfaceLine.Points.Add(new PipingPoint(34.5, 0.0, 5.0, PipingCharacteristicPointType.DikeTopAtRiver)); + if (includingTraffic) + { + surfaceLine.Points.Add(new PipingPoint(35.0, 0.0, 5.0, PipingCharacteristicPointType.TrafficLoadOutside)); + surfaceLine.Points.Add(new PipingPoint(38.5, 0.0, 5.0, PipingCharacteristicPointType.TrafficLoadInside)); + } + surfaceLine.Points.Add(new PipingPoint(40.5, 0.0, 5.0, PipingCharacteristicPointType.DikeTopAtPolder)); + surfaceLine.Points.Add(new PipingPoint(50.5, 0.0, 0.0, PipingCharacteristicPointType.DikeToeAtPolder)); + surfaceLine.Points.Add(new PipingPoint(58.5, 0.0, 0.0, PipingCharacteristicPointType.DitchDikeSide)); + surfaceLine.Points.Add(new PipingPoint(59.5, 0.0, -2.0, PipingCharacteristicPointType.BottomDitchDikeSide)); + surfaceLine.Points.Add(new PipingPoint(61.5, 0.0, -2.0, PipingCharacteristicPointType.BottomDitchPolderSide)); + surfaceLine.Points.Add(new PipingPoint(61.5, 0.0, 0.0, PipingCharacteristicPointType.DitchPolderSide)); + surfaceLine.Points.Add(new PipingPoint(75.0, 0.0, 0.0, PipingCharacteristicPointType.SurfaceLevelInside)); + return surfaceLine; + } + + + } +} Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingCharacteristicPointType.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingCharacteristicPointType.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingCharacteristicPointType.cs (revision 326) @@ -0,0 +1,20 @@ +namespace Deltares.DamPiping.UpliftLocationDeterminator +{ + public enum PipingCharacteristicPointType + { + None, + SurfaceLevelOutside, + DikeToeAtRiver, + DikeTopAtRiver, + TrafficLoadOutside, + TrafficLoadInside, + ShoulderBaseInside, + DikeTopAtPolder, + DikeToeAtPolder, // Teen dijk binnenwaarts + DitchDikeSide, // Insteek sloot dijkzijde + BottomDitchDikeSide, // Slootbodem dijkzijde + BottomDitchPolderSide, // Slootbodem polderzijde + DitchPolderSide, // Insteek sloot polderzijde + SurfaceLevelInside, + } +} Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/Resources.resx =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/Resources.resx (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Properties/Resources.resx (revision 326) @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 1.3 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + CharacteristicPointXNotAscending + + + DitchIncorrect + + + PointXNotAscending + + \ No newline at end of file Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Routines2D.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Routines2D.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Routines2D.cs (revision 326) @@ -0,0 +1,516 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Deltares.DamPiping.UpliftLocationDeterminator +{ + public enum LineIntersection + { + NoIntersection, + Intersects, + Parallel, + } + public static class Routines2D + { +// private const float cCoincideTolerance = 0.0001f; +// private const double cEpsilon = 0.0001; +// + public static double Compute2DDistance(double aX1, double aY1, double aX2, double aY2) + { + double num1 = aX1 - aX2; + double num2 = aY1 - aY2; + return Math.Sqrt(num1 * num1 + num2 * num2); + } + +// public static PointLocation RelativePointPositionToLine(double aLine1X, double aLine1Y, double aLine2X, double aLine2Y, double aPointX, double aPointY) +// { +// double num = Routines2D.CrossProduct(aLine2X - aLine1X, aLine2Y - aLine1Y, aPointX - aLine1X, aPointY - aLine1Y); +// if (Math.Abs(num) < 0.0001) +// return PointLocation.On; +// return num < 0.0 ? PointLocation.Right : PointLocation.Left; +// } +// + public static LineIntersection DetermineIf2DLinesIntersectStrickly(Point2D point1, Point2D point2, Point2D point3, Point2D point4, ref Point2D intersectionPoint) + { + return Routines2D.DetermineIf2DLinesIntersectStrickly(point1, point2, point3, point4, out intersectionPoint, 0.0001); + } + + public static LineIntersection DetermineIf2DLinesIntersectStrickly(Point2D point1, Point2D point2, Point2D point3, Point2D point4, out Point2D intersectionPoint, double tolerance) + { + LineIntersection lineIntersection = Routines2D.DetermineIf2DLinesIntersectWithExtrapolation(Routines2D.CalculateNormalLineConstants(point1, point2), Routines2D.CalculateNormalLineConstants(point3, point4), out intersectionPoint); + switch (lineIntersection) + { + case LineIntersection.Intersects: + if (!Routines2D.DoesPointExistInLine(point1, point2, intersectionPoint, tolerance) || !Routines2D.DoesPointExistInLine(point3, point4, intersectionPoint, tolerance)) + { + intersectionPoint = (Point2D)null; + lineIntersection = LineIntersection.NoIntersection; + break; + } + break; + case LineIntersection.Parallel: + if (!Routines2D.DoLinesAtLeastPartialyOverlap(point1, point2, point3, point4, tolerance)) + { + if (Routines2D.DetermineIfPointsCoincide(point1, point3, tolerance) || Routines2D.DetermineIfPointsCoincide(point1, point4, tolerance)) + { + intersectionPoint = point1; + lineIntersection = LineIntersection.Intersects; + } + if (Routines2D.DetermineIfPointsCoincide(point2, point3, tolerance) || Routines2D.DetermineIfPointsCoincide(point2, point4, tolerance)) + { + intersectionPoint = point2; + lineIntersection = LineIntersection.Intersects; + break; + } + break; + } + break; + } + return lineIntersection; + } + + public static bool DoLinesAtLeastPartialyOverlap(Point2D point1, Point2D point2, Point2D point3, Point2D point4, double tolerance) + { + bool flag = Routines2D.AreLinesParallel(point1, point2, point3, point4, tolerance); + if (!flag) + return false; + if (Math.Abs(point1.X - point2.X) < double.Epsilon) + { + double num1 = Math.Max(point1.Y, point2.Y); + double num2 = Math.Min(point1.Y, point2.Y); + double num3 = Math.Max(point3.Y, point4.Y); + double num4 = Math.Min(point3.Y, point4.Y); + if (num1 <= num4 || num2 >= num3) + flag = false; + } + else + { + double num1 = Math.Max(point1.X, point2.X); + double num2 = Math.Min(point1.X, point2.X); + double num3 = Math.Max(point3.X, point4.X); + double num4 = Math.Min(point3.X, point4.X); + if (num1 <= num4 || num2 >= num3) + flag = false; + } + return flag; + } + + public static bool AreLinesParallel(Point2D point1, Point2D point2, Point2D point3, Point2D point4) + { + return Routines2D.AreLinesParallel(point1, point2, point3, point4, 0.0001); + } + + public static bool AreLinesParallel(Point2D point1, Point2D point2, Point2D point3, Point2D point4, double tolerance) + { + Vector3D vector3D1 = new Vector3D(point2.X, point2.Y, 0.0) - new Vector3D(point1.X, point1.Y, 0.0); + Vector3D vector3D2 = new Vector3D(point4.X, point4.Y, 0.0) - new Vector3D(point3.X, point3.Y, 0.0); + vector3D1.Normalize(); + vector3D2.Normalize(); + return Routines2D.AreLinesParallel(new Point2D(vector3D1.X, vector3D1.Y), new Point2D(vector3D2.X, vector3D2.Y), tolerance); + } + + public static LineIntersection DetermineIf2DLinesIntersectWithExtrapolation(Point2D aPoint1, Point2D aPoint2, Point2D aPoint3, Point2D aPoint4, ref Point2D aIntersectionPoint) + { + return Routines2D.DetermineIf2DLinesIntersectWithExtrapolation(Routines2D.CalculateNormalLineConstants(aPoint1, aPoint2), Routines2D.CalculateNormalLineConstants(aPoint3, aPoint4), out aIntersectionPoint); + } + + public static bool DetermineIfPointsCoincide(Point2D point1, Point2D point2, double tolerance) + { + return Math.Abs(point1.X - point2.X) < tolerance && Math.Abs(point1.Y - point2.Y) < tolerance; + } + + public static bool DoesPointExistInLine(Point2D linePoint1, Point2D linePoint2, Point2D point, double tolerance) + { + double x1 = linePoint1.X; + double y1 = linePoint1.Y; + double x2 = linePoint2.X; + double y2 = linePoint2.Y; + if (linePoint1.X == linePoint2.X && linePoint1.Y == linePoint2.Y) + return Routines2D.Compute2DDistance(point.X, point.Y, x1, y1) < tolerance; + double num1 = Math.Max(x1, x2); + double num2 = Math.Min(x1, x2); + double num3 = Math.Max(y1, y2); + double num4 = Math.Min(y1, y2); + double num5 = num2 - tolerance; + double num6 = num4 - tolerance; + double num7 = num1 + tolerance; + double num8 = num3 + tolerance; + double x3 = point.X; + double y3 = point.Y; + if (x3 <= num5 || x3 >= num7 || (y3 <= num6 || y3 >= num8)) + return false; + double num9 = y1 - y2; + double num10 = x2 - x1; + double num11 = -(num9 * x1 + num10 * y1); + return Math.Abs((num9 * x3 + num10 * y3 + num11) / Routines2D.Compute2DDistance(x1, y1, x2, y2)) < tolerance; + } + +// public static double LinInpolY(double aXStart, double aYStart, double aXEnd, double aYEnd, double aXInterpolation) +// { +// if (Math.Abs(aXEnd - aXStart) < 1E-15) +// return (aYEnd + aYStart) * 0.5; +// return GeneralMathRoutines.LinearInterpolate(aYStart, aYEnd, (aXInterpolation - aXStart) / (aXEnd - aXStart)); +// } +// +// public static double CalculateSquaredDistance(Point2D point, Point2D segmentPoint1, Point2D segmentPoint2) +// { +// Point2D point2D1 = segmentPoint2 - segmentPoint1; +// Point2D point2D2 = point - segmentPoint1; +// Func func = (Func)((first, second) => first.X * second.X + first.Y * second.Y); +// double num1 = func(point2D2, point2D1); +// double num2 = func(point2D1, point2D1); +// Point2D point2D3; +// if (num1 <= 0.0) +// point2D3 = point - segmentPoint1; +// else if (num2 <= num1) +// { +// point2D3 = point - segmentPoint2; +// } +// else +// { +// double num3 = num1 / num2; +// Point2D point2D4 = segmentPoint1 + num3 * point2D1; +// point2D3 = point - point2D4; +// } +// return func(point2D3, point2D3); +// } +// +// public static double CalculateSquaredDistance(Point2D segment1Point1, Point2D segment1Point2, Point2D segment2Point1, Point2D segment2Point2) +// { +// return ((IEnumerable)new double[4] +// { +// Routines2D.CalculateSquaredDistance(segment1Point1, segment2Point1, segment2Point2), +// Routines2D.CalculateSquaredDistance(segment1Point2, segment2Point1, segment2Point2), +// Routines2D.CalculateSquaredDistance(segment2Point1, segment1Point1, segment1Point2), +// Routines2D.CalculateSquaredDistance(segment2Point2, segment1Point1, segment1Point2) +// }).Min(); +// } +// +// public static double CalculateDistanceToLine(double pointX, double pointY, double segmentStartX, double segmentStartY, double segmentEndX, double segmentEndY) +// { +// return Math.Sqrt(Routines2D.CalculateSquaredDistance(new Point2D(pointX, pointY), new Point2D(segmentStartX, segmentStartY), new Point2D(segmentEndX, segmentEndY))); +// } +// +// public static void FindParallelLine(double x1, double y1, double x2, double y2, double distance, out double resultX1, out double resultY1, out double resultX2, out double resultY2) +// { +// if (Math.Abs(distance) > 0.0) +// { +// double num1 = x2 - x1; +// double num2 = y2 - y1; +// double num3 = Routines2D.Compute2DDistance(x1, y1, x2, y2); +// double num4 = distance / num3; +// double num5 = num4 * num1; +// double num6 = num4 * num2; +// x1 -= num6; +// x2 -= num6; +// y1 += num5; +// y2 += num5; +// } +// resultX1 = x1; +// resultX2 = x2; +// resultY1 = y1; +// resultY2 = y2; +// } +// +// public static PointInPolygon CheckIfPointIsInPolygon(List polygon, double x, double y) +// { +// PointInPolygon pointInPolygon = PointInPolygon.OutsidePolygon; +// if (polygon.Count > 0) +// polygon.Add(polygon[0]); +// double count = (double)polygon.Count; +// if (count > 2.0) +// { +// double x1 = polygon[0].X - x; +// double y1 = polygon[0].Y - y; +// if (Math.Abs(x1) < 1E-10 && Math.Abs(y1) < 1E-10) +// return PointInPolygon.OnPolygonEdge; +// double num1 = Math.Atan2(y1, x1); +// double num2 = 0.0; +// for (int index = 1; (double)index < count; ++index) +// { +// double x2 = polygon[index].X - x; +// double y2 = polygon[index].Y - y; +// if (Math.Abs(x2) < 1E-10 && Math.Abs(y2) < 1E-10) +// return PointInPolygon.OnPolygonEdge; +// double num3 = Math.Atan2(y2, x2); +// double num4 = num3 - num1; +// if (num4 < -1.0 * Math.PI) +// num4 += 2.0 * Math.PI; +// if (num4 > Math.PI) +// num4 -= 2.0 * Math.PI; +// if (Math.PI - num4 < 1E-10 || Math.PI + num4 < 1E-10) +// return PointInPolygon.OnPolygonEdge; +// num2 += num4; +// num1 = num3; +// } +// pointInPolygon = num2 > 19.0 * Math.PI / 10.0 || num2 < -19.0 * Math.PI / 10.0 ? PointInPolygon.InsidePolygon : PointInPolygon.OutsidePolygon; +// } +// return pointInPolygon; +// } +// +// public static void GetPointOnLineClosestTo(double aPointX, double aPointY, double aLine1X, double aLine1Y, double aLine2X, double aLine2Y, out double aResultX, out double aResultY) +// { +// double x = Routines2D.Compute2DDistance(aLine1X, aLine1Y, aLine2X, aLine2Y); +// double num = (Math.Pow(Routines2D.Compute2DDistance(aLine1X, aLine1Y, aPointX, aPointY), 2.0) - Math.Pow(Routines2D.Compute2DDistance(aLine2X, aLine2Y, aPointX, aPointY), 2.0) + Math.Pow(x, 2.0)) / (2.0 * x); +// if (num <= 0.0) +// { +// aResultX = aLine1X; +// aResultY = aLine1Y; +// } +// else if (num >= x) +// { +// aResultX = aLine2X; +// aResultY = aLine2Y; +// } +// else +// { +// aResultX = aLine1X + num / x * (aLine2X - aLine1X); +// aResultY = aLine1Y + num / x * (aLine2Y - aLine1Y); +// } +// } +// +// public static List IntersectCircleline(double aX, double aY, double aR, double aX1, double aX2, double aY1, double aY2) +// { +// double num1 = aX2 - aX1; +// double x1 = aX1 - aX; +// double num2 = aY2 - aY1; +// double x2 = aY1 - aY; +// List point2DList = new List(); +// if (Math.Abs(num1) > 1E-08 || Math.Abs(num2) > 1E-08) +// { +// double num3 = num1 * num1 + num2 * num2; +// double num4 = 2.0 * (num1 * x1 + num2 * x2); +// double num5 = x1 * x1 + x2 * x2 - aR * aR; +// double d = num4 * num4 - 4.0 * num3 * num5; +// if (d > 1E-08) +// { +// double num6 = (-num4 + Math.Sqrt(d)) / (2.0 * num3); +// if (num6 >= -1E-08 && num6 <= 1.00000001) +// point2DList.Add(new Point2D(aX1 + num6 * num1, aY1 + num6 * num2)); +// double num7 = (-num4 - Math.Sqrt(d)) / (2.0 * num3); +// if (num7 >= -1E-08 && num7 <= 1.00000001) +// point2DList.Add(new Point2D(aX1 + num7 * num1, aY1 + num7 * num2)); +// } +// else if (Math.Abs(d) <= 1E-08) +// { +// double num6 = -num4 / (2.0 * num3); +// if (num6 >= -1E-08 && num6 <= 1.00000001) +// point2DList.Add(new Point2D(aX1 + num6 * num1, aY1 + num6 * num2)); +// } +// } +// else if (Math.Abs(Math.Pow(x1, 2.0) + Math.Pow(x2, 2.0) - Math.Pow(aR, 2.0)) < 1E-08) +// point2DList.Add(new Point2D(aX1, aY1)); +// return point2DList; +// } +// +// public static Clockwise IsClockWise(IEnumerable aPolygon) +// { +// Point2D[] array = aPolygon.Distinct().ToArray(); +// if (array.Length < 3) +// return Clockwise.NotEnoughUniquePoints; +// double num1 = 0.0; +// for (int index = 0; index < array.Length - 1; ++index) +// { +// double num2 = (array[index + 1].X - array[index].X) * (array[index + 1].Y + array[index].Y); +// num1 += num2; +// } +// double num3 = (array[0].X - array[array.Length - 1].X) * (array[0].Y + array[array.Length - 1].Y); +// int num4 = Math.Sign(num1 + num3); +// if (num4 == 0) +// return Clockwise.PointsOnLine; +// return (double)num4 <= 0.0 ? Clockwise.AntiClockwise : Clockwise.IsClockwise; +// } +// +// public static double ComputeTriangleArea(double aX1, double aY1, double aX2, double aY2, double aX3, double aY3) +// { +// return 0.5 * ((aX3 - aX1) * (aY2 - aY1) - (aY3 - aY1) * (aX2 - aX1)); +// } +// +// public static bool AreEqual(double x1, double x2, double tolerance) +// { +// return Math.Abs(x1 - x2) < tolerance; +// } +// +// public static bool AreEqual(Point2D p1, Point2D p2, int tolerance) +// { +// if (Routines2D.AreEqual(p1.X, p2.X, (double)tolerance)) +// return Routines2D.AreEqual(p1.Y, p2.Y, (double)tolerance); +// return false; +// } +// +// public static bool AreEqual(int x1, int x2, int tolerance) +// { +// return Math.Abs(x1 - x2) < tolerance; +// } +// +// public static bool DetermineIfPointsCoincide(double aX1, double aY1, double aX2, double aY2, double aTolerance) +// { +// if (Math.Abs(aX2 - aX1) < aTolerance) +// return Math.Abs(aY2 - aY1) < aTolerance; +// return false; +// } +// +// public static double Determine2DPolygonArea(List closedPolygon) +// { +// int count = closedPolygon.Count; +// double num = 0.0; +// if (!Routines2D.DetermineIfPointsCoincide(closedPolygon[0], closedPolygon[count - 1], 9.99999974737875E-05)) +// { +// closedPolygon.Add(closedPolygon[0]); +// count = closedPolygon.Count; +// } +// for (int index = 0; index < count - 1; ++index) +// num += Routines2D.CrossProduct(closedPolygon[index].X, closedPolygon[index].Y, closedPolygon[index + 1].X, closedPolygon[index + 1].Y); +// return num / 2.0; +// } +// +// public static Point2D DeterminePolygonCentroid(List closedPolygon) +// { +// int count = closedPolygon.Count; +// if (!Routines2D.DetermineIfPointsCoincide(closedPolygon[0], closedPolygon[count - 1], 9.99999974737875E-05)) +// closedPolygon.Add(closedPolygon[0]); +// else +// --count; +// double num1 = Routines2D.Determine2DPolygonArea(closedPolygon); +// if (num1 > 0.0) +// { +// double num2 = 0.0; +// double num3 = 0.0; +// for (int index = 0; index < count; ++index) +// { +// double num4 = Routines2D.CrossProduct(closedPolygon[index].X, closedPolygon[index].Y, closedPolygon[index + 1].X, closedPolygon[index + 1].Y); +// num2 += (closedPolygon[index].X + closedPolygon[index + 1].X) * num4; +// num3 += (closedPolygon[index].Y + closedPolygon[index + 1].Y) * num4; +// } +// return new Point2D(num2 / (6.0 * num1), num3 / (6.0 * num1)); +// } +// double num5 = 0.0; +// double num6 = 0.0; +// for (int index = 0; index < count; ++index) +// { +// num5 += closedPolygon[index].X; +// num6 += closedPolygon[index].Y; +// } +// return new Point2D(num5 / (double)count, num6 / (double)count); +// } +// +// public static MinMax GetMinMax(List aPointList, ref double aMin, ref double aMax, MinMaxCordinate aMinMaxCoordinate) +// { +// if (aPointList.Count < 2) +// return MinMax.Error; +// aMin = aPointList.Min((Func)(x => +// { +// if (aMinMaxCoordinate != MinMaxCordinate.X) +// return x.Y; +// return x.X; +// })); +// aMax = aPointList.Max((Func)(x => +// { +// if (aMinMaxCoordinate != MinMaxCordinate.X) +// return x.Y; +// return x.X; +// })); +// return MinMax.Calculated; +// } +// +// public static double GetAngle(double x1, double y1, double x2, double y2) +// { +// double aValue1_1 = y2 - y1; +// double aValue1_2 = x2 - x1; +// if (aValue1_2.IsNearEqual(1E-08)) +// return 90.0; +// if (aValue1_1.IsNearEqual(1E-08)) +// return 0.0; +// return Math.Atan(aValue1_1 / aValue1_2) * 180.0 / Math.PI; +// } +// +// public static bool IsPointInRectangularBounds(double aXLeft, double aXRight, double aYTop, double aYBottom, Point2D aPoint) +// { +// bool flag1 = aPoint.X.IsGreaterThanOrEqualTo(aXLeft) && aPoint.X.IsLessThanOrEqualTo(aXRight); +// bool flag2 = aPoint.Y.IsGreaterThanOrEqualTo(aYBottom) && aPoint.Y.IsLessThanOrEqualTo(aYTop); +// if (flag1) +// return flag2; +// return false; +// } +// +// public static double GetMinimumDistanceAmongPoints(List pointList) +// { +// if (pointList.Count < 2) +// return 0.0; +// List doubleList = new List(); +// for (int index1 = 0; index1 < pointList.Count; ++index1) +// { +// for (int index2 = index1 + 1; index2 < pointList.Count; ++index2) +// doubleList.Add(Routines2D.Compute2DDistance(pointList[index1].X, pointList[index1].Y, pointList[index2].X, pointList[index2].Y)); +// } +// doubleList.Sort(); +// return doubleList[0]; +// } +// +// public static Point2D RotateAroundPoint(Point2D rotatePoint, Point2D rotateCenter, double theta) +// { +// double num1 = rotatePoint.X - rotateCenter.X; +// double num2 = rotatePoint.Y - rotateCenter.Y; +// return new Point2D() +// { +// X = Math.Cos(theta) * num1 - Math.Sin(theta) * num2 + rotateCenter.X, +// Y = Math.Sin(theta) * num1 + Math.Cos(theta) * num2 + rotateCenter.Y +// }; +// } +// +// public static bool IsBetween(double x, double x1, double x2) +// { +// if (x1 <= x && x2 >= x) +// return true; +// if (x1 >= x) +// return x2 <= x; +// return false; +// } +// + private static double CrossProduct(double pointAx, double pointAy, double pointBx, double pointBy) + { + return pointAx * pointBy - pointBx * pointAy; + } + + private static Vector3D CalculateNormalLineConstants(Point2D aPoint1, Point2D aPoint2) + { + return new Vector3D() + { + X = aPoint2.Y - aPoint1.Y, + Y = -(aPoint2.X - aPoint1.X), + Z = (aPoint2.Y - aPoint1.Y) * aPoint1.X - (aPoint2.X - aPoint1.X) * aPoint1.Y + }; + } + + private static bool AreLinesParallel(Point2D aLine1Constant, Point2D aLine2Constant, double tolerance) + { + double x1 = aLine1Constant.X; + double y1 = aLine1Constant.Y; + double x2 = aLine2Constant.X; + double y2 = aLine2Constant.Y; + return Math.Abs(Routines2D.CrossProduct(x1, x2, y1, y2)) < tolerance; + } + + private static LineIntersection DetermineIf2DLinesIntersectWithExtrapolation(Vector3D aLine1Constant, Vector3D aLine2Constant, out Point2D aIntersectionPoint) + { + aIntersectionPoint = new Point2D(0.0, 0.0); + double x1 = aLine1Constant.X; + double y1 = aLine1Constant.Y; + double z1 = aLine1Constant.Z; + double x2 = aLine2Constant.X; + double y2 = aLine2Constant.Y; + double z2 = aLine2Constant.Z; + if (Routines2D.AreLinesParallel(new Point2D(x1, x2), new Point2D(y1, y2), 0.0001)) + { + aIntersectionPoint = (Point2D)null; + return LineIntersection.Parallel; + } + double num1 = (y2 * z1 - y1 * z2) / (x1 * y2 - x2 * y1); + double num2 = (z1 * x2 - z2 * x1) / (x2 * y1 - x1 * y2); + aIntersectionPoint.X = num1; + aIntersectionPoint.Y = num2; + return LineIntersection.Intersects; + } + } +} Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Vector3D.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Vector3D.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Vector3D.cs (revision 326) @@ -0,0 +1,247 @@ +using System; +using System.ComponentModel; +using System.Globalization; + + +namespace Deltares.DamPiping.UpliftLocationDeterminator +{ + [TypeConverter(typeof(Vector3D))] + public class Vector3D : ExpandableObjectConverter + { + private double x; + private double y; + private double z; + + public double X + { + get + { + return this.x; + } + set + { + this.x = value; + } + } + + public double Y + { + get + { + return this.y; + } + set + { + this.y = value; + } + } + + public double Z + { + get + { + return this.z; + } + set + { + this.z = value; + } + } + + public Vector3D() + { + this.x = this.y = this.z = 0.0; + } + + public Vector3D(double aX, double aY, double aZ) + { + this.x = aX; + this.y = aY; + this.z = aZ; + } + + public Vector3D(Point3D aPoint) + { + this.x = aPoint.X; + this.y = aPoint.Y; + this.z = aPoint.Z; + } + + public Vector3D(double aValue1, Vector3D aVector1, double aValue2, Vector3D aVector2) + { + this.x = aValue1 * aVector1.x + aValue2 * aVector2.x; + this.y = aValue1 * aVector1.y + aValue2 * aVector2.y; + this.z = aValue1 * aVector1.z + aValue2 * aVector2.z; + } + + public Vector3D(double aValue1, Vector3D aVector1, double aValue2, Vector3D aVector2, double aValue3, Vector3D aVector3, double aValue4, Vector3D aVector4) + { + this.x = aValue1 * aVector1.X + aValue2 * aVector2.X + aValue3 * aVector3.X + aValue4 * aVector4.X; + this.y = aValue1 * aVector1.Y + aValue2 * aVector2.Y + aValue3 * aVector3.Y + aValue4 * aVector4.Y; + this.z = aValue1 * aVector1.Z + aValue2 * aVector2.Z + aValue3 * aVector3.Z + aValue4 * aVector4.Z; + } + + public Vector3D(Vector3D aVector) + { + this.x = aVector.x; + this.y = aVector.y; + this.z = aVector.z; + } + + public static Vector3D operator -(Vector3D aVector) + { + return new Vector3D(-aVector.x, -aVector.y, -aVector.z); + } + + public static Vector3D operator +(Vector3D aVector2, Vector3D aVector1) + { + return new Vector3D(aVector2.x + aVector1.x, aVector2.y + aVector1.y, aVector2.z + aVector1.z); + } + + public static Vector3D operator -(Vector3D aVector2, Vector3D aVector1) + { + return new Vector3D(aVector2.x - aVector1.x, aVector2.y - aVector1.y, aVector2.z - aVector1.z); + } + + public static Vector3D operator *(double aValue, Vector3D aVector) + { + return new Vector3D(aValue * aVector.x, aValue * aVector.y, aValue * aVector.z); + } + + public static Vector3D operator *(Vector3D aVector, double aValue) + { + return new Vector3D(aValue * aVector.x, aValue * aVector.y, aValue * aVector.z); + } + + public static double operator ~(Vector3D aVector) + { + return Math.Sqrt(aVector.x * aVector.x + aVector.y * aVector.y + aVector.z * aVector.z); + } + + public static double operator |(Vector3D aVector2, Vector3D aVector1) + { + return aVector2.x * aVector1.x + aVector2.y * aVector1.y + aVector2.z * aVector1.z; + } + + public static Vector3D operator *(Vector3D aVector1, Vector3D aVector2) + { + return new Vector3D(aVector1.y * aVector2.z - aVector1.z * aVector2.y, aVector1.z * aVector2.x - aVector1.x * aVector2.z, aVector1.x * aVector2.y - aVector1.y * aVector2.x); + } + + public static Point3D operator *(Point3D aPoint, Vector3D aVector) + { + return new Point3D(aPoint.Y * aVector.z - aPoint.Z * aVector.y, aPoint.Z * aVector.x - aPoint.X * aVector.z, aPoint.X * aVector.y - aPoint.Y * aVector.x); + } + + public static Point3D operator +(Point3D aPoint, Vector3D aVector) + { + return new Point3D(aPoint.X + aVector.X, aPoint.Y + aVector.Y, aPoint.Z + aVector.Z); + } + + public static Point3D operator +(Vector3D aVector, Point3D aPoint) + { + return new Point3D(aVector.X + aPoint.X, aVector.Y + aPoint.Y, aVector.Z + aPoint.Z); + } + + public static Point3D operator -(Point3D aPoint, Vector3D aVector) + { + return new Point3D(aPoint.X - aVector.X, aPoint.Y - aVector.Y, aPoint.Z - aVector.Z); + } + + public static Vector3D operator !(Vector3D aVector) + { + Vector3D vector3D = new Vector3D(aVector); + vector3D.Normalize(); + return vector3D; + } + + public void Init(double aX, double aY, double aZ) + { + this.x = aX; + this.y = aY; + this.z = aZ; + } + + public void Init(Vector3D aVector) + { + this.x = aVector.x; + this.y = aVector.y; + this.z = aVector.z; + } + + public void Normalize() + { + double num = Math.Sqrt(this.x * this.x + this.y * this.y + this.z * this.z); + if (num == 0.0) + return; + this.x = this.x / num; + this.y = this.y / num; + this.z = this.z / num; + } + + public Vector3D Add(Vector3D aVector) + { + this.x += aVector.x; + this.y += aVector.y; + this.z += aVector.z; + return this; + } + + public bool IsZero() + { + if (Math.Abs(this.x - 0.0) < 0.001 && Math.Abs(this.y - 0.0) < 0.001) + return Math.Abs(this.z - 0.0) < 0.001; + return false; + } + + public Vector3D RotateVectorAroundAxis(Vector3D aAxis, double aFi) + { + Vector3D vector3D1 = (this | aAxis) * aAxis; + Vector3D vector3D2 = this - vector3D1; + Vector3D vector3D3 = aAxis * vector3D2; + double num1 = Math.Cos(aFi); + double num2 = Math.Sin(aFi); + this.Init(vector3D2 * num1 + vector3D3 * num2 + vector3D1); + return this; + } + + public bool FromString(string aString, params char[] aSeparator) + { + string[] strArray = aString.Split(aSeparator); + if (strArray.Length != 3) + return false; + this.x = Convert.ToDouble(strArray[0]); + this.y = Convert.ToDouble(strArray[1]); + this.z = Convert.ToDouble(strArray[2]); + return true; + } + + public string ToStringSep(char aSeparator) + { + return this.x.ToString() + (object)aSeparator + this.y.ToString() + (object)aSeparator + this.z.ToString(); + } + + public string ToStringSep(IFormatProvider aFormatProvider, char aSeparator) + { + return this.x.ToString(aFormatProvider) + (object)aSeparator + this.y.ToString(aFormatProvider) + (object)aSeparator + this.z.ToString(aFormatProvider); + } + + public override bool Equals(object aObject) + { + Vector3D vector3D = aObject as Vector3D; + if (Math.Abs(this.x - vector3D.x) < 0.001 && Math.Abs(this.y - vector3D.y) < 0.001) + return Math.Abs(this.z - vector3D.z) < 0.001; + return false; + } + + public override object ConvertTo(ITypeDescriptorContext aContext, CultureInfo aCulture, object aValue, Type aDestinationType) + { + return (object)""; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + } +} Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/DeterminatorUpliftLocation.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/DeterminatorUpliftLocation.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/DeterminatorUpliftLocation.cs (revision 326) @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Deltares.DamPiping.UpliftLocationDeterminator +{ + public class DeterminatorUpliftLocation + { + /// + /// 2D surface line with all relevant points labelled (toe, ditch) as input. + /// + public PipingSurfaceLine SurfaceLine { get; set; } + } +} Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingConstants.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingConstants.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingConstants.cs (revision 326) @@ -0,0 +1,21 @@ +namespace Deltares.DamPiping.UpliftLocationDeterminator +{ + /// + /// Class holding all constant default values specific to the Piping kernel + /// + public class PipingConstants + { +// public const double UnitWeightOfWater = 9.81; +// public const double GammaSubParticles = 16.5; +// public const double BeddingAngleSellmeijerOriginal = 41.0; +// public const double BeddingAngleSellmeijerRevised = 37.0; +// public const double WhitesDragCoefficient = 0.25; +// public const double D70Mean = 2.08e-4; +// public const double RExitDefault = 1.00; +// public const double RToeDefault = 1.00; +// public const double RcDefault = 0.3; + public const double Accuracy = 0.0005; +// public const double MinimumLayerThickness = 0.001; +// public const double Epsilon = 1e-8; + } +} \ No newline at end of file Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Point3D.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Point3D.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Point3D.cs (revision 326) @@ -0,0 +1,222 @@ +using System; +using System.ComponentModel; +using System.Globalization; + +namespace Deltares.DamPiping.UpliftLocationDeterminator +{ + [TypeConverter(typeof(Point3D))] + public class Point3D : ExpandableObjectConverter, IComparable + { + private double x; + private double y; + private double z; + + [Description("Set X coordinate")] + public double X + { + get + { + return this.x; + } + set + { + this.x = value; + } + } + + [Description("Set Y coordinate")] + public double Y + { + get + { + return this.y; + } + set + { + this.y = value; + } + } + + [Description("Set Z coordinate")] + public double Z + { + get + { + return this.z; + } + set + { + this.z = value; + } + } + + public Point3D() + { + this.x = 0.0; + this.y = 0.0; + this.z = 0.0; + } + + public Point3D(Point3D point) + { + this.x = point.X; + this.y = point.Y; + this.z = point.Z; + } + + public Point3D(double aX, double aY, double aZ) + { + this.x = aX; + this.y = aY; + this.z = aZ; + } + + public Point3D(double aValue1, Point3D aPoint1, double aValue2, Point3D aPoint2) + { + this.x = aValue1 * aPoint1.X + aValue2 * aPoint2.X; + this.y = aValue1 * aPoint1.Y + aValue2 * aPoint2.Y; + this.z = aValue1 * aPoint1.Z + aValue2 * aPoint2.Z; + } + + public Point3D(double aValue1, Point3D aPoint1, double aValue2, Point3D aPoint2, double aValue3, Point3D aPoint3) + { + this.x = aValue1 * aPoint1.X + aValue2 * aPoint2.X + aValue3 * aPoint3.X; + this.y = aValue1 * aPoint1.Y + aValue2 * aPoint2.Y + aValue3 * aPoint3.Y; + this.z = aValue1 * aPoint1.Z + aValue2 * aPoint2.Z + aValue3 * aPoint3.Z; + } + + public Point3D(double aValue1, Point3D aPoint1, double aValue2, Point3D aPoint2, double aValue3, Point3D aPoint3, double aValue4, Point3D aPoint4) + { + this.x = aValue1 * aPoint1.X + aValue2 * aPoint2.X + aValue3 * aPoint3.X + aValue4 * aPoint4.X; + this.y = aValue1 * aPoint1.Y + aValue2 * aPoint2.Y + aValue3 * aPoint3.Y + aValue4 * aPoint4.Y; + this.z = aValue1 * aPoint1.Z + aValue2 * aPoint2.Z + aValue3 * aPoint3.Z + aValue4 * aPoint4.Z; + } + + public static Point3D operator +(Point3D aPoint1, Point3D aPoint2) + { + return new Point3D(aPoint1.X + aPoint2.x, aPoint1.Y + aPoint2.y, aPoint1.Z + aPoint2.Z); + } + + public static Point3D operator -(Point3D aPoint1, Point3D aPoint2) + { + return new Point3D(aPoint1.X - aPoint2.x, aPoint1.Y - aPoint2.y, aPoint1.Z - aPoint2.Z); + } + + public static Point3D operator *(double scale, Point3D point) + { + return point * scale; + } + + public static Point3D operator *(Point3D point, double scale) + { + return new Point3D(point.x * scale, point.y * scale, point.z * scale); + } + + public static Point3D operator /(double scale, Point3D point) + { + return point / scale; + } + + public static Point3D operator /(Point3D point, double scale) + { + return point * (1.0 / scale); + } + + public bool Compare(Point3D aPoint, double aDistance) + { + return Math.Pow(this.x - aPoint.X, 2.0) + Math.Pow(this.y - aPoint.Y, 2.0) + Math.Pow(this.z - aPoint.Z, 2.0) <= Math.Pow(aDistance, 2.0); + } + + public void Init(double aX, double aY, double aZ) + { + this.x = aX; + this.y = aY; + this.z = aZ; + } + + public void Init(Point3D aPoint) + { + this.x = aPoint.X; + this.y = aPoint.Y; + this.z = aPoint.Z; + } + + public void Add(Point3D aPoint) + { + this.x += aPoint.X; + this.y += aPoint.Y; + this.z += aPoint.Z; + } + + public void Mul(double aValue) + { + this.x *= aValue; + this.y *= aValue; + this.z *= aValue; + } + + public bool FromString(string aString, params char[] aSeperator) + { + string[] strArray = aString.Split(aSeperator); + if (strArray.Length != 3) + return false; + this.x = Convert.ToDouble(strArray[0]); + this.y = Convert.ToDouble(strArray[1]); + this.z = Convert.ToDouble(strArray[2]); + return true; + } + + public Point2D GetPointXZ() + { + return new Point2D(this.X, this.Z); + } + + public double LengthSquared() + { + return this.DotProduct(this); + } + + public double Length() + { + return Math.Sqrt(this.LengthSquared()); + } + + public double DotProduct(Point3D p) + { + return this.X * p.X + this.Y * p.Y + this.Z * p.Z; + } + + public Point3D CrossProduct(Point3D p) + { + return new Point3D(this.Y * p.Z - this.Z * p.Y, this.Z * p.X - this.X * p.Z, this.X * p.Y - this.Y * p.X); + } + + public override bool Equals(object aObject) + { + Point3D point3D = aObject as Point3D; + if (point3D == null || Math.Abs(this.x - point3D.x) >= 0.001 || Math.Abs(this.y - point3D.y) >= 0.001) + return false; + return Math.Abs(this.z - point3D.z) < 0.001; + } + + public override object ConvertTo(ITypeDescriptorContext aContext, CultureInfo aCulture, object aValue, Type aDestinationType) + { + return (object)""; + } + + public override string ToString() + { + return this.X.ToString("F2") + " " + this.Y.ToString("F2") + " " + this.Z.ToString("F2"); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + public int CompareTo(object obj) + { + return this.X.CompareTo(((Point3D)obj).X); + } + } +} Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingPoint.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingPoint.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingPoint.cs (revision 326) @@ -0,0 +1,71 @@ +namespace Deltares.DamPiping.UpliftLocationDeterminator +{ + /// + /// Class to hold points (3D) for the Piping kernel + /// + public class PipingPoint + { + /// + /// Initializes a new instance of the class. + /// + public PipingPoint() + { + Type = PipingCharacteristicPointType.None; + } + + /// + /// Initializes a new instance of the class. + /// + /// The point. + /// + public PipingPoint(PipingPoint point, PipingCharacteristicPointType type = PipingCharacteristicPointType.None) + { + X = point.X; + Y = point.Y; + Z = point.Z; + Type = type; + } + + /// + /// Initializes a new instance of the class. + /// + /// The x. + /// The y. + /// The z. + /// + public PipingPoint(double x, double y, double z, PipingCharacteristicPointType type = PipingCharacteristicPointType.None) + { + X = x; + Y = y; + Z = z; + Type = type; + } + + /// + /// Gets or sets the x. + /// + /// + /// The x. + /// + public double X { get; set; } + + /// + /// Gets or sets the y. + /// + /// + /// The y. + /// + public double Y { get; set; } + + /// + /// Gets or sets the z. + /// + /// + /// The z. + /// + public double Z { get; set; } + + public PipingCharacteristicPointType Type { get; set; } + + } +} Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingSurfaceLine.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingSurfaceLine.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/PipingSurfaceLine.cs (revision 326) @@ -0,0 +1,362 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Deltares.DamPiping.UpliftLocationDeterminator.Properties; + +namespace Deltares.DamPiping.UpliftLocationDeterminator +{ + /// + /// PipingSurfaceLine Exception class + /// + public class PipingSurfaceLineException : Exception + { + /// + /// Initializes a new instance of the class. + /// + /// The message that describes the error. + public PipingSurfaceLineException(string message) : base(message) { } + } + + /// + /// Class to hold the surface line for the Piping kernel + /// + public class PipingSurfaceLine + { + private List points = new List(); + + /// + /// Gets or sets the name. + /// + /// + /// The name. + /// + public string Name {get; set;} + + /// + /// Gets or sets the points. + /// + /// + /// The points. + /// + public List Points + { + get + { + return points; + } + set + { + points = value; + } + } + + /// + /// Determines whether this instance has ditch. + /// + /// + public bool HasDitch() + { + var i = 0; + var foundDitch = false; + while (!foundDitch && i < Points.Count) + { + foundDitch = points[i].Type == PipingCharacteristicPointType.BottomDitchDikeSide; + i++; + } + return foundDitch; + } + + /// + /// Gets the ditch dike side. + /// + /// + /// The ditch dike side. + /// + public PipingPoint DitchDikeSide + { + get + { + var point = points.Where(x => x.Type == PipingCharacteristicPointType.DitchDikeSide); + return point.FirstOrDefault(); + } + } + + /// + /// Gets the bottom ditch dike side. + /// + /// + /// The bottom ditch dike side. + /// + public PipingPoint BottomDitchDikeSide + { + get + { + var point = points.Where(x => x.Type == PipingCharacteristicPointType.BottomDitchDikeSide); + return point.FirstOrDefault(); + } + } + + /// + /// Gets the bottom ditch polder side. + /// + /// + /// The bottom ditch polder side. + /// + public PipingPoint BottomDitchPolderSide + { + get + { + var point = points.Where(x => x.Type == PipingCharacteristicPointType.BottomDitchPolderSide); + return point.FirstOrDefault(); + } + } + + /// + /// Gets the ditch polder side. + /// + /// + /// The ditch polder side. + /// + public PipingPoint DitchPolderSide + { + get + { + var point = points.Where(x => x.Type == PipingCharacteristicPointType.DitchPolderSide); + return point.FirstOrDefault(); + } + } + + /// + /// Gets the shoulder base inside. + /// + /// + /// The shoulder base inside. + /// + public PipingPoint ShoulderBaseInside + { + get + { + var point = points.Where(x => x.Type == PipingCharacteristicPointType.ShoulderBaseInside); + return point.FirstOrDefault(); + } + } + + /// + /// Gets the dike toe at polder. + /// + /// + /// The dike toe at polder. + /// + public PipingPoint DikeToeAtPolder + { + get + { + var point = points.Where(x => x.Type == PipingCharacteristicPointType.DikeToeAtPolder); + return point.FirstOrDefault(); + } + } + + /// + /// If shoulder is present then the toe of the shoulder (DikeToeAtPolder) is returned + /// Else if present the toe of the dike (ShoulderBaseInside) is returned + /// Else the first point of the surfaceline is returned if present. + /// + /// toe of the dike + public virtual PipingPoint GetDikeToeInward() + { + if (ShoulderBaseInside != null) + { + return ShoulderBaseInside; + } + if (DikeToeAtPolder != null) + { + return DikeToeAtPolder; + } + return Points.FirstOrDefault(); + } + + /// + /// Gets the z at x. + /// + /// The x. + /// + public virtual double GetZatX(double x) + { + for (int i = 0; i < Points.Count - 1; i++) + { + var current = Points[i]; + var next = Points[i + 1]; + + var leftOffset = x - current.X; + var rightOffset = next.X - x; + + if (Math.Abs(leftOffset) < PipingConstants.Accuracy) + { + return current.Z; + } + if (Math.Abs(rightOffset) < PipingConstants.Accuracy) + { + return next.Z; + } + if (leftOffset >= 0 && rightOffset >= 0) + { + var fraction = leftOffset / (leftOffset + rightOffset); + + return (1.0 - fraction) * current.Z + fraction * next.Z; + } + } + + return double.NaN; + } + + /// + /// Intersections the points xz with line xz. + /// + /// The begin. + /// The end. + /// + public IList IntersectionPointsXzWithLineXz(PipingPoint begin, PipingPoint end) + { + var intersectionPointsWithLine = new List(); + + for (int pointIndex = 0; pointIndex < Points.Count - 1; pointIndex++) + { + DoIntersectAndAddToCollection(begin, end, Points[pointIndex], Points[pointIndex + 1], intersectionPointsWithLine); + } + return intersectionPointsWithLine; + } + + /// + /// Validates this instance. + /// + /// + internal void Validate() + { + if (!AreAllCharacteristicPointsOrdered()) + { + var format = Resources.PipingSurfaceLine_Validate_CharacteristicPointXNotAscending; + var message = string.Format(format, Name); + throw new PipingSurfaceLineException(message); + } + if (!IsDitchCorrect()) + { + var format = Resources.PipingSurfaceLine_Validate_DitchIncorrect; + var message = string.Format(format, Name); + throw new PipingSurfaceLineException(message); + } + if (!ArePointsAscending()) + { + var format = Resources.PipingSurfaceLine_Validate_PointXNotAscending; + var message = string.Format(format, Name); + throw new PipingSurfaceLineException(message); + } + } + + /// + /// Checks if points are ascending. + /// + /// true if points are ascending, otherwise false + private bool ArePointsAscending() + { + for (int i = 1; i < points.Count; i++) + { + if (points[i].X < points[i - 1].X) + { + return false; + } + } + return true; + } + + + /// + /// Does the intersect and add to collection. + /// + /// a point1. + /// a point2. + /// The begin. + /// The end. + /// The intersection points with line. + private static void DoIntersectAndAddToCollection(PipingPoint aPoint1, PipingPoint aPoint2, PipingPoint begin, PipingPoint end, ICollection intersectionPointsWithLine) + { + Point2D intersectionPoint2D = null; + Routines2D.DetermineIf2DLinesIntersectStrickly(new Point2D(aPoint1.X, aPoint1.Z), new Point2D(aPoint2.X, aPoint2.Z), new Point2D(begin.X, begin.Z), new Point2D(end.X, end.Z), ref intersectionPoint2D); + if (intersectionPoint2D != null) + { + var intersectionPoint = new PipingPoint(intersectionPoint2D.X, 0, intersectionPoint2D.Y); + if (NoPointSameXzLocation(intersectionPointsWithLine, intersectionPoint)) + { + intersectionPointsWithLine.Add(intersectionPoint); + } + } + } + + /// + /// Determines if there is a point with same xz location. + /// + /// The collection. + /// The point. + /// + private static bool NoPointSameXzLocation(IEnumerable collection, PipingPoint point) + { + return !collection.Any( + p => Math.Abs(p.X - point.X) < PipingConstants.Accuracy && + Math.Abs(p.Z - point.Z) < PipingConstants.Accuracy); + } + + /// + /// Determines whether the ditch (when defined) is defined correct. It is correct if all + /// four points are there and they are in the proper left to right order. + /// + /// + /// true if its is else false + /// + private bool IsDitchCorrect() + { + if (DitchDikeSide != null || BottomDitchDikeSide != null || BottomDitchPolderSide != null || DitchPolderSide != null) + { + // At least on ditch point given, so they must now all exist + if (DitchDikeSide == null || BottomDitchDikeSide == null || BottomDitchPolderSide == null || DitchPolderSide == null) + { + return false; + } + // they must be left to right + if (BottomDitchDikeSide.X < DitchDikeSide.X || BottomDitchPolderSide.X < BottomDitchDikeSide.X || + DitchPolderSide.X < BottomDitchPolderSide.X) + { + return false; + } + } + // no ditch or ditch is ok + return true; + } + + /// + /// Determines whether the characteristic points (when defined) are ordered correct. + /// Note that the ditch is checked separatly. + /// + /// + private bool AreAllCharacteristicPointsOrdered() + { + if (ShoulderBaseInside != null) + { + if (DikeToeAtPolder != null && DikeToeAtPolder.X < ShoulderBaseInside.X) + { + return false; + } + if (DitchDikeSide != null && DitchDikeSide.X < ShoulderBaseInside.X) + { + return false; + } + } + if (DikeToeAtPolder != null) + { + if (DitchDikeSide != null && DitchDikeSide.X < DikeToeAtPolder.X) + { + return false; + } + } + return true; + } + } +} Index: dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Point2D.cs =================================================================== diff -u --- dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Point2D.cs (revision 0) +++ dam failuremechanisms/damPiping/trunk/src/Deltares.DamPiping.UpliftLocationDeterminator/Geo/Point2D.cs (revision 326) @@ -0,0 +1,118 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Deltares.DamPiping.UpliftLocationDeterminator +{ + public class Point2D + { + public const double Epsilon = 1E-10; + + public double X { get; set; } + + public double Y { get; set; } + + public Point2D() + { + this.X = 0.0; + this.Y = 0.0; + } + + public Point2D(double aX, double aY) + { + this.X = aX; + this.Y = aY; + } + + public Point2D(double aValue1, Point2D aPoint1, double aValue2, Point2D aPoint2) + { + this.X = aValue1 * aPoint1.X + aValue2 * aPoint2.X; + this.Y = aValue1 * aPoint1.Y + aValue2 * aPoint2.Y; + } + + public Point2D(double aValue1, Point2D aPoint1, double aValue2, Point2D aPoint2, double aValue3, Point2D aPoint3, double aValue4, Point2D aPoint4) + { + this.X = aValue1 * aPoint1.X + aValue2 * aPoint2.X + aValue3 * aPoint3.X + aValue4 * aPoint4.X; + this.Y = aValue1 * aPoint1.Y + aValue2 * aPoint2.Y + aValue3 * aPoint3.Y + aValue4 * aPoint4.Y; + } + + public Point2D(Point2D aPoint) + { + this.X = aPoint.X; + this.Y = aPoint.Y; + } + + public static Point2D operator -(Point2D aPoint) + { + return new Point2D(-aPoint.X, -aPoint.Y); + } + + public static Point2D operator +(Point2D aPoint2, Point2D aPoint1) + { + return new Point2D(aPoint2.X + aPoint1.X, aPoint2.Y + aPoint1.Y); + } + + public static Point2D operator -(Point2D aPoint2, Point2D aPoint1) + { + return new Point2D(aPoint2.X - aPoint1.X, aPoint2.Y - aPoint1.Y); + } + + public static Point2D operator *(double aValue1, Point2D aPoint1) + { + return new Point2D(aValue1 * aPoint1.X, aValue1 * aPoint1.Y); + } + + public static Point2D operator *(Point2D aPoint1, double aValue1) + { + return new Point2D(aValue1 * aPoint1.X, aValue1 * aPoint1.Y); + } + + public void Init(double aX, double aY) + { + this.X = aX; + this.Y = aY; + } + + public void Init(Point2D aPoint) + { + this.X = aPoint.X; + this.Y = aPoint.Y; + } + + public Point2D Add(Point2D aPoint) + { + this.X += aPoint.X; + this.Y += aPoint.Y; + return this; + } + + public bool FromString(string aString, params char[] aSeparator) + { + string[] strArray = aString.Split(aSeparator); + if (strArray.Length != 2) + return false; + this.X = Convert.ToDouble(strArray[0]); + this.Y = Convert.ToDouble(strArray[1]); + return true; + } + + public override bool Equals(object obj) + { + Point2D point2D = obj as Point2D; + if (point2D != null && Helper.AlmostEquals(X, point2D.X, 1E-10)) + return Helper.AlmostEquals(Y, point2D.Y, 1E-10); + return false; + } + + public override int GetHashCode() + { + return this.GetType().GetHashCode() + 11 * (int)Math.Round(this.X * 1000000000) + 29 * (int)Math.Round(this.Y * 1000000000); + } + + public override string ToString() + { + return this.X.ToString("F3") + ", " + this.Y.ToString("F3"); + } + } +}