using System; using System.Collections.Generic; using System.Text; using static Matrix_App.Defaults; namespace Matrix_App { public static class GifGeneratorUtils { public static float Dot(in float x0, in float y0, in float x1, in float y1) { return x0 * x1 + y0 * y1; } public static void CartesianToPolar(in float x, in float y, out float theta, out float r) { r = MathF.Sqrt(x * x + y * y); theta = MathF.Atan2(y, x); } public static void PolarToCartesian(in float theta, in float r, out float x, out float y) { x = MathF.Sin(theta) * r; y = MathF.Cos(theta) * r; } public static void Normalize(ref float x, ref float y) { var len = MathF.Sqrt(x * x + y * y); x /= len; y /= len; } public static void RgbFromHsl(float h, float s, float l, out float r, out float g, out float b) { var c = (1 - MathF.Abs(2 * l - 1)) * s; var x = c * (1.0f - Math.Abs((h / 60.0f) % 2.0f - 1.0f)); var m = l - c * 0.5f; if (h < 60) { r = c; g = x; b = 0; } else if (h < 120) { r = x; g = c; b = 0; } else if (h < 180) { r = 0; g = c; b = x; } else if (h < 240) { r = 0; g = x; b = c; } else if (h < 300) { r = x; g = 0; b = c; } else { r = c; g = 0; b = x; } r += m; g += m; b += m; } public static void HslFromRgb(float r, float g, float b, out float h, out float s, out float l) { var cmax = Math.Max(Math.Max(r, g), b); var cmin = Math.Min(Math.Min(r, g), b); var delta = cmax - cmin; if (delta < 1e-2) { h = 0; } else if (MathF.Abs(cmax - r) < 1e-3) { if (r < b) { h = 360 - MathF.Abs(60 * ((g - b) / delta)); } else { h = 60 * ((g - b) / delta + 0f); } } else if (MathF.Abs(cmax - g) < 1e-3) { h = 60 * ((b - r) / delta + 2f); } else if (MathF.Abs(cmax - b) < 1e-3) { h = 60 * ((r - g) / delta + 4f); } else { h = 0; } l = (cmax + cmin) * 0.5f; s = (cmax - cmin) / (1 - MathF.Abs(2 * l - 1.0f)); } public static void RgbFromHsv(float h, float s, float v, out float r, out float g, out float b) { var c = v * s; var x = c * (1.0f - Math.Abs((h / 60.0f) % 2.0f - 1.0f)); var m = v - c; if (h < 60) { r = c; g = x; b = 0; } else if (h < 120) { r = x; g = c; b = 0; } else if (h < 180) { r = 0; g = c; b = x; } else if (h < 240) { r = 0; g = x; b = c; } else if (h < 300) { r = x; g = 0; b = c; } else { r = c; g = 0; b = x; } r += m; g += m; b += m; } public static void HsvFromRgb(float r, float g, float b, out float h, out float s, out float v) { var cmax = Math.Max(Math.Max(r, g), b); var cmin = Math.Min(Math.Min(r, g), b); var delta = cmax - cmin; if (delta < 1e-2) { h = 0; } else if (MathF.Abs(cmax - r) < 1e-3) { if (r < b) { h = 360 - MathF.Abs(60 * ((g - b) / delta)); } else { h = 60 * ((g - b) / delta + 0f); } } else if (MathF.Abs(cmax - g) < 1e-3) { h = 60 * ((b - r) / delta + 2f); } else if (MathF.Abs(cmax - b) < 1e-3) { h = 60 * ((r - g) / delta + 4f); } else { h = 0; } s = delta / cmax; if (cmax == 0) { s = 0; } v = cmax; } public static void SampleFrame(in byte[][] sampler, int frame, int x, int y, int width, out float r, out float g, out float b) { var index = (x + y * width) * Bpp; // normalize pixel value to [0, 1] r = sampler[frame][index + 0] * 0.00392156862745f; g = sampler[frame][index + 1] * 0.00392156862745f; b = sampler[frame][index + 2] * 0.00392156862745f; } public static float Saturate(float x) { return x < 0.0f ? 0.0f : x > 1.0f ? 1.0f : x; } } }