// Copyright (C) Stichting Deltares 2018. All rights reserved. // // This file is part of the Dam Engine. // // The Dam Engine is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; namespace Deltares.DamEngine.Data.Geometry { /// /// Geometry Line, connecting begin point to end point with a straight line. /// public class Line { private readonly Line line = new Line(); /// /// Initializes a new instance of the class. /// public Line() : this(null, null) {} /// /// Initializes a new instance of the class. /// /// The begin point. /// The end point. public Line(Point2D beginPoint, Point2D endPoint) { BeginPoint = beginPoint; EndPoint = endPoint; } /// /// Gets or sets the begin point. /// /// /// The begin point. /// public Point2D BeginPoint { get { return line.Start; } set { line.Start = value; } } /// /// Gets or sets the end point. /// /// /// The end point. /// public Point2D EndPoint { get { return line.End; } set { line.End = value; } } /// /// Creates the horizontal z line. /// /// The x1. /// The x2. /// The z. public void CreateHorizontalZLine(double x1, double x2, double z) { SetBeginAndEndPoints(new Point2D{ X = x1, Z = z}, new Point2D{ X = x2, Z = z}); } /// /// Sets the begin and end points. /// /// The begin point. /// The end point. public void SetBeginAndEndPoints(Point2D beginPoint, Point2D endPoint) { BeginPoint = beginPoint; EndPoint = endPoint; } /// /// Calculate intersection with another projected to the XZ plane. /// /// The other line segment. /// An intersection point in the XZ-plane, or null in case no intersection. public Point2D GetIntersectPointXz(Line other) { Point2D intersectionPoint; var isIntersecting = line.IntersectsZ(other.line, out intersectionPoint); return isIntersecting ? intersectionPoint : null; } } /// /// /// /// public class Line where T : Point2D, new() { /// /// Initializes a new instance of the class. /// public Line() : this(null, null) {} /// /// Initializes a new instance of the class. /// /// The start. /// The end. public Line(T start, T end) { Start = start; End = end; } /// /// Gets or sets the start. /// /// /// The start. /// public T Start { get; set; } /// /// Gets or sets the end. /// /// /// The end. /// public T End { get; set; } /// /// Intersectses the z. /// /// The line. /// The intersection point. /// public bool IntersectsZ(Line line, out T intersectionPoint) { return Intersects(line, out intersectionPoint); } private bool Intersects(Line line, out T intersectionPoint) { intersectionPoint = null; var dx1 = End.X - Start.X; var dx2 = line.End.X - line.Start.X; var dyz1 = End.Z - Start.Z; var dyz2 = line.End.Z - line.Start.Z; var yz = Start.Z; var yzLine = line.Start.Z; var noem = dx1*dyz2 - dyz1*dx2; if (Math.Abs(noem) > 0.0) { var u = (dx2*(yz - yzLine) - dyz2*(Start.X - line.Start.X))/noem; if ((u >= 0.0) && (u <= 1.0)) { var v = (dx1*(yz - yzLine) - dyz1*(Start.X - line.Start.X))/noem; if ((v >= 0.0) && (v <= 1.0)) { intersectionPoint = new T { X = Start.X + u * dx1, Z = yz + u * dyz1 }; return true; } } } return false; } } }