// 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;
}
}
}