167 lines
4.9 KiB
C#
167 lines
4.9 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|