Index: DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs =================================================================== diff -u -r6025 -r6030 --- DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs (.../GeometryGenerator.cs) (revision 6025) +++ DamEngine/trunk/src/Deltares.DamEngine.Data/Geometry/GeometryGenerator.cs (.../GeometryGenerator.cs) (revision 6030) @@ -1071,17 +1071,6 @@ } } - protected internal static void DeterminePointClosestToAnotherPoint(Point2D point1, Point2D point2, Point2D point3, - ref bool isPoint1ClosestToPoint3, ref bool isPoint2ClosestToPoint3) - { - double distance1 = Routines2D.Compute2DDistance(point1.X, point1.Z, point3.X, point3.Z); - double distance2 = Routines2D.Compute2DDistance(point2.X, point2.Z, point3.X, point3.Z); - if (distance1 > distance2) - isPoint1ClosestToPoint3 = false; - else - isPoint2ClosestToPoint3 = false; - } - /// /// Regenerates all the Parallel curves. /// @@ -1115,152 +1104,233 @@ return true; } - double slope1 = DetermineSlope(line1); - double slope2 = DetermineSlope(line2); + CheckForNearParallelLines(line1, line2, ref isPoint1OnLine2, ref isPoint2OnLine2, ref isPoint3OnLine1, + ref isPoint4OnLine1); - const double accuracyAngle = 5E-12; - if (Math.Abs(Math.Abs(slope1) - Math.Abs(slope2)) > accuracyAngle) + // check for parallel + if ((isPoint1OnLine2 && isPoint2OnLine2) || (isPoint3OnLine1 && isPoint4OnLine1) + || ((isPoint3OnLine1 || isPoint4OnLine1) && (isPoint1OnLine2 || isPoint2OnLine2))) { - // lines are not (exactly) parallel - if (isPoint1OnLine2 && isPoint2OnLine2) + if (CheckCasesWhereLine1AndLine2Overlap(line1, line2, ref isCurveInserted, isPoint3OnLine1, isPoint4OnLine1, + isPoint1SameAsPoint3, isPoint2SameAsPoint3, isPoint2OnLine2, + isPoint1SameAsPoint4, isPoint2SameAsPoint4)) { - DeterminePointClosestToLine(localPoint1, localPoint2, line2, ref isPoint1OnLine2, ref isPoint2OnLine2); + return true; } - if (isPoint3OnLine1 && isPoint4OnLine1) + + if (CheckCasesWhereLine2IsInLine1(line1, line2, ref isCurveInserted, isPoint3OnLine1, isPoint4OnLine1, + isPoint1SameAsPoint3, isPoint2SameAsPoint4, isPoint2SameAsPoint3, + isPoint1SameAsPoint4)) { - DeterminePointClosestToLine(localPoint3, localPoint4, line1, ref isPoint3OnLine1, ref isPoint4OnLine1); + return true; } - if (isPoint1SameAsPoint3 && isPoint2SameAsPoint3) + + if (CheckCasesWhereLine1IsInLine2(line1, line2, ref isCurveInserted, isPoint1OnLine2, isPoint2OnLine2, + isPoint1SameAsPoint3, isPoint2SameAsPoint4, isPoint2SameAsPoint3, + isPoint1SameAsPoint4)) { - DeterminePointClosestToAnotherPoint(localPoint1, localPoint2, localPoint3, ref isPoint1SameAsPoint3, ref isPoint2SameAsPoint3); + return true; } - if (isPoint1SameAsPoint4 && isPoint2SameAsPoint4) + + if (CheckCasesWhereLine2IsInLine1WithOnePointEqual(line1, line2, isPoint4OnLine1, isPoint3OnLine1, + isPoint1SameAsPoint3, isPoint2SameAsPoint3, isPoint2SameAsPoint4)) { - DeterminePointClosestToAnotherPoint(localPoint1, localPoint2, localPoint4, ref isPoint1SameAsPoint4, ref isPoint2SameAsPoint4); + return true; } + + if (CheckCasesWhereLine1IsInLine2WithOnePointEqual(line1, line2, isPoint1OnLine2, isPoint2OnLine2, + isPoint1SameAsPoint3, isPoint1SameAsPoint4, isPoint2SameAsPoint4)) + { + return true; + } } - // check for parallel - if ((isPoint1OnLine2 && isPoint2OnLine2) || (isPoint3OnLine1 && isPoint4OnLine1) - || ((isPoint3OnLine1 || isPoint4OnLine1) && (isPoint1OnLine2 || isPoint2OnLine2))) + return false; + } + + private bool CheckCasesWhereLine1IsInLine2(GeometryCurve line1, GeometryCurve line2, ref bool isCurveInserted, + bool isPoint1OnLine2, bool isPoint2OnLine2, bool isPoint1SameAsPoint3, + bool isPoint2SameAsPoint4, bool isPoint2SameAsPoint3, bool isPoint1SameAsPoint4) + { + GeometryCurve newLine; + // p3----p1------p2----p4 + if (isPoint1OnLine2 && isPoint2OnLine2 && !isPoint1SameAsPoint3 && !isPoint2SameAsPoint4 && + !isPoint2SameAsPoint3 && !isPoint1SameAsPoint4) { - GeometryCurve newLine; - - // p1----p3------p2----p4 - if (isPoint3OnLine1 && !isPoint4OnLine1 && !isPoint1SameAsPoint3 && !isPoint2SameAsPoint3) - { - newLine = SplitCurve(line1, line2.HeadPoint); + double distance1 = Routines2D.Compute2DDistance(line2.HeadPoint.X, line2.HeadPoint.Z, line1.HeadPoint.X, line1.HeadPoint.Z); + double distance2 = Routines2D.Compute2DDistance(line2.HeadPoint.X, line2.HeadPoint.Z, line1.EndPoint.X, line1.EndPoint.Z); - line2.HeadPoint = isPoint2OnLine2 ? newLine.EndPoint : line1.HeadPoint; - - isCurveInserted = true; - return true; + if (distance1 < distance2) + { + newLine = SplitCurve(line2, line1.HeadPoint); + newLine.HeadPoint = line1.EndPoint; } + else + { + newLine = SplitCurve(line2, line1.EndPoint); + newLine.HeadPoint = line1.HeadPoint; + } + + isCurveInserted = true; + return true; + } - // p1----p4------p2----p3 - if (isPoint4OnLine1 && !isPoint3OnLine1 && !isPoint1SameAsPoint4 && !isPoint2SameAsPoint4) + return false; + } + + private bool CheckCasesWhereLine2IsInLine1(GeometryCurve line1, GeometryCurve line2, ref bool isCurveInserted, + bool isPoint3OnLine1, bool isPoint4OnLine1, bool isPoint1SameAsPoint3, + bool isPoint2SameAsPoint4, bool isPoint2SameAsPoint3, bool isPoint1SameAsPoint4) + { + GeometryCurve newLine; + // p1----p3------p4----p2 + if (isPoint3OnLine1 && isPoint4OnLine1 && !isPoint1SameAsPoint3 && !isPoint2SameAsPoint4 && + !isPoint2SameAsPoint3 && !isPoint1SameAsPoint4) + { + double distance1 = Routines2D.Compute2DDistance(line1.HeadPoint.X, line1.HeadPoint.Z, line2.HeadPoint.X, + line2.HeadPoint.Z); + double distance2 = Routines2D.Compute2DDistance(line1.HeadPoint.X, line1.HeadPoint.Z, line2.EndPoint.X, + line2.EndPoint.Z); + + if (distance1 < distance2) { + newLine = SplitCurve(line1, line2.HeadPoint); + newLine.HeadPoint = line2.EndPoint; + } + else + { newLine = SplitCurve(line1, line2.EndPoint); - line2.EndPoint = isPoint2OnLine2 ? newLine.EndPoint : line1.HeadPoint; - - isCurveInserted = true; - return true; + newLine.HeadPoint = line2.HeadPoint; } + + isCurveInserted = true; + return true; + } - // p1----p3------p4----p2 - if (isPoint3OnLine1 && isPoint4OnLine1 && !isPoint1SameAsPoint3 && !isPoint2SameAsPoint4 && - !isPoint2SameAsPoint3 && !isPoint1SameAsPoint4) - { - double distance1 = Routines2D.Compute2DDistance(localPoint1.X, localPoint1.Z, localPoint3.X, localPoint3.Z); - double distance2 = Routines2D.Compute2DDistance(localPoint1.X, localPoint1.Z, localPoint4.X, localPoint4.Z); + return false; + } - if (distance1 < distance2) - { - newLine = SplitCurve(line1, line2.HeadPoint); - newLine.HeadPoint = line2.EndPoint; - } - else - { - newLine = SplitCurve(line1, line2.EndPoint); - newLine.HeadPoint = line2.HeadPoint; - } + private bool CheckCasesWhereLine1AndLine2Overlap(GeometryCurve line1, GeometryCurve line2, ref bool isCurveInserted, + bool isPoint3OnLine1, bool isPoint4OnLine1, bool isPoint1SameAsPoint3, + bool isPoint2SameAsPoint3, bool isPoint2OnLine2, bool isPoint1SameAsPoint4, + bool isPoint2SameAsPoint4) + { + GeometryCurve newLine; + // p1----p3------p2----p4 + if (isPoint3OnLine1 && !isPoint4OnLine1 && !isPoint1SameAsPoint3 && !isPoint2SameAsPoint3) + { + newLine = SplitCurve(line1, line2.HeadPoint); + + line2.HeadPoint = isPoint2OnLine2 ? newLine.EndPoint : line1.HeadPoint; - isCurveInserted = true; - return true; - } + isCurveInserted = true; + return true; + } - // p3----p1------p2----p4 - if (isPoint1OnLine2 && isPoint2OnLine2 && !isPoint1SameAsPoint3 && !isPoint2SameAsPoint4 && - !isPoint2SameAsPoint3 && !isPoint1SameAsPoint4) - { - double distance1 = Routines2D.Compute2DDistance(localPoint3.X, localPoint3.Z, localPoint1.X, localPoint1.Z); - double distance2 = Routines2D.Compute2DDistance(localPoint3.X, localPoint3.Z, localPoint2.X, localPoint2.Z); - - if (distance1 < distance2) - { - newLine = SplitCurve(line2, line1.HeadPoint); - newLine.HeadPoint = line1.EndPoint; - } - else - { - newLine = SplitCurve(line2, line1.EndPoint); - newLine.HeadPoint = line1.HeadPoint; - } + // p1----p4------p2----p3 + if (isPoint4OnLine1 && !isPoint3OnLine1 && !isPoint1SameAsPoint4 && !isPoint2SameAsPoint4) + { + newLine = SplitCurve(line1, line2.EndPoint); + line2.EndPoint = isPoint2OnLine2 ? newLine.EndPoint : line1.HeadPoint; - isCurveInserted = true; - return true; - } + isCurveInserted = true; + return true; + } - // vertices coincidence cases - Line2 on Line1 - if (isPoint4OnLine1 && isPoint3OnLine1) + return false; + } + + private static bool CheckCasesWhereLine2IsInLine1WithOnePointEqual(GeometryCurve line1, GeometryCurve line2, + bool isPoint4OnLine1, bool isPoint3OnLine1, + bool isPoint1SameAsPoint3, bool isPoint2SameAsPoint3, + bool isPoint2SameAsPoint4) + { + if (isPoint4OnLine1 && isPoint3OnLine1) + { + // Line2 on Line1 like p1--p3--p4--p2, p2--p3--p4--p1 etc. + if (isPoint1SameAsPoint3) { - if (isPoint1SameAsPoint3) - { - // p1/p3----p4----p2 --> c1(p4, p2) & c2(p3, p4) - line1.HeadPoint = line2.EndPoint; - } - else if (isPoint2SameAsPoint3) - { - // p2/p3----p4----p1 --> c1(p1, p4) & c2(p3, p4) - line1.EndPoint = line2.EndPoint; - } - else if (isPoint2SameAsPoint4) - { - line1.EndPoint = line2.HeadPoint; - } - else - { - line1.HeadPoint = line2.HeadPoint; - } - return true; + // p1/p3----p4----p2 --> c1(p4, p2) & c2(p3, p4) + line1.HeadPoint = line2.EndPoint; } + else if (isPoint2SameAsPoint3) + { + // p2/p3----p4----p1 --> c1(p1, p4) & c2(p3, p4) + line1.EndPoint = line2.EndPoint; + } + else if (isPoint2SameAsPoint4) + { + // p2/p4----p3----p1 --> c1(p1, p3) & c2(p3, p4) + line1.EndPoint = line2.HeadPoint; + } + else + { + // p1/p4----p3----p2 --> c1(p3, p2) & c2(p3, p4) + line1.HeadPoint = line2.HeadPoint; + } - // Line1 on Line2 - if (isPoint1OnLine2 && isPoint2OnLine2) + return true; + } + + return false; + } + + private static bool CheckCasesWhereLine1IsInLine2WithOnePointEqual(GeometryCurve line1, GeometryCurve line2, + bool isPoint1OnLine2, bool isPoint2OnLine2, + bool isPoint1SameAsPoint3, bool isPoint1SameAsPoint4, + bool isPoint2SameAsPoint4) + { + // Line1 on Line2 like p3--p1--p2--p4, p4--p1--p2--p3 etc. + if (isPoint1OnLine2 && isPoint2OnLine2) + { + if (isPoint1SameAsPoint3) { - if (isPoint1SameAsPoint3) - { - line2.HeadPoint = line1.EndPoint; - } - else if (isPoint1SameAsPoint4) - { - line2.EndPoint = line1.EndPoint; - } - else if (isPoint2SameAsPoint4) - { - line2.EndPoint = line1.HeadPoint; - } - else - { - line2.HeadPoint = line1.HeadPoint; - } - return true; + //p3/p1--p2--p4 + line2.HeadPoint = line1.EndPoint; } + else if (isPoint1SameAsPoint4) + { + //p4/p1--p2--p3 + line2.EndPoint = line1.EndPoint; + } + else if (isPoint2SameAsPoint4) + { + //p4/p2--p1--p3 + line2.EndPoint = line1.HeadPoint; + } + else + { + //p3/p2--p1--p4 + line2.HeadPoint = line1.HeadPoint; + } + + return true; } return false; } + private static void CheckForNearParallelLines(GeometryCurve line1, GeometryCurve line2, ref bool isPoint1OnLine2, + ref bool isPoint2OnLine2, ref bool isPoint3OnLine1, ref bool isPoint4OnLine1) + { + double slope1 = DetermineSlope(line1); + double slope2 = DetermineSlope(line2); + const double accuracyAngle = 5E-12; + if (Math.Abs(Math.Abs(slope1) - Math.Abs(slope2)) > accuracyAngle) + { + if (isPoint1OnLine2 && isPoint2OnLine2) + { + // lines are not (exactly) parallel but within the geometry accuracy off each other + DeterminePointClosestToLine(line1.HeadPoint, line1.EndPoint, line2, ref isPoint1OnLine2, ref isPoint2OnLine2); + } + if (isPoint3OnLine1 && isPoint4OnLine1) + { + // lines are not (exactly) parallel but within the geometry accuracy off each other + DeterminePointClosestToLine(line2.HeadPoint, line2.EndPoint, line1, ref isPoint3OnLine1, ref isPoint4OnLine1); + } + } + } + private GeometryCurve SplitCurve(GeometryCurve srcCurve, Point2D pointOnCurve) { if (pointOnCurve.LocationEquals(srcCurve.HeadPoint) || pointOnCurve.LocationEquals(srcCurve.EndPoint))