207 lines
9.2 KiB
C#
207 lines
9.2 KiB
C#
using System.Drawing;
|
|
using System.Numerics;
|
|
|
|
namespace WebmrAPI.Utils.Sequences
|
|
{
|
|
public abstract class OscillationGenerator<T> : BaseGenerator<T>
|
|
{
|
|
private int _segments = 1;
|
|
private double _amplitude = 100.0;
|
|
public double Amplitude { get => _amplitude; protected set => _amplitude = Math.Abs(value); }
|
|
public int Segments { get => _segments; protected set => _segments = value < 1 ? 1 : value; }
|
|
public override double Step { get; protected set; }
|
|
protected abstract double FOffset { get; }
|
|
public OscillationGenerator(T min, T max)
|
|
: base(min, max) { }
|
|
}
|
|
|
|
public abstract class SawtoothGenerator<T> : OscillationGenerator<T>
|
|
{
|
|
protected override double FOffset { get { double s = (Progress * Segments) % 1.0; return (s < 0.5 ? s : (1.0 - s)) * 4.0 - 1.0; } }
|
|
|
|
public SawtoothGenerator(T min, T max)
|
|
: base(min, max) { }
|
|
}
|
|
|
|
public abstract class SineWaveGenerator<T> : OscillationGenerator<T>
|
|
{
|
|
protected override double FOffset { get => Math.Sin(Progress * (Segments * 2.0) * Math.PI); }
|
|
|
|
public SineWaveGenerator(T min, T max)
|
|
: base(min, max) { }
|
|
}
|
|
|
|
public abstract class SquareWaveGenerator<T> : OscillationGenerator<T>
|
|
{
|
|
protected override double FOffset { get => (Math.Floor(Progress * Segments) % 2 == 0) ? 1 : -1; }
|
|
|
|
public SquareWaveGenerator(T min, T max)
|
|
: base(min, max) { }
|
|
}
|
|
public sealed class SawtoothNumberGenerator<T> : SawtoothGenerator<T>, INumberGenerator<T> where T : struct, INumber<T>
|
|
{
|
|
public INumberGenerator<T> Self { get => this; }
|
|
public SawtoothNumberGenerator<T> SetShapeFactor(double fShape) { FShape = fShape; return this; }
|
|
public SawtoothNumberGenerator<T> SetFadeFactor(double fade) { FFade = fade; return this; }
|
|
public SawtoothNumberGenerator<T> SetSegments(int count) { Segments = count; return this; }
|
|
public SawtoothNumberGenerator<T> SetAmplitude(double amplitude) { Amplitude = amplitude; return this; }
|
|
protected override T Calc()
|
|
{
|
|
var offs = Amplitude * FOffset * Scale * ((Self.DMax - Self.DMin) / 2.0);
|
|
|
|
return T.CreateChecked(Math.Clamp(Self.Mean + offs, Self.DMin, Self.DMax));
|
|
}
|
|
public SawtoothNumberGenerator(T min, T max, int count = 10) : base(min, max)
|
|
{
|
|
Step = CalcStepByCount(count);
|
|
Amplitude = 1.0; // Set default
|
|
}
|
|
}
|
|
public sealed class SineWaveNumberGenerator<T> : SineWaveGenerator<T>, INumberGenerator<T> where T : struct, INumber<T>
|
|
{
|
|
public INumberGenerator<T> Self { get => this; }
|
|
public SineWaveNumberGenerator<T> SetShapeFactor(double fShape) { FShape = fShape; return this; }
|
|
public SineWaveNumberGenerator<T> SetFadeFactor(double fade) { FFade = fade; return this; }
|
|
public SineWaveNumberGenerator<T> SetSegments(int count) { Segments = count; return this; }
|
|
public SineWaveNumberGenerator<T> SetAmplitude(double amplitude) { Amplitude = amplitude; return this; }
|
|
protected override T Calc()
|
|
{
|
|
var offs = Amplitude * FOffset * Scale * ((Self.DMax - Self.DMin) / 2.0);
|
|
|
|
return T.CreateChecked(Math.Clamp(Self.Mean + offs, Self.DMin, Self.DMax));
|
|
}
|
|
public SineWaveNumberGenerator(T min, T max, int count = 10) : base(min, max)
|
|
{
|
|
Step = CalcStepByCount(count);
|
|
Amplitude = 1.0; // Set default
|
|
}
|
|
}
|
|
public sealed class SquareWaveNumberGenerator<T> : SquareWaveGenerator<T>, INumberGenerator<T> where T : struct, INumber<T>
|
|
{
|
|
public INumberGenerator<T> Self { get => this; }
|
|
public SquareWaveNumberGenerator<T> SetShapeFactor(double fShape) { FShape = fShape; return this; }
|
|
public SquareWaveNumberGenerator<T> SetFadeFactor(double fade) { FFade = fade; return this; }
|
|
public SquareWaveNumberGenerator<T> SetSegments(int count) { Segments = count; return this; }
|
|
public SquareWaveNumberGenerator<T> SetAmplitude(double amplitude) { Amplitude = amplitude; return this; }
|
|
protected override T Calc()
|
|
{
|
|
var offs = Amplitude * FOffset * Scale * ((Self.DMax - Self.DMin) / 2.0);
|
|
|
|
return T.CreateChecked(Math.Clamp(Self.Mean + offs, Self.DMin, Self.DMax));
|
|
}
|
|
public SquareWaveNumberGenerator(T min, T max, int count = 10) : base(min, max)
|
|
{
|
|
Step = CalcStepByCount(count);
|
|
Amplitude = 1.0; // Set default
|
|
}
|
|
}
|
|
|
|
public sealed class SawtoothPointGenerator : SawtoothGenerator<Point>, IPointGenerator
|
|
{
|
|
private readonly double _pAngle;
|
|
public IPointGenerator Self { get => this; }
|
|
public SawtoothPointGenerator SetShapeFactor(double fShape) { FShape = fShape; return this; }
|
|
public SawtoothPointGenerator SetFadeFactor(double fade) { FFade = fade; return this; }
|
|
public SawtoothPointGenerator SetSegments(int count) { Segments = count; return this; }
|
|
public SawtoothPointGenerator SetAmplitude(double amplitude) { Amplitude = amplitude; return this; }
|
|
protected override Point Calc()
|
|
{
|
|
return IPointGenerator.CalcPoint(Self.LinearX, Self.LinearY, Amplitude * FOffset * Scale, _pAngle);
|
|
}
|
|
|
|
public static SawtoothPointGenerator CreateByCount(Point start, Point end, int count)
|
|
{
|
|
return new SawtoothPointGenerator(start, end) { Step = CalcStepByCount(count) };
|
|
}
|
|
|
|
public static SawtoothPointGenerator CreateByStepSize(Point start, Point end, double pxPerStep = 5)
|
|
{
|
|
return new SawtoothPointGenerator(start, end, pxPerStep);
|
|
}
|
|
|
|
public SawtoothPointGenerator(Point start, Point end, double pxPerStep = 5)
|
|
: this(start, end)
|
|
{
|
|
Step = pxPerStep / IPointGenerator.CalcDistance(start, end);
|
|
}
|
|
|
|
private SawtoothPointGenerator(Point start, Point end)
|
|
: base(start, end)
|
|
{
|
|
_pAngle = IPointGenerator.CalcAngle(start, end) + Math.PI / 2.0;
|
|
}
|
|
}
|
|
|
|
public sealed class SineWavePointGenerator : SineWaveGenerator<Point>, IPointGenerator
|
|
{
|
|
private readonly double _pAngle;
|
|
public IPointGenerator Self { get => this; }
|
|
public SineWavePointGenerator SetShapeFactor(double fShape) { FShape = fShape; return this; }
|
|
public SineWavePointGenerator SetFadeFactor(double fade) { FFade = fade; return this; }
|
|
public SineWavePointGenerator SetSegments(int count) { Segments = count; return this; }
|
|
public SineWavePointGenerator SetAmplitude(double amplitude) { Amplitude = amplitude; return this; }
|
|
protected override Point Calc()
|
|
{
|
|
return IPointGenerator.CalcPoint(Self.LinearX, Self.LinearY, Amplitude * FOffset * Scale, _pAngle);
|
|
}
|
|
|
|
public static SineWavePointGenerator CreateByCount(Point start, Point end, int count)
|
|
{
|
|
return new SineWavePointGenerator(start, end) { Step = CalcStepByCount(count) };
|
|
}
|
|
|
|
public static SineWavePointGenerator CreateByStepSize(Point start, Point end, double pxPerStep = 5)
|
|
{
|
|
return new SineWavePointGenerator(start, end, pxPerStep);
|
|
}
|
|
|
|
public SineWavePointGenerator(Point start, Point end, double pxPerStep = 5)
|
|
: this(start, end)
|
|
{
|
|
Step = pxPerStep / IPointGenerator.CalcDistance(start, end);
|
|
}
|
|
|
|
private SineWavePointGenerator(Point start, Point end)
|
|
: base(start, end)
|
|
{
|
|
_pAngle = IPointGenerator.CalcAngle(start, end) + Math.PI / 2.0;
|
|
}
|
|
}
|
|
|
|
public sealed class SquareWavePointGenerator : SquareWaveGenerator<Point>, IPointGenerator
|
|
{
|
|
private readonly double _pAngle;
|
|
public IPointGenerator Self { get => this; }
|
|
public SquareWavePointGenerator SetShapeFactor(double fShape) { FShape = fShape; return this; }
|
|
public SquareWavePointGenerator SetFadeFactor(double fade) { FFade = fade; return this; }
|
|
public SquareWavePointGenerator SetSegments(int count) { Segments = count; return this; }
|
|
public SquareWavePointGenerator SetAmplitude(double amplitude) { Amplitude = amplitude; return this; }
|
|
protected override Point Calc()
|
|
{
|
|
return IPointGenerator.CalcPoint(Self.LinearX, Self.LinearY, Amplitude * FOffset * Scale, _pAngle);
|
|
}
|
|
|
|
public static SquareWavePointGenerator CreateByCount(Point start, Point end, int count)
|
|
{
|
|
return new SquareWavePointGenerator(start, end) { Step = CalcStepByCount(count) };
|
|
}
|
|
|
|
public static SquareWavePointGenerator CreateByStepSize(Point start, Point end, double pxPerStep = 5)
|
|
{
|
|
return new SquareWavePointGenerator(start, end, pxPerStep);
|
|
}
|
|
|
|
public SquareWavePointGenerator(Point start, Point end, double pxPerStep = 5)
|
|
: this(start, end)
|
|
{
|
|
Step = pxPerStep / IPointGenerator.CalcDistance(start, end);
|
|
}
|
|
|
|
private SquareWavePointGenerator(Point start, Point end)
|
|
: base(start, end)
|
|
{
|
|
_pAngle = IPointGenerator.CalcAngle(start, end) + Math.PI / 2.0;
|
|
}
|
|
}
|
|
}
|