> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.w55967FT2CR/rev.69
 * 
 * authors: 
 *   GoToLoop

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



/*____________________________________________________________________________________________________*/

// Twister (v2.3)
// date @ 2012/Aug
// program by tonyrocks
// modded  by GoToLoop

// Converted from MS Small Basic
// Import Code: FKF358-5
// http://social.msdn.microsoft.com/Forums/en-US/smallbasic
// /thread/abc69be0-b2a9-4bb2-b5aa-c652f4258308

/*____________________________________________________________________________________________________*/
// Constants:
private static final short gw = 800;           // window width
private static final short gh = 600;           // window height
private static final short oSet = gw>>1;       // offset (gw/2)

private static final short tSize  = 180;       // twister size
private static final short twist  = 200;       // twister amplitude
private static final short angMax = 180;       // max angle samples
private static final byte  fps    = 10;        // FPS refresh
private static final byte  ruggy  = 1;         // how rugged lines are

private static final boolean useSmooth = false;

//colors = "0=Maroon;1=DarkRed;2=Red;3=SkyBlue;4=DodgerBlue;5=Blue;6=Navy;7=Indigo;"
private static final color[] colors = {
    #800000, #8B0000, #FF0000, #87CEEB, #1E90FF, #0000FF, #000080, #4B0082
};

private static final byte  colorsIndex = (byte) colors.length;  // # of colors = # of lines to draw at each row
private static final float angStep     = 360f/colorsIndex;      // angle gap for lines of each color
/*____________________________________________________________________________________________________*/
// Variables:
private static short   ang = 0;           // current angle loop iterator to display

private static boolean isRunning = true;  // running status

private static final short[][][] x = new short[angMax][gh][colorsIndex + 1];  // coordinate 3d array
/*____________________________________________________________________________________________________*/
// Initialization:
final void setup() {

    size(800, 600);
    frameRate(fps);
    strokeWeight(ruggy);

    if (useSmooth)    smooth();

    TwisterData();
}
/*____________________________________________________________________________________________________*/
// Store all calcs in array x[ang][y][row]:
private static final void TwisterData() {

    float amp, calc;

    for (short ang = 0; ang < angMax; ++ang) {
        amp = sin(ang)*gh + twist;         // Set the amplitude and change it based on height & angle

        for (short y = 0; y < gh; y += ruggy) {
            calc = y/amp + ang;            // Pre-Calc

            for (byte row = 0; row < colorsIndex; ++row)
                x[ang][y][row] = (short) ( sin(angStep*row + calc) * tSize + oSet );

            x[ang][y][colorsIndex] = x[ang][y][0]; // Extra redundant row = 1st row
        }
    }
}
/*____________________________________________________________________________________________________*/
// Twister drawing loop:
final void draw() {

    background(0);                     // Clear screen w/ black

    print(ang + " \t");                // Print current angle in the text console

    for (short y = 0, x1, x2; y < gh; y += ruggy) {
        x1 = x[ang][y][0];             // 1st horizontal coordinate

        for (byte row = 0; row < colorsIndex; ++row, x1 = x2) {
            x2 = x[ang][y][row+1];     // destination horizontal coordinate

            if (x1 < x2) {
                stroke( colors[row] );
                line( x1, y, x2, y );
            }
        }
    }

    if (++ang == angMax)    ang = 0;   // Increase angle & check if it's time to reset it
}
/*____________________________________________________________________________________________________*/
// Pause animation
final void keyPressed() {

    if (isRunning = !isRunning)   loop();
    else                          noLoop();
}
/*____________________________________________________________________________________________________*/
// Pause animation
final void mousePressed() {

    keyPressed();
}
/*____________________________________________________________________________________________________*/