/// <summary> /// Creates a new LineCirclePattern, duplicating an existing one /// </summary> /// <param name="CopyTarget">The LineCirclePattern to duplicate</param> public LineCirclePattern(LineCirclePattern CopyTarget) { Count = CopyTarget.Count; LineCount = CopyTarget.LineCount; LineScaleMultiplier = CopyTarget.LineScaleMultiplier; LineRotationMultiplier = CopyTarget.LineRotationMultiplier; SphericalCoordinates = CopyTarget.SphericalCoordinates; LineInterval = CopyTarget.LineInterval; AutoScaleLines = CopyTarget.AutoScaleLines; TimeStep = CopyTarget.TimeStep; TimeSpan = CopyTarget.TimeSpan; TimeOffset = CopyTarget.TimeOffset; DrawLines = CopyTarget.DrawLines; DrawFill = CopyTarget.DrawFill; LineColor = CopyTarget.LineColor; FillColor = CopyTarget.FillColor; SrcMode = CopyTarget.SrcMode; DstMode = CopyTarget.DstMode; Oscillators = new Oscillator[CopyTarget.Oscillators.Length]; for (int i = 0; i < Oscillators.Length; i++) { Oscillators[i] = new Oscillator(CopyTarget.Oscillators[i]); } TimeToZ = CopyTarget.TimeToZ; ZFade = CopyTarget.ZFade; }
/// <summary> /// Initialises a new LineCirclePattern which is the interpolation of two other LineCirclePatterns /// </summary> /// <param name="PatternA"></param> /// <param name="PatternB"></param> /// <param name="LerpFactor"></param> public LineCirclePattern(LineCirclePattern PatternA, LineCirclePattern PatternB, float LerpFactor) { Count = Mathf.RoundToInt(Mathf.Lerp(PatternA.Count, PatternB.Count, LerpFactor)); LineCount = Mathf.RoundToInt(Mathf.Lerp(PatternA.LineCount, PatternB.LineCount, LerpFactor)); LineScaleMultiplier = Mathf.Lerp(PatternA.LineScaleMultiplier, PatternB.LineScaleMultiplier, LerpFactor); LineRotationMultiplier = Mathf.Lerp(PatternA.LineRotationMultiplier, PatternB.LineRotationMultiplier, LerpFactor); SphericalCoordinates = LerpFactor < 0.5f ? PatternA.SphericalCoordinates : PatternB.SphericalCoordinates; LineInterval = Mathf.RoundToInt(Mathf.Lerp(PatternA.LineInterval, PatternB.LineInterval, LerpFactor)); AutoScaleLines = LerpFactor < 0.5f ? PatternA.AutoScaleLines : PatternB.AutoScaleLines; TimeStep = Mathf.Lerp(PatternA.TimeStep, PatternB.TimeStep, LerpFactor); TimeSpan = Mathf.Lerp(PatternA.TimeSpan, PatternB.TimeSpan, LerpFactor); TimeOffset = Mathf.Lerp(PatternA.TimeOffset, PatternB.TimeOffset, LerpFactor); DrawLines = LerpFactor < 0.5f ? PatternA.DrawLines : PatternB.DrawLines; DrawFill = LerpFactor < 0.5f ? PatternA.DrawFill : PatternB.DrawFill; LineColor = Color.Lerp(PatternA.LineColor, PatternB.LineColor, LerpFactor); FillColor = Color.Lerp(PatternA.FillColor, PatternB.FillColor, LerpFactor); SrcMode = LerpFactor < 0.5f ? PatternA.SrcMode : PatternB.SrcMode; DstMode = LerpFactor < 0.5f ? PatternA.DstMode : PatternB.DstMode; Oscillators = new Oscillator[PatternA.Oscillators.Length]; for (int i = 0; i < Oscillators.Length; i++) { Oscillators[i] = new Oscillator(PatternA.Oscillators[i], PatternB.Oscillators[i], LerpFactor); } TimeToZ = LerpFactor < 0.5f ? PatternA.TimeToZ : PatternB.TimeToZ; ZFade = LerpFactor < 0.5f ? PatternA.ZFade : PatternB.ZFade; }
/// <summary> /// Creates a new Oscillator which is the interpolation of two existing ones /// </summary> /// <param name="OscillatorA">The first Oscillator to lerp between</param> /// <param name="OscillatorB">The second Oscillator to lerp between</param> /// <param name="LerpFactor">The lerp value - a value of 0 creates a copy of OscillatorA, a value of 1 creates a copy of OscillatorB, 0.5 creates one exactly between them, etc...</param> public Oscillator(Oscillator OscillatorA, Oscillator OscillatorB, float LerpFactor) { Name = OscillatorA.Name; Type = LerpFactor < 0.5f ? OscillatorA.Type : OscillatorB.Type; Center = Mathf.Lerp(OscillatorA.Center, OscillatorB.Center, LerpFactor); Amplitude = Mathf.Lerp(OscillatorA.Amplitude, OscillatorB.Amplitude, LerpFactor); Period = Mathf.Lerp(OscillatorA.Period, OscillatorB.Period, LerpFactor); Phase = Mathf.Lerp(OscillatorA.Phase, OscillatorB.Phase, LerpFactor); }
/// <summary> /// Creates a new Oscillator copying from an existing one /// </summary> /// <param name="CopyTarget">The existing oscillator to duplicate</param> public Oscillator(Oscillator CopyTarget) { Name = CopyTarget.Name; Type = CopyTarget.Type; Center = CopyTarget.Center; Amplitude = CopyTarget.Amplitude; Period = CopyTarget.Period; Phase = CopyTarget.Phase; }
/// <summary> /// Ensures that we never exceed the provided min and max frequency values (uses internal override values) /// </summary> public void EnforceMaxFrequency(ref Oscillator target) { //this is the coefficient of X at each local maxima of the derivative of the waveform function var coefficient = 1f; switch (target.Type) { case OscillatorShape.Constant: //we don't need to check change per second because it's not changing! return; case OscillatorShape.Sine: coefficient = 2f * Mathf.PI; break; case OscillatorShape.Sawtooth: coefficient = 2f; break; case OscillatorShape.Triangle: coefficient = 4f; break; case OscillatorShape.Square: //we don't need to check change per second because it's changing instantly! return; default: throw new ArgumentOutOfRangeException($"Unexpected value {target.Type} for OscillatorShuffler EnforceMaxFrequency"); } //this just makes sure that even at the minimum possible frequency, the function won't ever have a point where it's changing faster than MaxChangePerSecond var calculatedMaxFrequency = MaxChangePerSecond / (coefficient * target.Amplitude); var calculatedMinPeriod = 1f / calculatedMaxFrequency; target.Period = Mathf.Max(calculatedMinPeriod, target.Period); }
/// <summary> /// Randomises the Phase value of the target oscillator /// </summary> /// <param name="target">The oscillator to be modified</param> public static void RandomisePhase(ref Oscillator target) { target.Phase = Random.Range(0f, 1f); }
/// <summary> /// Randomises the Center value of the target oscillator /// </summary> /// <param name="target">The oscillator to be modified</param> public void RandomiseCenter(ref Oscillator target) { target.Center = Random.Range(AbsoluteMin, AbsoluteMax); }
/// <summary> /// Ensures the target oscillator moves between zero and two pi (used for sawtooth waves) /// </summary> /// <param name="target">The oscillator to be modified</param> public static void EnforceTwoPi(ref Oscillator target) { target.Amplitude = Mathf.PI * 2f; target.Center = Mathf.PI; }
/// <summary> /// Randomises the Amplitude and Center values of the target oscillator /// </summary> /// <param name="target">The oscillator to be modified</param> public void RandomiseRange(ref Oscillator target) { target.Amplitude = Random.Range(0, (AbsoluteMax - AbsoluteMin) * 0.5f); target.Center = Random.Range(AbsoluteMin + target.Amplitude, AbsoluteMax - target.Amplitude); }
/// <summary> /// Randomises the Frequency value of the target oscillator using the Override Minimum and Maximum Frequency values for this OscillatorRandomiator /// </summary> /// <param name="target">The oscillator to be modified</param> /// <param name="minimumFrequency">The minimum possible value for the target oscillator's frequency (in seconds)</param> /// <param name="maximumFrequency">The maximum possible value for the target oscillator's frequency (in seconds)</param> public static void RandomiseFrequency(ref Oscillator target, float minimumFrequency, float maximumFrequency) { target.Period = 1f / Random.Range(minimumFrequency, maximumFrequency); }
/// <summary> /// Randomises the Frequency value of the target oscillator using the Override Minimum and Maximum Frequency values for this OscillatorRandomiator /// </summary> /// <param name="target">The oscillator to be modified</param> public void RandomiseFrequency(ref Oscillator target) { RandomiseFrequency(ref target, OverrideMinFrequency, OverrideMaxFrequency); }