// ReSharper disable MemberCanBePrivate.Global
using System;
using RGB.NET.Core;
namespace RGB.NET.Presets.Helper;
///
/// Offers some extensions and helper-methods for gradient related things.
///
public static class GradientHelper
{
#region Methods
// Based on https://web.archive.org/web/20170125201230/https://dotupdate.wordpress.com/2008/01/28/find-the-color-of-a-point-in-a-lineargradientbrush/
///
/// Calculates the offset of an specified on an gradient.
///
/// The start of the gradient.
/// The end of the gradient.
/// The on the gradient to which the offset is calculated.
/// The offset of the on the gradient.
public static float CalculateLinearGradientOffset(Point startPoint, Point endPoint, Point point)
{
Point intersectingPoint;
if (startPoint.Y.EqualsInTolerance(endPoint.Y)) // Horizontal case
intersectingPoint = new Point(point.X, startPoint.Y);
else if (startPoint.X.EqualsInTolerance(endPoint.X)) // Vertical case
intersectingPoint = new Point(startPoint.X, point.Y);
else // Diagonal case
{
float slope = (endPoint.Y - startPoint.Y) / (endPoint.X - startPoint.X);
float orthogonalSlope = -1 / slope;
float startYIntercept = startPoint.Y - (slope * startPoint.X);
float pointYIntercept = point.Y - (orthogonalSlope * point.X);
float intersectingPointX = (pointYIntercept - startYIntercept) / (slope - orthogonalSlope);
float intersectingPointY = (slope * intersectingPointX) + startYIntercept;
intersectingPoint = new Point(intersectingPointX, intersectingPointY);
}
// Calculate distances relative to the vector start
float intersectDistance = CalculateDistance(intersectingPoint, startPoint, endPoint);
float gradientLength = CalculateDistance(endPoint, startPoint, endPoint);
return intersectDistance / gradientLength;
}
// Based on https://web.archive.org/web/20170125201230/https://dotupdate.wordpress.com/2008/01/28/find-the-color-of-a-point-in-a-lineargradientbrush/
///
/// Returns the signed magnitude of a on a vector.
///
/// The on the vector of which the magnitude should be calculated.
/// The origin of the vector.
/// The direction of the vector.
/// The signed magnitude of a on a vector.
public static float CalculateDistance(Point point, Point origin, Point direction)
{
float distance = CalculateDistance(point, origin);
return (((point.Y < origin.Y) && (direction.Y > origin.Y))
|| ((point.Y > origin.Y) && (direction.Y < origin.Y))
|| ((point.Y.EqualsInTolerance(origin.Y)) && (point.X < origin.X) && (direction.X > origin.X))
|| ((point.Y.EqualsInTolerance(origin.Y)) && (point.X > origin.X) && (direction.X < origin.X)))
? -distance : distance;
}
///
/// Calculated the distance between two .
///
/// The first .
/// The second .
/// The distance between the two .
public static float CalculateDistance(Point point1, Point point2)
{
float x = point1.X - point2.X;
float y = point1.Y - point2.Y;
return MathF.Sqrt((y * y) + (x * x));
}
#endregion
}