float stageHeight, stageWidth; CurvePoint curvePoints; ICurveFormula formula; int counter = 0; float radius =100; void setup() { size( 300, 300 ); stageHeight = height; stageWidth = width; frameRate( 60 ); smooth(); noStroke(); ellipseMode( CENTER ); colorMode( HSB, 100 ); background(0); formula = new BotanicCurveFormula( 5, 5, 1, 1 ); curvePoints = new CurvePoint( formula, false ); } void draw() { rectMode( CORNER ); fill( 0, 2 ); rect( 0, 0, stageHeight, stageWidth ); float[] p = curvePoints.getAnglePoint( counter * 1 ); float x = p[0] * radius + 150; float y = p[1] * radius + 150; int h = floor( ( mouseX / stageWidth ) * 100 ); int s = floor( ( mouseY / stageHeight ) * 100 ); fill( h, s, 100 ); ellipse( x, y, 5, 5 ); counter++; } class CurvePoint { int DRAW_COUNTER_MAX = 360; float RADIAN_CONVERT = PI / 180; ICurveFormula _formula; float _stepSize = 1; boolean _isClockWise = false; float cycle = 1; CurvePoint( ICurveFormula formula, boolean isClockWise ) { _formula = formula; _isClockWise = isClockWise; cycle = _formula.getCycleCount(); } float[] getAnglePoint( float angle ) { float radian = angle * RADIAN_CONVERT; return _formula.calculate( radian ); } float getPointCount() { float pointCount = DRAW_COUNTER_MAX / _stepSize * cycle; return pointCount; } } interface ICurveFormula { float[] calculate( float radian ); float getCycleCount(); } class BotanicCurveFormula implements ICurveFormula { float d, c = 0; int numerator, denominator; float cycleCount; BotanicCurveFormula( int dN, int cN, int dD, int cD ) { if ( dN <= 0 || cN <= 0 || dD <= 0 || cD <= 0 ) { throw new Error( "arguments error" ); } d = (float)dN / (float)dD; c = (float)cN / (float)cD; numerator = cN; denominator = cD; cycleCount = setCycleCount(); } float getCycleCount() { return cycleCount; } float[] calculate( float radian ) { /* Botanic Curve */ /* r = 1 + d * sin(c * θ) */ int radius = 1; float value = 1 + d * sin( c * radian ); float radiusAjust = radius / ( 1 + d ); float curveRadius = radiusAjust * value; float valueX = curveRadius * cos( radian ); float valueY = curveRadius * sin( radian ); float[] p = new float[2]; p[0] = valueX; p[1] = valueY * -1; return p; } float setCycleCount() { int g = gcm( numerator, denominator ); return ( denominator / g ); } int gcm( int a, int b ) { // G.C.M. while( b != 0 ) { int r = a % b; a = b; b = r; } return a; } }