/// <summary> /// Returns a color from this gradient at the specified lerp value. /// </summary> /// <param name="amount">The lerp amount.</param> /// <returns>A color.</returns> public Color Lerp(float amount) { if (Stops.Length == 0) { throw new global::System.IndexOutOfRangeException("The ColorGradient object does not have any gradient stops defined."); } else if (Stops.Length == 1) { return(Stops[0].Color); } int counter; for (counter = 0; counter < Stops.Length && Stops[counter].Stop < amount; counter++) { ; } counter--; counter = (int)MyMathHelper.Clamp(counter, 0, Stops.Length - 2); float newLerp = (Stops[counter].Stop - (float)amount) / (Stops[counter].Stop - Stops[counter + 1].Stop); return(ColorHelper.Lerp(Stops[counter].Color, Stops[counter + 1].Color, newLerp)); }
/// <summary> /// Processes an area and applies a gradient calculation to each part of the area. /// </summary> /// <param name="position">The center of the gradient.</param> /// <param name="strength">The width of the gradient spread.</param> /// <param name="angle">The angle to apply the gradient.</param> /// <param name="area">The area to calculate.</param> /// <param name="applyAction">The callback called for each part of the area.</param> public static void GradientFill(Point cellSize, Point position, int strength, int angle, Rectangle area, ColorGradient gradient, Action <int, int, Color> applyAction) { double radians = angle * Math.PI / 180; // = Math.Atan2(x1 - x2, y1 - y2); Vector2 angleVector = new Vector2((float)(Math.Sin(radians) * strength), (float)(Math.Cos(radians) * strength)) / 2; Vector2 location = new Vector2(position.X, position.Y); if (cellSize.X > cellSize.Y) { angleVector.Y *= cellSize.X / cellSize.Y; } else if (cellSize.X < cellSize.Y) { angleVector.X *= cellSize.Y / cellSize.X; } Vector2 endingPoint = location + angleVector; Vector2 startingPoint = location - angleVector; double x1 = (startingPoint.X / (double)area.Width) * 2.0f - 1.0f; double y1 = (startingPoint.Y / (double)area.Height) * 2.0f - 1.0f; double x2 = (endingPoint.X / (double)area.Width) * 2.0f - 1.0f; double y2 = (endingPoint.Y / (double)area.Height) * 2.0f - 1.0f; double start = x1 * angleVector.X + y1 * angleVector.Y; double end = x2 * angleVector.X + y2 * angleVector.Y; for (int x = area.Left; x < area.Width; x++) { for (int y = area.Top; y < area.Height; y++) { // but we need vectors from (-1, -1) to (1, 1) // instead of pixels from (0, 0) to (width, height) double u = (x / (double)area.Width) * 2.0f - 1.0f; double v = (y / (double)area.Height) * 2.0f - 1.0f; double here = u * angleVector.X + v * angleVector.Y; double lerp = (start - here) / (start - end); //lerp = Math.Abs((lerp - (int)lerp)); lerp = MyMathHelper.Clamp((float)lerp, 0f, 1.0f); int counter; for (counter = 0; counter < gradient.Stops.Length && gradient.Stops[counter].Stop < (float)lerp; counter++) { ; } counter--; counter = (int)MyMathHelper.Clamp(counter, 0, gradient.Stops.Length - 2); float newLerp = (gradient.Stops[counter].Stop - (float)lerp) / (gradient.Stops[counter].Stop - gradient.Stops[counter + 1].Stop); applyAction(x, y, ColorHelper.Lerp(gradient.Stops[counter].Color, gradient.Stops[counter + 1].Color, newLerp)); } } }
/// <summary> /// Creates a <see cref="SadConsole.ColoredString"/> object using the current gradient. /// </summary> /// <param name="text">The text to use for the colored string.</param> /// <returns>A new colored string object.</returns> public SadConsole.ColoredString ToColoredString(string text) { SadConsole.ColoredString stringObject = new SadConsole.ColoredString(text); if (Stops.Length == 0) { throw new global::System.IndexOutOfRangeException("The ColorGradient object does not have any gradient stops defined."); } else if (Stops.Length == 1) { stringObject.SetForeground(Stops[0].Color); return(stringObject); } float lerp = 1f / (text.Length - 1); float lerpTotal = 0f; stringObject[0].Foreground = Stops[0].Color; stringObject[text.Length - 1].Foreground = Stops[Stops.Length - 1].Color; for (int i = 1; i < text.Length - 1; i++) { lerpTotal += lerp; int counter; for (counter = 0; counter < Stops.Length && Stops[counter].Stop < lerpTotal; counter++) { ; } counter--; counter = (int)MyMathHelper.Clamp(counter, 0, Stops.Length - 2); float newLerp = (Stops[counter].Stop - (float)lerpTotal) / (Stops[counter].Stop - Stops[counter + 1].Stop); stringObject[i].Foreground = ColorHelper.Lerp(Stops[counter].Color, Stops[counter + 1].Color, newLerp); } return(stringObject); }