// ReSharper disable MemberCanBePrivate.Global using System; using RGB.NET.Core; namespace RGB.NET.Brushes.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 given 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 double CalculateLinearGradientOffset(Point startPoint, Point endPoint, Point point) { Point intersectingPoint; if (startPoint.Y.Equals(endPoint.Y)) // Horizontal case intersectingPoint = new Point(point.X, startPoint.Y); else if (startPoint.X.Equals(endPoint.X)) // Vertical case intersectingPoint = new Point(startPoint.X, point.Y); else // Diagonal case { double slope = (endPoint.Y - startPoint.Y) / (endPoint.X - startPoint.X); double orthogonalSlope = -1 / slope; double startYIntercept = startPoint.Y - (slope * startPoint.X); double pointYIntercept = point.Y - (orthogonalSlope * point.X); double intersectingPointX = (pointYIntercept - startYIntercept) / (slope - orthogonalSlope); double intersectingPointY = (slope * intersectingPointX) + startYIntercept; intersectingPoint = new Point(intersectingPointX, intersectingPointY); } // Calculate distances relative to the vector start double intersectDistance = CalculateDistance(intersectingPoint, startPoint, endPoint); double 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 double CalculateDistance(Point point, Point origin, Point direction) { double distance = CalculateDistance(point, origin); return (((point.Y < origin.Y) && (direction.Y > origin.Y)) || ((point.Y > origin.Y) && (direction.Y < origin.Y)) || ((point.Y.Equals(origin.Y)) && (point.X < origin.X) && (direction.X > origin.X)) || ((point.Y.Equals(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 double CalculateDistance(Point point1, Point point2) => Math.Sqrt(((point1.Y - point2.Y) * (point1.Y - point2.Y)) + ((point1.X - point2.X) * (point1.X - point2.X))); #endregion } }