Some color things. More to come.
This commit is contained in:
parent
27c64c4291
commit
866326863b
10
Nerd_STF/Graphics/ColorChannel.cs
Normal file
10
Nerd_STF/Graphics/ColorChannel.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace Nerd_STF.Graphics
|
||||||
|
{
|
||||||
|
public enum ColorChannel
|
||||||
|
{
|
||||||
|
Red,
|
||||||
|
Green,
|
||||||
|
Blue,
|
||||||
|
Alpha
|
||||||
|
}
|
||||||
|
}
|
||||||
359
Nerd_STF/Graphics/ColorRGB.cs
Normal file
359
Nerd_STF/Graphics/ColorRGB.cs
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
using Nerd_STF.Exceptions;
|
||||||
|
using Nerd_STF.Mathematics;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Nerd_STF.Graphics
|
||||||
|
{
|
||||||
|
public struct ColorRGB : IColor<ColorRGB>
|
||||||
|
#if CS11_OR_GREATER
|
||||||
|
,IFromTuple<ColorRGB, (double, double, double)>,
|
||||||
|
IFromTuple<ColorRGB, (double, double, double, double)>,
|
||||||
|
ISplittable<ColorRGB, (double[] Rs, double[] Gs, double[] Bs, double[] As)>
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
public static int ChannelCount => 4;
|
||||||
|
|
||||||
|
public static ColorRGB Black => new ColorRGB(0, 0, 0, 1);
|
||||||
|
public static ColorRGB Blue => new ColorRGB(0, 0, 1, 1);
|
||||||
|
public static ColorRGB Clear => new ColorRGB(0, 0, 0, 0);
|
||||||
|
public static ColorRGB Cyan => new ColorRGB(0, 1, 1, 1);
|
||||||
|
public static ColorRGB Gray => new ColorRGB(0.5, 0.5, 0.5, 1);
|
||||||
|
public static ColorRGB Green => new ColorRGB(0, 1, 0, 1);
|
||||||
|
public static ColorRGB Magenta => new ColorRGB(1, 0, 1, 1);
|
||||||
|
public static ColorRGB Orange => new ColorRGB(1, 0.5, 0, 1);
|
||||||
|
public static ColorRGB Purple => new ColorRGB(0.5, 0, 1, 1);
|
||||||
|
public static ColorRGB Red => new ColorRGB(1, 0, 0, 1);
|
||||||
|
public static ColorRGB White => new ColorRGB(1, 1, 1, 1);
|
||||||
|
public static ColorRGB Yellow => new ColorRGB(1, 1, 0, 1);
|
||||||
|
|
||||||
|
public double Magnitude => MathE.Sqrt(r * r + g * g + b * b);
|
||||||
|
|
||||||
|
public double r, g, b, a;
|
||||||
|
|
||||||
|
public ColorRGB(double r, double g, double b)
|
||||||
|
{
|
||||||
|
this.r = r;
|
||||||
|
this.g = g;
|
||||||
|
this.b = b;
|
||||||
|
a = 1;
|
||||||
|
}
|
||||||
|
public ColorRGB(double r, double g, double b, double a)
|
||||||
|
{
|
||||||
|
this.r = r;
|
||||||
|
this.g = g;
|
||||||
|
this.b = b;
|
||||||
|
this.a = a;
|
||||||
|
}
|
||||||
|
public ColorRGB(IEnumerable<double> nums)
|
||||||
|
{
|
||||||
|
r = 0;
|
||||||
|
g = 0;
|
||||||
|
b = 0;
|
||||||
|
a = 1;
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
foreach (double item in nums)
|
||||||
|
{
|
||||||
|
this[index] = item;
|
||||||
|
index++;
|
||||||
|
if (index == 4) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public ColorRGB(Fill<double> fill)
|
||||||
|
{
|
||||||
|
r = fill(0);
|
||||||
|
g = fill(1);
|
||||||
|
b = fill(2);
|
||||||
|
a = fill(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public double this[int index]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: return r;
|
||||||
|
case 1: return g;
|
||||||
|
case 2: return b;
|
||||||
|
case 3: return a;
|
||||||
|
default: throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0: r = value; break;
|
||||||
|
case 1: g = value; break;
|
||||||
|
case 2: b = value; break;
|
||||||
|
case 3: a = value; break;
|
||||||
|
default: throw new ArgumentOutOfRangeException(nameof(index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public ListTuple<double> this[string key]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
double[] items = new double[key.Length];
|
||||||
|
for (int i = 0; i < key.Length; i++)
|
||||||
|
{
|
||||||
|
char c = key[i];
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'r': items[i] = r; break;
|
||||||
|
case 'g': items[i] = g; break;
|
||||||
|
case 'b': items[i] = b; break;
|
||||||
|
case 'a': items[i] = a; break;
|
||||||
|
default: throw new ArgumentException("Invalid key.", nameof(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ListTuple<double>(items);
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
IEnumerator<double> stepper = value.GetEnumerator();
|
||||||
|
for (int i = 0; i < key.Length; i++)
|
||||||
|
{
|
||||||
|
char c = key[i];
|
||||||
|
stepper.MoveNext();
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case 'r': r = stepper.Current; break;
|
||||||
|
case 'g': g = stepper.Current; break;
|
||||||
|
case 'b': b = stepper.Current; break;
|
||||||
|
case 'a': a = stepper.Current; break;
|
||||||
|
default: throw new ArgumentException("Invalid key.", nameof(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ColorRGB Average(double gamma, IEnumerable<ColorRGB> colors)
|
||||||
|
{
|
||||||
|
double avgR = 0, avgG = 0, avgB = 0, avgA = 0;
|
||||||
|
int count = 0;
|
||||||
|
foreach (ColorRGB color in colors)
|
||||||
|
{
|
||||||
|
double correctR = MathE.Pow(color.r, gamma),
|
||||||
|
correctG = MathE.Pow(color.g, gamma),
|
||||||
|
correctB = MathE.Pow(color.b, gamma);
|
||||||
|
// Gamma doesn't apply to the alpha channel.
|
||||||
|
|
||||||
|
avgR += correctR;
|
||||||
|
avgG += correctG;
|
||||||
|
avgB += correctB;
|
||||||
|
avgA += color.a;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
avgR /= count;
|
||||||
|
avgG /= count;
|
||||||
|
avgB /= count;
|
||||||
|
avgA /= count;
|
||||||
|
double invGamma = 1 / gamma;
|
||||||
|
return new ColorRGB(MathE.Pow(avgR, invGamma),
|
||||||
|
MathE.Pow(avgG, invGamma),
|
||||||
|
MathE.Pow(avgB, invGamma),
|
||||||
|
avgA);
|
||||||
|
}
|
||||||
|
public static ColorRGB Clamp(ColorRGB color, ColorRGB min, ColorRGB max) =>
|
||||||
|
new ColorRGB(MathE.Clamp(color.r, min.r, max.r),
|
||||||
|
MathE.Clamp(color.g, min.g, max.g),
|
||||||
|
MathE.Clamp(color.b, min.b, max.b),
|
||||||
|
MathE.Clamp(color.a, min.a, max.a));
|
||||||
|
public static ColorRGB ClampMagnitude(ColorRGB color, double minMag, double maxMag)
|
||||||
|
{
|
||||||
|
ColorRGB copy = color;
|
||||||
|
ClampMagnitude(ref copy, minMag, maxMag);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
public static void ClampMagnitude(ref ColorRGB color, double minMag, double maxMag)
|
||||||
|
{
|
||||||
|
if (minMag > maxMag) throw new ClampOrderMismatchException(nameof(minMag), nameof(maxMag));
|
||||||
|
double mag = color.Magnitude;
|
||||||
|
|
||||||
|
if (mag < minMag)
|
||||||
|
{
|
||||||
|
double factor = minMag / mag;
|
||||||
|
color.r *= factor;
|
||||||
|
color.g *= factor;
|
||||||
|
color.b *= factor;
|
||||||
|
}
|
||||||
|
else if (mag > maxMag)
|
||||||
|
{
|
||||||
|
double factor = maxMag / mag;
|
||||||
|
color.r *= factor;
|
||||||
|
color.g *= factor;
|
||||||
|
color.b *= factor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static double Dot(ColorRGB a, ColorRGB b) => a.r * b.r + a.g * b.g + a.b * b.b;
|
||||||
|
public static double Dot(IEnumerable<ColorRGB> colors)
|
||||||
|
{
|
||||||
|
bool any = false;
|
||||||
|
double r = 1, g = 1, b = 1;
|
||||||
|
foreach (ColorRGB c in colors)
|
||||||
|
{
|
||||||
|
r *= c.r;
|
||||||
|
g *= c.g;
|
||||||
|
b *= c.b;
|
||||||
|
}
|
||||||
|
return any ? (r + g + b) : 0;
|
||||||
|
}
|
||||||
|
public static ColorRGB Lerp(double gamma, ColorRGB a, ColorRGB b, double t, bool clamp = true)
|
||||||
|
{
|
||||||
|
double aCorrectedR = MathE.Pow(a.r, gamma),
|
||||||
|
aCorrectedG = MathE.Pow(a.g, gamma),
|
||||||
|
aCorrectedB = MathE.Pow(a.b, gamma),
|
||||||
|
bCorrectedR = MathE.Pow(b.r, gamma),
|
||||||
|
bCorrectedG = MathE.Pow(b.g, gamma),
|
||||||
|
bCorrectedB = MathE.Pow(b.b, gamma);
|
||||||
|
// Gamma doesn't apply to the alpha channel.
|
||||||
|
|
||||||
|
double newR = MathE.Lerp(aCorrectedR, bCorrectedR, t, clamp),
|
||||||
|
newG = MathE.Lerp(aCorrectedG, bCorrectedG, t, clamp),
|
||||||
|
newB = MathE.Lerp(aCorrectedB, bCorrectedB, t, clamp),
|
||||||
|
newA = MathE.Lerp(a.a, b.a, t, clamp);
|
||||||
|
|
||||||
|
double invGamma = 1 / gamma;
|
||||||
|
return new ColorRGB(MathE.Pow(newR, invGamma),
|
||||||
|
MathE.Pow(newG, invGamma),
|
||||||
|
MathE.Pow(newB, invGamma),
|
||||||
|
newA);
|
||||||
|
}
|
||||||
|
#if CS11_OR_GREATER
|
||||||
|
static ColorRGB IInterpolable<ColorRGB>.Lerp(ColorRGB a, ColorRGB b, double t, bool clamp) => Lerp(1, a, b, t, clamp);
|
||||||
|
#endif
|
||||||
|
public static ColorRGB Product(IEnumerable<ColorRGB> colors)
|
||||||
|
{
|
||||||
|
bool any = false;
|
||||||
|
ColorRGB result = new ColorRGB(1, 1, 1, 1);
|
||||||
|
foreach (ColorRGB color in colors)
|
||||||
|
{
|
||||||
|
any = true;
|
||||||
|
result *= color;
|
||||||
|
}
|
||||||
|
return any ? result : Black;
|
||||||
|
}
|
||||||
|
public static ColorRGB Sum(IEnumerable<ColorRGB> colors)
|
||||||
|
{
|
||||||
|
bool any = false;
|
||||||
|
ColorRGB result = new ColorRGB(0, 0, 0, 1);
|
||||||
|
foreach (ColorRGB color in colors)
|
||||||
|
{
|
||||||
|
any = true;
|
||||||
|
result += color;
|
||||||
|
}
|
||||||
|
return any ? result : Black;
|
||||||
|
}
|
||||||
|
public static (double[] Rs, double[] Gs, double[] Bs, double[] As) SplitArray(IEnumerable<ColorRGB> colors)
|
||||||
|
{
|
||||||
|
int count = colors.Count();
|
||||||
|
double[] Rs = new double[count], Gs = new double[count], Bs = new double[count], As = new double[count];
|
||||||
|
int index = 0;
|
||||||
|
foreach (ColorRGB c in colors)
|
||||||
|
{
|
||||||
|
Rs[index] = c.r;
|
||||||
|
Gs[index] = c.g;
|
||||||
|
Bs[index] = c.b;
|
||||||
|
As[index] = c.a;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
return (Rs, Gs, Bs, As);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dictionary<ColorChannel, double> GetChannels() => new Dictionary<ColorChannel, double>()
|
||||||
|
{
|
||||||
|
{ ColorChannel.Red, r },
|
||||||
|
{ ColorChannel.Green, g },
|
||||||
|
{ ColorChannel.Blue, b },
|
||||||
|
{ ColorChannel.Alpha, a },
|
||||||
|
};
|
||||||
|
|
||||||
|
public TColor AsColor<TColor>() where TColor : struct, IColor<TColor>
|
||||||
|
{
|
||||||
|
Type type = typeof(TColor);
|
||||||
|
if (type == typeof(ColorRGB)) return (TColor)(object)this;
|
||||||
|
else throw new InvalidCastException();
|
||||||
|
}
|
||||||
|
public ColorRGB AsRgb() => this;
|
||||||
|
|
||||||
|
public IEnumerator<double> GetEnumerator()
|
||||||
|
{
|
||||||
|
yield return r;
|
||||||
|
yield return g;
|
||||||
|
yield return b;
|
||||||
|
yield return a;
|
||||||
|
}
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
|
public void Deconstruct(out double r, out double g, out double b)
|
||||||
|
{
|
||||||
|
r = this.r;
|
||||||
|
g = this.g;
|
||||||
|
b = this.b;
|
||||||
|
}
|
||||||
|
public void Deconstruct(out double r, out double g, out double b, out double a)
|
||||||
|
{
|
||||||
|
r = this.r;
|
||||||
|
g = this.g;
|
||||||
|
b = this.b;
|
||||||
|
a = this.a;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Equals(ColorRGB other)
|
||||||
|
{
|
||||||
|
if (a <= 0 && b <= 0) return true;
|
||||||
|
else return r == other.r && g == other.g && b == other.b;
|
||||||
|
}
|
||||||
|
public bool Equals(IColor other) => Equals(other.AsRgb());
|
||||||
|
#if CS8_OR_GREATER
|
||||||
|
public override bool Equals(object? other)
|
||||||
|
#else
|
||||||
|
public override bool Equals(object other)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (other is IColor color) return Equals(color.AsRgb());
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
public override int GetHashCode() => base.GetHashCode();
|
||||||
|
public override string ToString() => $"{{ r={r:0.00}, g={g:0.00}, b={b:0.00}, a={a:0.00} }}";
|
||||||
|
|
||||||
|
public double[] ToArray() => new double[] { r, g, b, a };
|
||||||
|
public Fill<double> ToFill()
|
||||||
|
{
|
||||||
|
ColorRGB copy = this;
|
||||||
|
return i => copy[i];
|
||||||
|
}
|
||||||
|
public List<double> ToList() => new List<double>() { r, g, b, a };
|
||||||
|
|
||||||
|
public static ColorRGB operator +(ColorRGB a) => a;
|
||||||
|
public static ColorRGB operator +(ColorRGB a, ColorRGB b) => new ColorRGB(a.r + b.r, a.g + b.g, a.b + b.b, 1 - (1 - a.a) * (1 - b.b));
|
||||||
|
public static ColorRGB operator -(ColorRGB a) => new ColorRGB(1 - a.r, 1 - a.g, 1 - a.b);
|
||||||
|
public static ColorRGB operator *(ColorRGB a, ColorRGB b) => new ColorRGB(a.r * b.r, a.g * b.g, a.b * b.b, a.a * b.a);
|
||||||
|
public static ColorRGB operator *(ColorRGB a, double b) => new ColorRGB(a.r * b, a.g * b, a.b * b);
|
||||||
|
public static bool operator ==(ColorRGB a, IColor b) => a.Equals(b.AsRgb());
|
||||||
|
public static bool operator !=(ColorRGB a, IColor b) => !a.Equals(b.AsRgb());
|
||||||
|
public static bool operator ==(ColorRGB a, ColorRGB b) => a.Equals(b);
|
||||||
|
public static bool operator !=(ColorRGB a, ColorRGB b) => !a.Equals(b);
|
||||||
|
|
||||||
|
public static implicit operator ColorRGB(ListTuple<double> tuple)
|
||||||
|
{
|
||||||
|
if (tuple.Length == 3) return new ColorRGB(tuple[0], tuple[1], tuple[2]);
|
||||||
|
else if (tuple.Length == 4) return new ColorRGB(tuple[0], tuple[1], tuple[2], tuple[3]);
|
||||||
|
else throw new InvalidCastException();
|
||||||
|
}
|
||||||
|
public static implicit operator ColorRGB((double, double, double) tuple) => new ColorRGB(tuple.Item1, tuple.Item2, tuple.Item3);
|
||||||
|
public static implicit operator ColorRGB((double, double, double, double) tuple) => new ColorRGB(tuple.Item1, tuple.Item2, tuple.Item3, tuple.Item4);
|
||||||
|
public static explicit operator ColorRGB(Float3 group) => new ColorRGB(group.x, group.y, group.z);
|
||||||
|
public static explicit operator ColorRGB(Float4 group) => new ColorRGB(group.x, group.y, group.z, group.w);
|
||||||
|
|
||||||
|
public static implicit operator ListTuple<double>(ColorRGB color) => new ListTuple<double>(color.r, color.g, color.b, color.a);
|
||||||
|
public static implicit operator ValueTuple<double, double, double>(ColorRGB color) => (color.r, color.g, color.b);
|
||||||
|
public static implicit operator ValueTuple<double, double, double, double>(ColorRGB color) => (color.r, color.g, color.b, color.a);
|
||||||
|
}
|
||||||
|
}
|
||||||
33
Nerd_STF/Graphics/IColor.cs
Normal file
33
Nerd_STF/Graphics/IColor.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
using Nerd_STF.Mathematics;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Nerd_STF.Graphics
|
||||||
|
{
|
||||||
|
public interface IColor : INumberGroupBase<double>
|
||||||
|
{
|
||||||
|
Dictionary<ColorChannel, double> GetChannels();
|
||||||
|
|
||||||
|
TColor AsColor<TColor>() where TColor : struct, IColor<TColor>;
|
||||||
|
ColorRGB AsRgb();
|
||||||
|
|
||||||
|
bool Equals(IColor other);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IColor<TSelf> : IColor,
|
||||||
|
IEquatable<TSelf>,
|
||||||
|
INumberGroup<TSelf, double>
|
||||||
|
#if CS11_OR_GREATER
|
||||||
|
,IColorPresets<TSelf>
|
||||||
|
#endif
|
||||||
|
where TSelf : struct, IColor<TSelf>
|
||||||
|
{
|
||||||
|
#if CS11_OR_GREATER
|
||||||
|
static abstract int ChannelCount { get; }
|
||||||
|
|
||||||
|
// TODO: Do all color formats have a gamma value?
|
||||||
|
static abstract TSelf Average(double gamma, IEnumerable<TSelf> colors);
|
||||||
|
static abstract TSelf Lerp(double gamma, TSelf a, TSelf b, double t, bool clamp = true);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Nerd_STF/Graphics/IColorPresets.cs
Normal file
24
Nerd_STF/Graphics/IColorPresets.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#if CS11_OR_GREATER
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Nerd_STF.Graphics
|
||||||
|
{
|
||||||
|
public interface IColorPresets<TSelf> where TSelf : struct, IColor<TSelf>, IColorPresets<TSelf>
|
||||||
|
{
|
||||||
|
static abstract TSelf Black { get; }
|
||||||
|
static abstract TSelf Blue { get; }
|
||||||
|
static abstract TSelf Clear { get; }
|
||||||
|
static abstract TSelf Cyan { get; }
|
||||||
|
static abstract TSelf Gray { get; }
|
||||||
|
static abstract TSelf Green { get; }
|
||||||
|
static abstract TSelf Magenta { get; }
|
||||||
|
static abstract TSelf Orange { get; }
|
||||||
|
static abstract TSelf Purple { get; }
|
||||||
|
static abstract TSelf Red { get; }
|
||||||
|
static abstract TSelf White { get; }
|
||||||
|
static abstract TSelf Yellow { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -46,7 +46,7 @@ namespace Nerd_STF.Mathematics
|
|||||||
{
|
{
|
||||||
this[index] = item;
|
this[index] = item;
|
||||||
index++;
|
index++;
|
||||||
if (index >= 2) break;
|
if (index == 2) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Float2(Fill<double> fill)
|
public Float2(Fill<double> fill)
|
||||||
|
|||||||
@ -49,7 +49,7 @@ namespace Nerd_STF.Mathematics
|
|||||||
{
|
{
|
||||||
this[index] = item;
|
this[index] = item;
|
||||||
index++;
|
index++;
|
||||||
if (index >= 2) break;
|
if (index == 3) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Float3(Fill<double> fill)
|
public Float3(Fill<double> fill)
|
||||||
|
|||||||
@ -53,7 +53,7 @@ namespace Nerd_STF.Mathematics
|
|||||||
{
|
{
|
||||||
this[index] = item;
|
this[index] = item;
|
||||||
index++;
|
index++;
|
||||||
if (index >= 2) break;
|
if (index == 4) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Float4(Fill<double> fill)
|
public Float4(Fill<double> fill)
|
||||||
|
|||||||
@ -7,7 +7,8 @@ namespace Nerd_STF.Mathematics
|
|||||||
{
|
{
|
||||||
public interface INumberGroup<TSelf, TItem> : ICombinationIndexer<TItem>,
|
public interface INumberGroup<TSelf, TItem> : ICombinationIndexer<TItem>,
|
||||||
IEnumerable<TItem>,
|
IEnumerable<TItem>,
|
||||||
IEquatable<TSelf>
|
IEquatable<TSelf>,
|
||||||
|
INumberGroupBase<TItem>
|
||||||
#if CS11_OR_GREATER
|
#if CS11_OR_GREATER
|
||||||
, IInterpolable<TSelf>,
|
, IInterpolable<TSelf>,
|
||||||
ISimpleMathOperations<TSelf>,
|
ISimpleMathOperations<TSelf>,
|
||||||
@ -17,11 +18,5 @@ namespace Nerd_STF.Mathematics
|
|||||||
#if CS11_OR_GREATER
|
#if CS11_OR_GREATER
|
||||||
where TItem : INumber<TItem>
|
where TItem : INumber<TItem>
|
||||||
#endif
|
#endif
|
||||||
{
|
{ }
|
||||||
TItem this[int index] { get; set; }
|
|
||||||
|
|
||||||
TItem[] ToArray();
|
|
||||||
Fill<TItem> ToFill();
|
|
||||||
List<TItem> ToList();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
17
Nerd_STF/Mathematics/INumberGroupBase.cs
Normal file
17
Nerd_STF/Mathematics/INumberGroupBase.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Numerics;
|
||||||
|
|
||||||
|
namespace Nerd_STF.Mathematics
|
||||||
|
{
|
||||||
|
public interface INumberGroupBase<TItem>
|
||||||
|
#if CS11_OR_GREATER
|
||||||
|
where TItem : INumber<TItem>
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
TItem this[int index] { get; set; }
|
||||||
|
|
||||||
|
TItem[] ToArray();
|
||||||
|
Fill<TItem> ToFill();
|
||||||
|
List<TItem> ToList();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,7 +5,6 @@ using System.Numerics;
|
|||||||
namespace Nerd_STF.Mathematics
|
namespace Nerd_STF.Mathematics
|
||||||
{
|
{
|
||||||
public interface ISimpleMathOperations<TSelf> : IAdditionOperators<TSelf, TSelf, TSelf>,
|
public interface ISimpleMathOperations<TSelf> : IAdditionOperators<TSelf, TSelf, TSelf>,
|
||||||
ISubtractionOperators<TSelf, TSelf, TSelf>,
|
|
||||||
IMultiplyOperators<TSelf, TSelf, TSelf>
|
IMultiplyOperators<TSelf, TSelf, TSelf>
|
||||||
where TSelf : ISimpleMathOperations<TSelf>
|
where TSelf : ISimpleMathOperations<TSelf>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -44,7 +44,7 @@ namespace Nerd_STF.Mathematics
|
|||||||
{
|
{
|
||||||
this[index] = item;
|
this[index] = item;
|
||||||
index++;
|
index++;
|
||||||
if (index >= 2) break;
|
if (index == 2) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Int2(Fill<int> fill)
|
public Int2(Fill<int> fill)
|
||||||
|
|||||||
@ -47,7 +47,7 @@ namespace Nerd_STF.Mathematics
|
|||||||
{
|
{
|
||||||
this[index] = item;
|
this[index] = item;
|
||||||
index++;
|
index++;
|
||||||
if (index >= 2) break;
|
if (index == 3) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Int3(Fill<int> fill)
|
public Int3(Fill<int> fill)
|
||||||
|
|||||||
@ -51,7 +51,7 @@ namespace Nerd_STF.Mathematics
|
|||||||
{
|
{
|
||||||
this[index] = item;
|
this[index] = item;
|
||||||
index++;
|
index++;
|
||||||
if (index >= 2) break;
|
if (index == 4) break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public Int4(Fill<int> fill)
|
public Int4(Fill<int> fill)
|
||||||
|
|||||||
@ -703,7 +703,11 @@ namespace Nerd_STF.Mathematics
|
|||||||
public static IEquation Cot(IEquation inputRad, int terms = 8) =>
|
public static IEquation Cot(IEquation inputRad, int terms = 8) =>
|
||||||
new Equation((double x) => Cot(inputRad[x], terms));
|
new Equation((double x) => Cot(inputRad[x], terms));
|
||||||
|
|
||||||
public static double Sqrt(double num) => 1 / InverseSqrtFast((float)num); // !!TODO!!: Bring back Newton's
|
// YOU CANNOT USE POW HERE!!!
|
||||||
|
// The CordicHelper uses the Sqrt function for the Pow method.
|
||||||
|
// It'll cause a stack overflow.
|
||||||
|
// !!TODO!! - Bring back Newton's
|
||||||
|
public static double Sqrt(double num) => 1 / InverseSqrtFast((float)num);
|
||||||
public static IEquation Sqrt(IEquation equ) =>
|
public static IEquation Sqrt(IEquation equ) =>
|
||||||
new Equation((double x) => Sqrt(equ.Get(x)));
|
new Equation((double x) => Sqrt(equ.Get(x)));
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user