// Path: udder/src/main/java/com/coillighting/udder/geometry/Crossfade.java
// public class Crossfade {
// 
//     /** Linearly interpolate x, a value between 0 and 1, between two points,
//      *  (0, y0) and (1, y1). If you supply an x that is out of range, the
//      *  result will likewise be out of range.
//      */
//     public static final double linear(double x, double y0, double y1) {
//         return y0 + x * (y1 - y0);
//     }
// 
//     /** A 32-bit version of Crossfade.linear. */
//     public static final float linear(float x, float y0, float y1) {
//         return y0 + x * (y1 - y0);
//     }
// 
//     /** For a fast attack followed by a slower follow-through, try an exponent
//      *  of 0.5 or 0.25. For a gradual attack with an accelerating follow-up,
//      *  try an exponent of 2-5. This is not really the shapliest easing curve
//      *  curve out there, but it's good to have in the arsenal.
//      */
//     public static final double exponential(double x, double exponent, double y0, double y1) {
//         double balance = Reshape.exponential(x, exponent);
//         return linear(balance, y0, y1);
//     }
// 
//     /** A mostly 32-bit version of Crossfade.exponential. */
//     public static final float exponential(float x, float exponent, float y0, float y1) {
//         float balance = Reshape.exponential(x, exponent);
//         return linear(balance, y0, y1);
//     }
// 
//     /** Use a sinewave to approximate a sigmoidal cross-fade curve.
//      *  Submit this expression to wolframalpha.com to see the resulting curve:
//      *      0.5*(1 + (sin((pi*(x-0.5)))))
//      *  Direct link:
//      *      http://www.wolframalpha.com/input/?i=0.5*%281+%2B+%28sin%28%28pi*%28x-0.5%29%29%29%29%29+from+-0.25+to+1.5
//      */
//     public static final double sinusoidal(double x, double y0, double y1) {
//         double balance = Reshape.sinusoidal(x);
//         return linear(balance, y0, y1);
//     }
// 
//     /** A mostly 32-bit version of crossfadeExponential. */
//     public static final float sinusoidal(float x, float y0, float y1) {
//         float balance = Reshape.sinusoidal(x);
//         return linear(balance, y0, y1);
//     }
// 
//     // TODO logarithmic mode!
// 
// }


import com.coillighting.udder.geometry.Crossfade;
package com.coillighting.udder.geometry.wave;


/** A sinusoidally interpolated signal that continuously oscillates between two
 *  values, with smooth corners at the values themselves.
 */
 public class SinusoidalWave extends WaveBase {

    public SinusoidalWave(double start, double end, long period) {
        super(start, end, period);
    }

    public double interpolate(double x) {
        // This is a funny way to implement this, but I want to give
        // crossfadeSinusoidal a little exercise before simplifying it.
        // Alternately, I might add a ramp-up balance/ramp-down balance
        // param to this class, for use as a simple impulse envelope. (FUTURE)
        double x0;
        double x1;
        if(x <= 0.5) {
            x0 = start;
            x1 = end;
        } else {
            x -= -0.5;
            x0 = end;
            x1 = start;
        }
        x *= 2.0;
// Path: udder/src/main/java/com/coillighting/udder/geometry/Crossfade.java
// public class Crossfade {
// 
//     /** Linearly interpolate x, a value between 0 and 1, between two points,
//      *  (0, y0) and (1, y1). If you supply an x that is out of range, the
//      *  result will likewise be out of range.
//      */
//     public static final double linear(double x, double y0, double y1) {
//         return y0 + x * (y1 - y0);
//     }
// 
//     /** A 32-bit version of Crossfade.linear. */
//     public static final float linear(float x, float y0, float y1) {
//         return y0 + x * (y1 - y0);
//     }
// 
//     /** For a fast attack followed by a slower follow-through, try an exponent
//      *  of 0.5 or 0.25. For a gradual attack with an accelerating follow-up,
//      *  try an exponent of 2-5. This is not really the shapliest easing curve
//      *  curve out there, but it's good to have in the arsenal.
//      */
//     public static final double exponential(double x, double exponent, double y0, double y1) {
//         double balance = Reshape.exponential(x, exponent);
//         return linear(balance, y0, y1);
//     }
// 
//     /** A mostly 32-bit version of Crossfade.exponential. */
//     public static final float exponential(float x, float exponent, float y0, float y1) {
//         float balance = Reshape.exponential(x, exponent);
//         return linear(balance, y0, y1);
//     }
// 
//     /** Use a sinewave to approximate a sigmoidal cross-fade curve.
//      *  Submit this expression to wolframalpha.com to see the resulting curve:
//      *      0.5*(1 + (sin((pi*(x-0.5)))))
//      *  Direct link:
//      *      http://www.wolframalpha.com/input/?i=0.5*%281+%2B+%28sin%28%28pi*%28x-0.5%29%29%29%29%29+from+-0.25+to+1.5
//      */
//     public static final double sinusoidal(double x, double y0, double y1) {
//         double balance = Reshape.sinusoidal(x);
//         return linear(balance, y0, y1);
//     }
// 
//     /** A mostly 32-bit version of crossfadeExponential. */
//     public static final float sinusoidal(float x, float y0, float y1) {
//         float balance = Reshape.sinusoidal(x);
//         return linear(balance, y0, y1);
//     }
// 
//     // TODO logarithmic mode!
// 
// }


// Path: udder/src/main/java/com/coillighting/udder/geometry/wave/SinusoidalWave.java
import com.coillighting.udder.geometry.Crossfade;

package com.coillighting.udder.geometry.wave;


/** A sinusoidally interpolated signal that continuously oscillates between two
 *  values, with smooth corners at the values themselves.
 */
 public class SinusoidalWave extends WaveBase {

    public SinusoidalWave(double start, double end, long period) {
        super(start, end, period);
    }

    public double interpolate(double x) {
        // This is a funny way to implement this, but I want to give
        // crossfadeSinusoidal a little exercise before simplifying it.
        // Alternately, I might add a ramp-up balance/ramp-down balance
        // param to this class, for use as a simple impulse envelope. (FUTURE)
        double x0;
        double x1;
        if(x <= 0.5) {
            x0 = start;
            x1 = end;
        } else {
            x -= -0.5;
            x0 = end;
            x1 = start;
        }
        x *= 2.0;
        return Crossfade.sinusoidal(x, x0, x1);