From 8e0b8ae883a6c9a1952051ae45c4635488065639 Mon Sep 17 00:00:00 2001 From: Darth Affe Date: Sat, 5 Aug 2017 16:32:10 +0200 Subject: [PATCH] Fixed gradient calculation (moving gradients caused issues) --- RGB.NET.Brushes/Gradients/AbstractGradient.cs | 11 +-- RGB.NET.Brushes/Gradients/LinearGradient.cs | 72 +++++++++++-------- RGB.NET.Brushes/Gradients/RainbowGradient.cs | 4 +- 3 files changed, 52 insertions(+), 35 deletions(-) diff --git a/RGB.NET.Brushes/Gradients/AbstractGradient.cs b/RGB.NET.Brushes/Gradients/AbstractGradient.cs index 3ed396b..dcd50ce 100644 --- a/RGB.NET.Brushes/Gradients/AbstractGradient.cs +++ b/RGB.NET.Brushes/Gradients/AbstractGradient.cs @@ -88,14 +88,15 @@ namespace RGB.NET.Brushes.Gradients offset /= 360.0; foreach (GradientStop gradientStop in GradientStops) - { - gradientStop.Offset = gradientStop.Offset + offset; + gradientStop.Offset += offset; - if (gradientStop.Offset > 1) + while (GradientStops.All(x => x.Offset > 1)) + foreach (GradientStop gradientStop in GradientStops) gradientStop.Offset -= 1; - else if (gradientStop.Offset < 0) + + while (GradientStops.All(x => x.Offset < 0)) + foreach (GradientStop gradientStop in GradientStops) gradientStop.Offset += 1; - } } #endregion diff --git a/RGB.NET.Brushes/Gradients/LinearGradient.cs b/RGB.NET.Brushes/Gradients/LinearGradient.cs index cbe66d8..0392056 100644 --- a/RGB.NET.Brushes/Gradients/LinearGradient.cs +++ b/RGB.NET.Brushes/Gradients/LinearGradient.cs @@ -48,35 +48,9 @@ namespace RGB.NET.Brushes.Gradients public override Color GetColor(double offset) { if (GradientStops.Count == 0) return Color.Transparent; - if (GradientStops.Count == 1) return new Color(GradientStops.First().Color); + if (GradientStops.Count == 1) return new Color(GradientStops[0].Color); - GradientStop gsBefore; - GradientStop gsAfter; - - IList orderedStops = GradientStops.OrderBy(x => x.Offset).ToList(); - if (WrapGradient) - { - gsBefore = orderedStops.LastOrDefault(n => n.Offset <= offset); - if (gsBefore == null) - { - GradientStop lastStop = orderedStops[orderedStops.Count - 1]; - gsBefore = new GradientStop(lastStop.Offset - 1, lastStop.Color); - } - - gsAfter = orderedStops.FirstOrDefault(n => n.Offset >= offset); - if (gsAfter == null) - { - GradientStop firstStop = orderedStops[0]; - gsAfter = new GradientStop(firstStop.Offset + 1, firstStop.Color); - } - } - else - { - offset = ClipOffset(offset); - - gsBefore = orderedStops.Last(n => n.Offset <= offset); - gsAfter = orderedStops.First(n => n.Offset >= offset); - } + (GradientStop gsBefore, GradientStop gsAfter) = GetEnclosingGradientStops(offset, GradientStops, WrapGradient); double blendFactor = 0; if (!gsBefore.Offset.Equals(gsAfter.Offset)) @@ -90,6 +64,48 @@ namespace RGB.NET.Brushes.Gradients return new Color(colA, colR, colG, colB); } + /// + /// Get the two s encapsulating the given offset. + /// + /// The reference offset. + /// The to choose from. + /// Bool indicating if the gradient should be wrapped or not. + /// + protected virtual (GradientStop gsBefore, GradientStop gsAfter) GetEnclosingGradientStops(double offset, IEnumerable stops, bool wrap) + { + LinkedList orderedStops = new LinkedList(stops.OrderBy(x => x.Offset)); + + if (wrap) + { + GradientStop gsBefore, gsAfter; + + do + { + gsBefore = orderedStops.LastOrDefault(n => n.Offset <= offset); + if (gsBefore == null) + { + GradientStop lastStop = orderedStops.Last.Value; + orderedStops.AddFirst(new GradientStop(lastStop.Offset - 1, lastStop.Color)); + orderedStops.RemoveLast(); + } + + gsAfter = orderedStops.FirstOrDefault(n => n.Offset >= offset); + if (gsAfter == null) + { + GradientStop firstStop = orderedStops.First.Value; + orderedStops.AddLast(new GradientStop(firstStop.Offset + 1, firstStop.Color)); + orderedStops.RemoveFirst(); + } + + } while ((gsBefore == null) || (gsAfter == null)); + + return (gsBefore, gsAfter); + } + + offset = ClipOffset(offset); + return (orderedStops.Last(n => n.Offset <= offset), orderedStops.First(n => n.Offset >= offset)); + } + #endregion } } diff --git a/RGB.NET.Brushes/Gradients/RainbowGradient.cs b/RGB.NET.Brushes/Gradients/RainbowGradient.cs index a35591c..a254a62 100644 --- a/RGB.NET.Brushes/Gradients/RainbowGradient.cs +++ b/RGB.NET.Brushes/Gradients/RainbowGradient.cs @@ -65,12 +65,12 @@ namespace RGB.NET.Brushes.Gradients StartHue += offset; EndHue += offset; - if ((StartHue > 360) && (EndHue > 360)) + while ((StartHue > 360) && (EndHue > 360)) { StartHue -= 360; EndHue -= 360; } - else if ((StartHue < -360) && (EndHue < -360)) + while ((StartHue < -360) && (EndHue < -360)) { StartHue += 360; EndHue += 360;