// Copyright (C) Stichting Deltares 2016. All rights reserved.
//
// This file is part of Ringtoets.
//
// Ringtoets is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser 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 Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser 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;
using MathNet.Numerics.LinearAlgebra;
namespace Core.Common.Base.Geometry
{
///
/// Extension methods for .
///
public static class Point3DExtensions
{
///
/// This method defines the 'spanning line' as the 2D vector going from
/// to . Then the is projected onto
/// this vector. Then the local coordinate is determined by taking the length of each vector along the 'spanning line'.
///
/// The point to project.
/// The start of the 'spanning line'.
/// The end point of the 'spanning line'.
/// Thrown when either:
///
/// - is null.
/// - is null.
/// - is null.
///
///
/// Thrown when the
/// and the are the same.
public static Point2D ProjectIntoLocalCoordinates(this Point3D worldCoordinate, Point2D startWorldCoordinate, Point2D endWorldCoordinate)
{
if (worldCoordinate == null)
{
throw new ArgumentNullException("worldCoordinate");
}
if (startWorldCoordinate == null)
{
throw new ArgumentNullException("startWorldCoordinate");
}
if (endWorldCoordinate == null)
{
throw new ArgumentNullException("endWorldCoordinate");
}
Point2D worldCoordinate2D = new Point2D(worldCoordinate.X, worldCoordinate.Y);
Vector vectorToPoint = (worldCoordinate2D - startWorldCoordinate);
// Determine the 'spanning line' vector:
Vector spanningVector = endWorldCoordinate - startWorldCoordinate;
double spanningVectorDotProduct = spanningVector.DotProduct(spanningVector);
double length = Math.Sqrt(spanningVectorDotProduct);
if (Math.Abs(length) < 1e-6)
{
throw new ArgumentException("The startWorldCoordinate and endWorldCoordinate can't be the same.");
}
// Project vector onto the 'spanning vector' to determine it's X coordinate in local coordinates:
double projectOnSpanningVectorFactor = (vectorToPoint.DotProduct(spanningVector)) / spanningVectorDotProduct;
double localCoordinateX = projectOnSpanningVectorFactor * length;
return new Point2D(localCoordinateX, worldCoordinate.Z);
}
}
}