37
//------------------------------------------------------------------------------ // Geometric animations // Philip R Brenan, 2015, appaapps.com, philip r brenan at gmail dot common // Public domain: please feel free to contribute //------------------------------------------------------------------------------ package com.appaapps.vocabulary; import android.app.Activity; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.os.Bundle; import android.util.Log; import android.view.View; import com.appaapps.Colours; import java.util.Random; //------------------------------------------------------------------------------ // Geometric animations //------------------------------------------------------------------------------ public class VocabularyActivity extends Activity // Connect to Android, {protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView( new // OpposingAnglesAreEqual // ParallelLinesPreserveAngles // AnglesOfATriangleSumTo180 // CircleHasAConstantRadius // DrawSemiCircle // TwoRightAnglesMakeASemiCircle // FourRightAnglesMakeACircle // CircleTangent // LineToPoint // ParallelLineThroughAPoint // Chord // Diameter // ChordBisection // RectangleInACircle // DoubleAnAngle BisectAnAngle // BisectALine // Kite // EquilateralTriangle (this)); } class Draw extends View // Draw animation {float screenWidth = 2000, screenHeight = 1000, // Screen dimensions cx = 1000, cy = 500, // Centre of screen in x,y - replace with display metrics radius = 400, // Radius of circle and semi circles - compute from screensize axisLength = 2000, axisWidth = 100, // Dimensions of an axis bar - twice maximum dimension

Vocabulary Activity

Embed Size (px)

DESCRIPTION

Android program which draws geometric figures

Citation preview

  • //------------------------------------------------------------------------------// Geometric animations// Philip R Brenan, 2015, appaapps.com, philip r brenan at gmail dot common// Public domain: please feel free to contribute//------------------------------------------------------------------------------package com.appaapps.vocabulary;

    import android.app.Activity;import android.graphics.Canvas;import android.graphics.Matrix;import android.graphics.Paint;import android.graphics.Path;import android.graphics.RectF;import android.os.Bundle;import android.util.Log;import android.view.View;import com.appaapps.Colours;

    import java.util.Random;

    //------------------------------------------------------------------------------// Geometric animations//------------------------------------------------------------------------------

    public class VocabularyActivity extends Activity // Connect to Android, {protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState); setContentView( new// OpposingAnglesAreEqual// ParallelLinesPreserveAngles// AnglesOfATriangleSumTo180// CircleHasAConstantRadius// DrawSemiCircle// TwoRightAnglesMakeASemiCircle// FourRightAnglesMakeACircle// CircleTangent// LineToPoint// ParallelLineThroughAPoint// Chord// Diameter// ChordBisection// RectangleInACircle// DoubleAnAngle BisectAnAngle// BisectALine// Kite// EquilateralTriangle (this)); } class Draw extends View // Draw animation {float screenWidth = 2000, screenHeight = 1000, // Screen dimensions cx = 1000, cy = 500, // Centre of screen in x,y - replace with display metrics radius = 400, // Radius of circle and semi circles - compute from screensize axisLength = 2000, axisWidth = 100, // Dimensions of an axis bar - twice maximum dimension

  • pointRadius = 20, // Radius of a point limit = 2000, // Maximum dimension of drawable things arcRadius = 200, // Arc radius - shouldbe quarter minimum dimension outLineWidth = 10, // Thickness of outlineand centre line when not computed via outlineRatio outLineRatio = 10; // Outline fraction

    float period () {return 10f;} // Period of one animation step in seconds float axisInnerWidth () {return 5f;} // Width of line down centre of axis relative to axis width float ringInnerWidth () {return 5f;} // Width of line in centre of ring relative to ring width float radiusInnerWidth () {return 5f;} // Width of line in centre of radius relative to radius width float radiusWidthRatio () {return 0.1f;} // Ratio of length of radius to width float rightAngleTolerance() {return 2f;} // Right angle tolerance in degrees

    float radiusWidthRatio(float r) {return r * radiusWidthRatio();} // Ratio of length of radius to width final Random random = new Random(); // Random number generator final long startTime = t(); // Start time of animation final Path arcPath = new Path(); // Arc path final RectF unitSquare = new RectF(-1, -1, 1, 1); // Unit square final RectF rectF = new RectF(); // Rectangle with floating point coordinates final Matrix matrix = new Matrix(); // Matrix

    Draw(Activity Activity) // Construct {super(Activity); setTitle(title()); // Thetitle of the piece }

    protected void onSizeChanged (int w, int h, int oldw, int oldh) // Size change {final float m = m(w, h), M = M(w, h); screenWidth = w; screenHeight = h; // Screen dimensions axisLength = M; // Axis dimensions axisWidth = radiusWidthRatio(m); cx = w /

  • 2; // Centre cy = h / 2; radius = 0.4f * m; // Radius pointRadius = m(0.02f * m, 8); // Radius of a point outLineWidth = m(0.01f * m, 4); // Thickness of outline and centerline limit = M; // Maximum dimension of drawable things arcRadius = m/4f; // Arc radius - should be quarter minimum dimension }

    //------------------------------------------------------------------------------// Colours//------------------------------------------------------------------------------

    final ColourSet ColourSet1 = new ColourSet(Colours.SpanishSkyBlue, Colours.SpanishOrange, Colours.SpanishBlue, Colours.SpanishRed, Colours.SpanishGreen, Colours.SpanishPink, Colours.White, Colours.Yellow), ColourSet2 = new ColourSet(Colours.VividOrchid, Colours.VividCerulean, Colours.VividRed, Colours.VividMalachite, Colours.VividAmber, Colours.VividTangerine, Colours.White, Colours.VividBurgundy), ColourSet3 = new ColourSet(Colours.MediumTuscanRed, Colours.MediumChampagne, Colours.MediumSeaGreen, Colours.MediumPurple, Colours.MediumSkyBlue, Colours.MediumLavenderMagenta, Colours.White, Colours.MediumJungleGreen), ColourSetO1 = ColourSet1.setAlpha(224), ColourSetO2 = ColourSet2.setAlpha(224), ColourSetO3 = ColourSet3.setAlpha(224), ColourSeto1 = ColourSet1.setAlpha(192), ColourSeto2 = ColourSet2.setAlpha(192), ColourSeto3 = ColourSet3.setAlpha(192);

    class ColourSet {final Paint angle, axis, point, radius, ring, centre, outLine, cross; ColourSet(int Angle, int Axis, int Point, int Radius, int Ring, int Cross,int Centre, int OutLine) {angle = paint(Angle , 0); axis = paint(Axis , 0); point = paint(Point , 0); radius = paint(Radius , 0); ring = paint(Ring , 0); cross = paint(Cross , 0); centre = paint(Centre , 0); outLine = paint(OutLine, outLineWidth); } ColourSet(ColourSet Colours) // Clone {angle = new Paint(Colours.angle); axis = new Paint(Colours.axis); point = new Paint(Colours.point); radius = new Paint(Colours.radius); ring = new Paint(Colours.ring); cross = new Paint(Colours.cross); centre = new Paint(Colours.centre); outLine = new Paint(Colours.outLine);

  • } ColourSet setAlpha(int a) // Set opacity {final ColourSet c = new ColourSet(this); c.angle .setAlpha(a); c.axis .setAlpha(a); c.point .setAlpha(a); c.radius .setAlpha(a); c.ring .setAlpha(a); c.cross .setAlpha(a); c.centre .setAlpha(a); c.outLine.setAlpha(a); return c; } private Paint paint(int Color, float strokeWidth) // Create a paint {final Paint p = new Paint(); p.setAntiAlias(true); p.setColor(Color); if (strokeWidth == 0) {p.setStyle(Paint.Style.FILL_AND_STROKE); } else {p.setStyle(Paint.Style.STROKE); p.setStrokeWidth(strokeWidth); } return p; } Paint outLine(float r) // Paint for outline {final Paint p = outLine; // Not thread safe, but avoids allocation p.setStrokeWidth(M(1f, r / outLineRatio)); // At least one pixel wide return p; } }

    String title() {return "";} // Default title

    //------------------------------------------------------------------------------// Steps and fractions//------------------------------------------------------------------------------

    float stepAsFloat() {return f(since(startTime)) / period();} // Step as step.fraction float periodFraction() {return f((since(startTime) % period()) / period());}// Position in step

    float fraction() // Accelerate and de-accelerate along a sine squared wave {final float p = periodFraction(), f = f(Math.sin(p * /2)); return f*f; }

    float fraction(final boolean reverse) // Reversed - symmetric {final float f = fraction(); if (reverse) return 1f - f; return f; }

  • float fractionSin() // Sine squared fraction of positive half of wave gives softer start and end {final float f = f(Math.sin(periodFraction() * )); return f*f; } float fractionSin(float f) {return f*fractionSin();}

    float outBack() {return fraction(step() % 2 == 1);} // Out in one step and then back again float outBack(float f) {return outBack() * f;} // Out in one step and then back again with scale

    float outStopBack() // Out in one step and stop for one step then back again {final float s = step() % 3; return s == 1 ? 1f : fraction(s == 2); }

    float outStopBack(float f) {return outStopBack() * f;} // Out in one step and stop for one step then back again with scale float outStopBack(float a, float b) {return a + outStopBack(b - a);} // Out, stop, back within limits

    boolean outZoomBack(Canvas Canvas) // Out, zoom up and down, back {if (step() % 3 == 1) {final float s = 1 + fractionSin(); Canvas.scale(s, s, cx, cy); return true; } return false; }

    boolean outZoomBack(Canvas Canvas, float x, float y) // Out, zoom up and down, back at specified coordinates {if (step() % 3 == 1) {final float s = 1 + fractionSin(); Canvas.scale(s, s, cx+x, cy+y); return true; } return false; }

    float stopOutStopBack() // Out in one step and stop for one step then back again {final float s = step() % 4; return s == 0 ? 0 : s == 2 ? 1f : fraction(s == 3); }

    float stopOutStopBack(float f) {return stopOutStopBack() * f;} // Out in one step and stop for one step then back again with scale float stopOutStopBack(float a, float b) {return a + stopOutStopBack(b - a);}// Out, stop, back within limits

    float fractionWithHalfWayDelay() // Accelerate and de-accelerate along a sine squared wave with a half way delay

  • {final float h = 1f/2f, // Half p = periodFraction(), // Position in step f = f(Math.sin((p - 0) * )), F = f(Math.sin((p - h) * )), r = p < h ? f*f*h : h+F*F*h; // Ramp from 0 to 1/2 with Sin 1/4 period in first half of step and from 1/2 to 1 with Sin 1/4 period in second half of step return r; } float fractionExp(final float p) // Accelerate exponentially {final float x = p /2, // x between*0 and +pi/2 s = f(Math.sin(x)), // sin(x) y = f(Math.exp(x)*s*s), // exp(x)sin(x)**2 Y = f(Math.exp /2)), (// Maximum r = y / Y; // Normalized result return r; } float fractionExp() {return fractionExp(periodFraction());} float fractionExp(final boolean reverse) // Accelerate exponentially {final float f = fractionExp(); return reverse ? fractionExp(1f - periodFraction()): fractionExp( periodFraction()); } float outBackExp() {return fractionExp(step() % 2 == 1);} // Out in one step and then back again float outBackExp(float f) {return outBackExp() * f;} // Out in one step and then back again with scale float outStopBackExp() {final float s = step() % 3; return s == 1 ? 1f : fraction(s == 2);} // Out in one step and stop for one step then back again float outStopBackExp(float f) {return outStopBackExp() * f;} // Out in one step and stop for one step then back again with scale

    int step() // Step in animation {return i(Math.floor(since(startTime) / period()) % steps()); } int steps() {return 999999;} // Override with the number of steps in the animation class Pulse // Flip flop once per step {int lastStep = -1; boolean pulse()

  • {final int step = i(Math.floor(stepAsFloat())); if (step != lastStep) {lastStep = step; return true; } return false; } }

    //------------------------------------------------------------------------------// Geometric elements//------------------------------------------------------------------------------

    float xPolar(float Radius, float Angle) {return f(cd(Angle)*Radius);} // X coordinate from polar coordinates float yPolar(float Radius, float Angle) {return f(sd(Angle)*Radius);} // Y coordinate from polar coordinates

    // Angle + Right Angle

    void drawAngle(Canvas Canvas, ColourSet Colours, // Draw background and foreground of an angle which is not a right angle float X, float Y, float Radius, float Angle1, float Angle2) {drawAngle1(Canvas, Colours, X, Y, Radius, Angle1, Angle2); drawAngle2(Canvas, Colours, X, Y, Radius, Angle1, Angle2); }

    void drawAngle1(Canvas Canvas, ColourSet Colours, // Draw background of an angle which is not aright angle, float X, float Y, float Radius, float Angle1, float Angle2) {drawAngle(Canvas, X, Y, Radius, Angle1, Angle2, false, Colours.angle); }

    void drawAngle2(Canvas Canvas, ColourSet Colours, // Draw foreground of an angle which is not aright angle float X, float Y, float Radius, float Angle1, float Angle2) {drawAngle(Canvas, X, Y, Radius, Angle1, Angle2, false, Colours.outLine(Radius)); }

    void drawRightAngle1(Canvas Canvas, ColourSet Colours, // Draw background of an angle which might be right angle float X, float Y, float Radius, float Angle1, float Angle2) {drawAngle(Canvas, X, Y, Radius, Angle1, Angle2, true, Colours.angle); }

    void drawRightAngle2(Canvas Canvas, ColourSet Colours, // Draw foreground of an angle which might be right angle float X, float Y, float Radius, float Angle1, float Angle2) {drawAngle(Canvas, X, Y, Radius, Angle1, Angle2, true, Colours.outLine(Radius)); } void drawRightAngle(Canvas Canvas, ColourSet Colours, // Draw background of an angle which might be right angle float X, float Y, float Radius, float Angle1, float Angle2) {drawRightAngle1(Canvas, Colours, X, Y, Radius, Angle1, Angle2); drawRightAngle2(Canvas, Colours, X, Y, Radius, Angle1, Angle2); }

  • void drawAngle(Canvas Canvas, float X, float Y, float Radius, // Draw an angle at position with radius=width of angle, float Angle1, float Angle2, boolean rightAngles, Paint Paint) // Between angles, right angle display, paint {final Canvas c = Canvas; final Path p = arcPath; final float R = Radius, A = Angle1, a = Angle2 - A; // Angle of angle final float r = rightAngleTolerance(); // Right angle tolerance

    p.reset(); p.moveTo(0, 0); p.lineTo(1f, 0f); if (!rightAngles || a < 90-r || a > 90+r) // Not a right angle or right angles not requested, {p.addArc(unitSquare, 0, a); } else // Right angle {p.lineTo(1f, 1f); p.lineTo(0f, 1f); } p.lineTo(0, 0); p.close();

    final Matrix m = matrix; // Scale up path to size of an arc m.reset(); m.postScale(R, R); m.postRotate(A); p.transform(m);

    c.save(); c.translate(cx+X, cy+Y); // Places the origin at the centre of the screen, c.drawPath(p, Paint); c.restore(); } void drawRightAngle(Canvas Canvas, ColourSet Colours, // Draw a right angle between vectors - background and foreground combined float , float , float X, float Y, float , float , // Right angle between: , ), (X, Y), , ) (

    float Radius) // Right angle size {drawRightAngle1(Canvas, Colours, , , X, Y, , , Radius); drawRightAngle2(Canvas, Colours, , , X, Y, , , Radius); } void drawRightAngle1(Canvas Canvas, ColourSet Colours, // Draw a right angle between vectors - background float , float , float X, float Y, float , float , // Right angle between: , ), (X, Y), , ) (

    float Radius) // Right angle size {drawRightAngle(Canvas, , , X, Y, , , Radius, Colours.angle); }

  • void drawRightAngle2(Canvas Canvas, ColourSet Colours, // Draw a right angle between vectors - foreground float , float , float X, float Y, float , float , // Right angle between: , ), (X, Y), , ) (

    float Radius) // Right angle size {drawRightAngle(Canvas, , , X, Y, , , Radius, Colours.outLine(Radius)); } void drawRightAngle(Canvas Canvas, // Draw a right angle between vectors float , float , float X, float Y, float , float , // Right angle between: , ), (X, Y), , ) (

    float Radius, Paint Paint) // Right angle size and paint {final Canvas c = Canvas; final Path p = arcPath; final float = - X, = - Y, = d , ) / Radius, ( = - X, = - Y, = d , ) / Radius; ( (

    p.reset(); // Path of right angle p.moveTo(X, Y); p.lineTo(X , Y ); +/ +/// Edge p.lineTo(X , Y ); +/+/ +/+/+/ +/// Centre p.lineTo(X+ , Y+ ); / / / /// Other edge p.lineTo(X, Y); // Start p.close();

    c.save(); c.translate(cx, cy); // Places the origin at the centre of the screen, c.drawPath(p, Paint); // Draw right angle c.restore(); } void drawAngle (Canvas c, ColourSet C, float R, float a, float A) {drawAngle (c, C, 0, 0, R, a, A);} void drawAngle1 (Canvas c, ColourSet C, float R, float a, float A) {drawAngle1 (c, C, 0, 0, R, a, A);} void drawAngle2 (Canvas c, ColourSet C, float R, float a, float A) {drawAngle2 (c, C, 0, 0, R, a, A);} void drawRightAngle (Canvas c, ColourSet C, float R, float a, float A) {drawRightAngle (c, C, 0, 0, R, a, A);} void drawRightAngle1(Canvas c, ColourSet C, float R, float a, float A) {drawRightAngle1(c, C, 0, 0, R, a, A);} void drawRightAngle2(Canvas c, ColourSet C, float R, float a, float A) {drawRightAngle2(c, C, 0, 0, R, a, A);}

    // Axis

    void drawAxis1(Canvas Canvas, ColourSet Colours, // Draw background elements of an axis at through position(X, Y) at angle with colours float X, float Y, float Angle) {drawAxis (Canvas, X, Y, Angle, Colours.axis, null);

  • drawAxis (Canvas, X, Y, Angle, Colours.outLine, null); } void drawAxis2(Canvas Canvas, ColourSet Colours, // Draw foreground elements of an axis at through position(X, Y) at angle with colours float X, float Y, float Angle) {drawAxis (Canvas, X, Y, Angle, null, Colours.centre); } void drawAxis(Canvas Canvas, ColourSet Colours, // Draw foreground and background elements of an axis at through position(X, Y) at angle with colours float X, float Y, float Angle) {drawAxis1 (Canvas, Colours, X, Y, Angle); drawAxis2 (Canvas, Colours, X, Y, Angle); } void drawAxis(Canvas Canvas, // Draw elements of an axis at through position(X, Y) at angle with colours float X, float Y, float Angle, Paint back, Paint out) {final Canvas c = Canvas; final float L = axisLength, // Axis length W = axisWidth / 2, // Axis outer width w = axisInnerWidth(); // Axis inner width final Paint p = back, P = out; c.save(); c.translate(X+cx, Y+cy); // Places the origin at the centre of the screen c.rotate(Angle, 0, 0); // Angle is clockwise if (back != null) c.drawRect(-L, -W, +L, +W, back); // Axis if (out != null) c.drawRect(-L, -w, +L, +w, out); // Interior c.restore(); } void drawAxis (Canvas c, ColourSet C, float A) {drawAxis (c, C, 0, 0, A);} void drawAxis1(Canvas c, ColourSet C, float A) {drawAxis1(c, C, 0, 0, A);} void drawAxis2(Canvas c, ColourSet C, float A) {drawAxis2(c, C, 0, 0, A);}

    // Circle

    void drawCircle(Canvas Canvas, ColourSet Colours, // Draw the foreground elements of a circle float X, float Y, float Radius, float I, float O) {drawCircle1(Canvas, Colours, X, Y, Radius, I, O); drawCircle2(Canvas, Colours, X, Y, Radius, I, O); }

    void drawCircle1(Canvas Canvas, ColourSet Colours, // Draw the background elements of a circle float X, float Y, float Radius, float I, float O) {drawCircle (Canvas, X, Y, Radius, I, O, Colours.ring); drawCircle (Canvas, X, Y, Radius, I, O, Colours.outLine(Radius*(I+O))); }

    void drawCircle2(Canvas Canvas, ColourSet Colours, // Draw the foreground elements of a circle

  • float X, float Y, float Radius, float I, float O) {final float w = ringInnerWidth() / Radius; // Inner circle size drawCircle (Canvas, X, Y, Radius, w, w, Colours.centre); // Inner circle }

    void drawCircle(Canvas Canvas, float X, float Y, float Radius, // Draw a circle at position(X,Y) with radius float I, float O, Paint Paint) // Fraction of radius in and out, between angles with paint {final Canvas c = Canvas; final Path p = arcPath; final float ir = 1f-I, or = 1f+O; // Scaled inner and outer radii

    p.reset(); p.moveTo(or, 0); // Lower left corner of circle

    final RectF r = rectF; // Local rename r.set(-or, -or, +or, +or); // Square containing outer arc p.arcTo(r, 0, 359.99f); // Outer arc p.moveTo(ir, 0); // Move to inner arc r.set(-ir, -ir, +ir, +ir); // Square containing inner arc p.arcTo(r, 0, -359.99f); // Inner arc p.moveTo(or, 0); // Lower left corner of circle p.close();

    final Matrix m = matrix; // Scale up path to size indicated by Radius m.reset(); m.postScale(Radius, Radius); m.postTranslate(X, Y); p.transform(m);

    c.save(); c.translate(cx, cy); // Places the origin at the centre of the screen c.drawPath(p, Paint); c.restore(); }

    void drawCircle( Canvas c, ColourSet C) {drawCircle (c, C, 0, 0, radius, radiusWidthRatio(), radiusWidthRatio());} void drawCircle( Canvas c, ColourSet C, float R) {drawCircle (c, C, 0, 0, R, radiusWidthRatio(), radiusWidthRatio());} void drawCircle( Canvas c, ColourSet C, float X, float Y) {drawCircle (c, C, X, Y, radius, radiusWidthRatio(), radiusWidthRatio());}

  • void drawCircle( Canvas c, ColourSet C, float X, float Y, float R) {drawCircle (c, C, X, Y, R, radiusWidthRatio(), radiusWidthRatio());} void drawCircle1(Canvas c, ColourSet C) {drawCircle1 (c, C, 0, 0, radius, radiusWidthRatio(), radiusWidthRatio());} void drawCircle1(Canvas c, ColourSet C, float R) {drawCircle1 (c, C, 0, 0, R, radiusWidthRatio(), radiusWidthRatio());} void drawCircle1(Canvas c, ColourSet C, float X, float Y) {drawCircle1 (c, C, X, Y, radius, radiusWidthRatio(), radiusWidthRatio());} void drawCircle1(Canvas c, ColourSet C, float X, float Y, float R) {drawCircle1 (c, C, X, Y, R, radiusWidthRatio(), radiusWidthRatio());} void drawCircle2(Canvas c, ColourSet C) {drawCircle2 (c, C, 0, 0, radius, radiusWidthRatio(), radiusWidthRatio());} void drawCircle2(Canvas c, ColourSet C, float R) {drawCircle2 (c, C, 0, 0, R, radiusWidthRatio(), radiusWidthRatio());} void drawCircle2(Canvas c, ColourSet C, float X, float Y) {drawCircle2 (c, C, X, Y, radius, radiusWidthRatio(), radiusWidthRatio());} void drawCircle2(Canvas c, ColourSet C, float X, float Y, float R) {drawCircle2 (c, C, X, Y, R, radiusWidthRatio(), radiusWidthRatio());}

    // Cross

    void drawCross(Canvas Canvas, ColourSet Colours, float X, float Y, // Draw a cross float Width, float Rotate, float Radius, float Angle) // Size of cross, angle of rotation, additional polar(R, A) displacement {final Canvas c = Canvas; final Path p = arcPath; final float = 0.4f, w = 1f/2f - ; final float = xPolar(Radius, Angle), // Polar displacement x = yPolar(Radius, Angle); // Polar displacement y p.reset(); p.moveTo( w, -w); // Left corner

    p.lineTo( 1, -w); p.lineTo( 1, w); p.lineTo( w, w);

    p.lineTo( w, 1); p.lineTo(-w, 1); p.lineTo(-w, w);

    p.lineTo(-1, w); p.lineTo(-1, -w); p.lineTo(-w, -w);

    p.lineTo(-w, -1); p.lineTo( w, -1); p.lineTo( w, -w); p.close();

    final Matrix m = matrix; // Scale up path to size indicated by Radius m.reset(); m.postScale(Width, Width); m.postRotate(Rotate, 0, 0); // Rotate m.postTranslate(X, Y); p.transform(m);

  • c.save(); c.translate(cx , cy ); + +// Places the origin at the centre of the screen c.drawPath(p, Colours.cross); c.restore(); } void drawCross(Canvas c, ColourSet C) {drawCross(c, C, 0, 0, radius/8, 0, 0, 0);} void drawCross(Canvas c, ColourSet C, float X, float Y) {drawCross(c, C, X, Y, radius/8, 0, 0, 0);} void drawCross(Canvas c, ColourSet C, float X, float Y, float W) {drawCross(c, C, X, Y, W, 0, 0, 0);} void drawCross(Canvas c, ColourSet C, float X, float Y, float W, float A) {drawCross(c, C, X, Y, W, A, 0, 0);}

    // Point

    void drawPoint(Canvas Canvas, ColourSet Colours, float X, float Y, // Draw a point at position(X,Y) float Width, float Radius, float Angle) // With width, at the end of a radius rotated through an angle {final Canvas c = Canvas; final float R = Radius, r = Width, a = Angle; // Half width of radius, angle, polar position

    c.save(); c.translate (cx+X, cy+Y); // Origin of radius c.rotate (a, 0, 0); // Angle is clockwise c.drawCircle (R, 0, r, Colours.point); // Circle representing a point c.restore(); } void drawPoint(Canvas c, ColourSet C, float W) {drawPoint(c, C, 0, 0, W, 0, 0);} void drawPoint(Canvas c, ColourSet C, float X, float Y, float W) {drawPoint(c, C, X, Y, W, 0, 0);}

    // Radius

    void drawRadius(Canvas Canvas, ColourSet Colours, float X, float Y, // Draw foreground elements of a radius float Radius, float WidthRatio, float Angle) {drawRadius1 (Canvas, Colours, X, Y, Radius, WidthRatio, Angle); drawRadius2 (Canvas, Colours, X, Y, Radius, WidthRatio, Angle); }

    void drawRadius1(Canvas Canvas, ColourSet Colours, float X, float Y, // Draw background elements of a radius = inner+outline float Radius, float WidthRatio, float Angle) {drawRadius(Canvas, X, Y, Radius, WidthRatio, Angle, Colours.radius); drawRadius(Canvas, X, Y, Radius, WidthRatio, Angle, Colours.outLine(Radius*WidthRatio)); }

    void drawRadius2(Canvas Canvas, ColourSet Colours, float X, float Y, // Draw foreground elements of a radius float Radius, float WidthRatio, float Angle) {final float w = radiusInnerWidth() / Radius; drawRadius(Canvas, X, Y, Radius, w, Angle, Colours.centre); }

  • void drawRadius(Canvas Canvas, float X, float Y, float Radius, // Draw a radius at position(X,Y) with radius and width, atangle with paint float widthRatio, float Angle, Paint paint) // Width of radius relative to length, angle of radius, colour of radius, colour of circles on each end - null ofr the item not to be drawn {final Canvas c = Canvas; final float R = Radius, r = widthRatio * R / 2; // Radius, half width of radius

    final Path p = arcPath; final RectF s = rectF; p.reset(); p.moveTo(0, -r); p.lineTo(R, -r); s.set (R-r, -r, R+r, +r); p.arcTo (s, 270, 180); p.lineTo(0, +r); s.set ( -r, -r, +r, +r); p.arcTo (s, 90, 180); p.close (); c.save(); c.translate (cx+X, cy+Y); // Origin of radius c.rotate (Angle, 0, 0); // Angle is clockwise c.drawPath (p, paint); // Draw radius path c.restore(); } void drawRadius (Canvas c, ColourSet C, float R, float W, float A) {drawRadius (c, C, 0, 0, R, W, A);} void drawRadius1(Canvas c, ColourSet C, float R, float W, float A) {drawRadius1(c, C, 0, 0, R, W, A);} void drawRadius2(Canvas c, ColourSet C, float R, float W, float A) {drawRadius2(c, C, 0, 0, R, W, A);}

    // Ring

    void drawRing(Canvas Canvas, ColourSet Colours, // Draw the foreground elements of a ring float X, float Y, float Radius, float I, float O, float Angle1, float Angle2) {drawRing1(Canvas, Colours, X, Y, Radius, I, O, Angle1, Angle2); drawRing2(Canvas, Colours, X, Y, Radius, I, O, Angle1, Angle2); }

    void drawRing1(Canvas Canvas, ColourSet Colours, // Draw the background elements of a ring float X, float Y, float Radius, float I, float O, float Angle1, float Angle2) {drawRing (Canvas, X, Y, Radius, I, O, Angle1, Angle2, Colours.ring); drawRing (Canvas, X, Y, Radius, I, O, Angle1, Angle2, Colours.outLine(Radius*(I+O))); }

    void drawRing2(Canvas Canvas, ColourSet Colours, // Draw the foreground elements of a ring float X, float Y, float Radius, float I, float O, float Angle1, float Angle2) {final float w = ringInnerWidth() / Radius; // Inner ring size

  • drawRing (Canvas, X, Y, Radius, w, w, Angle1, Angle2, Colours.centre); // Inner ring }

    void drawRing(Canvas Canvas, float X, float Y, float Radius, // Draw a ring which could in fact be a circle at its full extent, at a position with radius float I, float O, float Angle1, float Angle2, Paint Paint) // Fraction of radius in and out, between angles with paint {final Canvas c = Canvas; final Path p = arcPath; final float ir = 1f-I, or = 1f+O; // Scaled inner and outer radii final float c1 = cd(Angle1), s1 = sd(Angle1); // Cos and sin of Angle1 final float c2 = cd(Angle2), s2 = sd(Angle2); // Cos and sin of Angle2

    p.reset(); p.moveTo(ir*c1, ir*s1); // Lower left corner of ring p.lineTo(or*c1, or*s1); // Line to upper left corner of ring

    final RectF r = rectF; // Local rename r.set(-or, -or, +or, +or); // Square containing outer arc p.arcTo(r, Angle1, Angle2-Angle1); // Outer arc to upper right corner p.lineTo(ir*c2, ir*s2); // Line to lower rightcorner r.set(-ir, -ir, +ir, +ir); // Square containing inner arc p.arcTo(r, Angle2, Angle1-Angle2); // Inner arc to lower right corner p.lineTo(ir*c1, ir*s1); // Line to lower left corner p.close();

    final Matrix m = matrix; // Scale up path to size indicated by Radius m.reset(); m.postScale(Radius, Radius); m.postTranslate(X, Y); p.transform(m);

    c.save(); c.translate(cx, cy); // Places the origin at the centre of the screen c.drawPath(p, Paint); c.restore(); }

  • void drawRing (Canvas c, ColourSet C, float R, float I, float O, float a, float A) {drawRing (c, C, 0, 0, R, I, O, a, A);} void drawRing1 (Canvas c, ColourSet C, float R, float I, float O, float a, float A) {drawRing1(c, C, 0, 0, R, I, O, a, A);} void drawRing2 (Canvas c, ColourSet C, float R, float I, float O, float a, float A) {drawRing2(c, C, 0, 0, R, I, O, a, A);}

    // Semi circle

    class SemiCircle // Draw a semi circle {void draw(Canvas Canvas, ColourSet Colours, float Radius, float Angle, // Draw Fraction of a semi-circle rotated through Angle float Fraction, boolean Moving) {final Canvas c = Canvas; // Canvas final ColourSet C = Colours; // Colours final float f = Fraction, A = 90 + 90*f, a = 180*f, // Angle to rotate axis, radius x = xPolar(Radius, Angle), // Centre of rotation of diameter in x y = yPolar(Radius, Angle), // Centre of rotation of diameter in y r = Radius, // Radius R = radiusWidthRatio(r); // Width of point

    side (c, C, Angle+A, x, y); // Side - moving with radii radii (c, C, r, Angle, a, 1, 0); // Radii - bar underneath ring (c, C, r, Angle, Angle+a, false); // Ring radius (c, C, r, Angle, 1, 1); // Radius - original radii (c, C, r, Angle, a, 0, 1); // Radii- end points on top drawPoint (c, C, R, 0, 0); // Centre point if (Moving) ring (c, C, r, Angle, Angle+a, true); // Ring outline if it is moving } void radii(Canvas Canvas, ColourSet Colours, float Radius, float Angle, // Draw radii float a, int Bar, int Ends) {radius (Canvas, Colours, Radius, Angle, Bar, Ends); radius (Canvas, Colours, Radius, Angle+a, Bar, Ends); } void radius(Canvas Canvas, ColourSet Colours, float Radius, float Angle, // Radius int Bar, int Ends) {final float w = radiusWidthRatio(2); drawRadius (Canvas, Colours, Radius, w, Angle); } void ring(Canvas Canvas, ColourSet Colours, float Radius, // Draw the ring of the semi circle float Angle1, float Angle2, boolean OutLine)

  • {final Canvas c = Canvas; final ColourSet C = Colours; final float w = radiusWidthRatio(), R = Radius, a = Angle1, A = Angle2; if (!OutLine) drawRing (c, C, R, w, w, a, A); else drawRing (c, C, R, w, w, a, A); } void side(Canvas Canvas, ColourSet Colours, float Angle, float X, float Y) {drawAxis (Canvas, Colours, X, Y, Angle); // Draw an axis representing the diameter }

    //------------------------------------------------------------------------------// Draw a semi circle with central right angles//------------------------------------------------------------------------------

    void drawWithCentralRightAngles1(Canvas Canvas, // Draw semi circle with central right angles - background elements, ColourSet C1, ColourSet C2, float Rotate, float Angle) // Rotation of entire figure, angle of radii {final Canvas c = Canvas; final float R = radius, r = Rotate, a = Angle; // Amount of rotation to apply to figure, angle of radii draw (c, C1, radius, r, 1f, false); // Semi circle drawRadius1 (c, C2, radius, 0.2f, r+a); drawRadius1 (c, C2, radius, 0.2f, r+180-a); } void drawWithCentralRightAngles2(Canvas Canvas, // Draw semi circle with central right angles - foreground ColourSet C1, ColourSet C2, float Rotate, float Angle) // Rotation of entire figure, angle of radii {final Canvas c = Canvas; final float R = radius, r = Rotate, w = radiusWidthRatio(2), a = Angle; // Radius, rotation of entire figure, width of radii, angle of radii

    drawRadius2 (c, C2, R, w, r+a); drawRadius2 (c, C2, R, w, r+180-a);

    drawRightAngle (c, C2, R/2, r, r+a); drawRightAngle (c, C2, R/2, r+180-a, r+180); } void drawWithCentralRightAngles(Canvas Canvas, // Draw semi circle with central right angles- foreground and background ColourSet C1, ColourSet C2, float Rotate, float Angle) // Rotation of entire figure, angle of radii {drawWithCentralRightAngles1(Canvas, C1, C2, Rotate, Angle); drawWithCentralRightAngles2(Canvas, C1, C2, Rotate, Angle); } } // SemiCircle

    //------------------------------------------------------------------------------// Draw animation//------------------------------------------------------------------------------

    public void onDraw(Canvas Canvas) // Draw animation {drawAnimation(Canvas); invalidate(); } void drawAnimation(Canvas Canvas)

  • {} // Draw animation by overriding this method }

    //----------------------------------- -------------------------------------------// Opposing angles are equal//------------------------------------------------------------------------------

    class OpposingAnglesAreEqual extends Draw // Opposing angles are equal {final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3; OpposingAnglesAreEqual(Activity Activity) {super(Activity);} // Construct void drawAnimation(Canvas Canvas) // Draw animation {final float a = 0, A = outBack(180), // Angles r = arcRadius; // Arc radius final Canvas c = Canvas; drawAxis (c, C1, a); // Axis 1 drawAxis (c, C2, A); // Axis 2 drawAngle (c, O3, r, A, 180 ); // In between angle drawAngle (c, O1, r, a, A); // Opposing angle 1 drawAngle (c, O1, r, 180+a, 180+A); // Opposing angle 2 } String title() {return "Opposing angles are equal";} }

    //------------------------------------------------------------------------------// Parallel lines preserve angles//------------------------------------------------------------------------------

    class ParallelLinesPreserveAngles extends Draw // Parallel lines preserve angles {final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3; ParallelLinesPreserveAngles(Activity Activity) {super(Activity);} // Construct void drawAnimation(Canvas Canvas) // Animation {final float a = 112, A = a + 180, // Angle of crossing line Y = radius, // Y position of line 1 y = Y * (1f - outBack()), // Y position of line 2 X = cd(a)*Y, // X positionof line 1

  • x = -cd(A)*y, // X position of line 2 r = arcRadius; // Arc radius final Canvas c = Canvas; drawAxis (c, C1, a); // Crossing line drawAxis (c, C2, X, Y, 0); // First parallel line drawAxis (c, C3, x, y, 0); // Second parallel line drawAngle (c, O1, X, Y, r, 180, A); // First angle interior line 1 drawAngle (c, O1, x, y, r, 180, A); // First angle interior line 2 drawAngle (c, C1, X, Y, r, 180, A); // First angle exterior line 1 drawAngle (c, C1, x, y, r, 180, A); // First angle exterior line 2 drawAngle (c, O2, X, Y, r, A, 360); // Second angle interior line 1 drawAngle (c, O2, x, y, r, A, 360); // Second angle interior line 2 drawAngle (c, C2, X, Y, r, A, 360); // Second angle exterior line 1 drawAngle (c, C2, x, y, r, A, 360); // Second angle exterior line 2 } String title() {return "Parallel lines preserve angles";} }//------------------------------------------------------------------------------// Inside angles of a triangle make a straight line//------------------------------------------------------------------------------

    class AnglesOfATriangleSumTo180 extends Draw // Inside angles of a triangle make a straight line {final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3; AnglesOfATriangleSumTo180(Activity Activity) {super(Activity);} // Construct void drawAnimation(Canvas Canvas) // Draw animation {final float x = -radius + 2 * outBack(radius), // X position of apex Y = cy, // Y position of base line B = cx / 2, // Half the base a = f(Math.toDegrees(Math.atan2(Y, B+x))), // Angle a b = f(Math.toDegrees(Math.atan2(Y, B-x))), // Angle b c = 180 - a - b, // Angle c r = arcRadius; // Arc radius final Canvas C = Canvas;

  • drawAxis (C, O1, 0); // Parallel to base drawAxis (C, C1, 0, Y, 0); // Base drawAxis (C, C2, x, 0, 180-a); // Left drawAxis (C, C3, x, 0, b); // Right

    drawAngle (C, O1, -B, Y, r, 360-a, 360); // a interior lower line drawAngle (C, O1, x, 0, r, 360-a, 360); // a interior upper line

    drawAngle (C, O2, B, Y, r, 180, 180+b); // b interior lower line drawAngle (C, O2, x, 0, r, 180, 180+b); // b interior upper line

    drawAngle (C, O3, x, 0, r, b, b+c); // c interior lower drawAngle (C, O3, x, 0, r, 180+b, 180+b+c); // c interior upper } String title() {return "The angles inside a triangle make a straight line";} }

    //------------------------------------------------------------------------------// Circle//------------------------------------------------------------------------------

    class CircleHasAConstantRadius extends Draw // Circle {CircleHasAConstantRadius(Activity Activity) {super(Activity);} // Construct void drawAnimation(Canvas Canvas) // Draw animation {final float a = outBack(360), w = radiusWidthRatio(), r = w * radius; // Fraction through animation final Canvas c = Canvas; final ColourSet C1 = ColourSet1, O1 = ColourSetO1; drawRing (c, C1, radius, w, w, 0, a); // Ring drawRadius1 (c, O1, radius, w*2, a); // Radius drawPoint (c, C1, r, 0, a); // Centre// drawPoint (c, C1, r, radius, a); // Centre on circumference drawRadius2 (c, C1, radius, w*2, a); // Radius centre line } String title() {return "A swinging radius draws a circle";} }

    //------------------------------------------------------------------------------// Draw Semi-Circle//------------------------------------------------------------------------------

    class DrawSemiCircle extends Draw // Draw a semi circle {final SemiCircle c1 = new SemiCircle(), c2 = new SemiCircle(); final ColourSet C1 = ColourSetO1, C2 = ColourSetO2;

  • DrawSemiCircle(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas; final int s = step(); // Step final float f = fraction(), r = radius; // Fraction of step, radius, angle

    if (s == 0) // Draw first/lower semi circle {c1.draw (c, C1, r, 0, f, true); } else if (s == 1) // Draw first staticand second/upper moving {c1.draw (c, C1, r, 0, 1f, false); c2.draw (c, C2, r, 180, f, true); } else if (s == 2) // Lower semi-circlerotating on to upper semi-circle {c1.draw (c, C1, r, 0, 1f, false); c2.draw (c, C2, r, 180, 1f, false); c1.draw (c, C1, r, f*180, 1f, true); } else // Completed circle {c1.draw (c, C1, r, 0, 1f, false); c1.draw (c, C1, r, 180, 1f, false); } } int steps() {return 4;} // Number of steps in this animation String title() {return "Two semi circles make a circle";} // Title of animation }

    //------------------------------------------------------------------------------// Draw two right angles make a semi-circle//------------------------------------------------------------------------------

    class TwoRightAnglesMakeASemiCircle extends Draw // Draw two right angles make a semi-circle {final SemiCircle cs = new SemiCircle(); final ColourSet C1 = ColourSetO1, C3 = ColourSetO3;

    TwoRightAnglesMakeASemiCircle(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {outZoomBack(Canvas); cs.drawWithCentralRightAngles(Canvas, C1, C3, 180, outStopBack(90)); } String title() {return "Two right angles make a semi circle";} }

  • //------------------------------------------------------------------------------// Draw four right angles make a circle//------------------------------------------------------------------------------

    class FourRightAnglesMakeACircle extends Draw // Draw four right angles make a circle {final SemiCircle cs = new SemiCircle(); final ColourSet C1 = ColourSetO1, C2 = ColourSetO2, C3 = ColourSetO3; FourRightAnglesMakeACircle(Activity Activity) {super(Activity);} // Construct void drawAnimation(Canvas Canvas) // Draw animation {final float a = outStopBack(90); // Angle final Canvas c = Canvas;

    outZoomBack(c); cs.drawWithCentralRightAngles1 (c, C1, C3, 0, a); cs.drawWithCentralRightAngles1 (c, C2, C3, 180, a); cs.drawWithCentralRightAngles2 (c, C1, C3, 0, a); cs.drawWithCentralRightAngles2 (c, C2, C3, 180, a); } String title() {return "Four right angles make a circle";} }

    //------------------------------------------------------------------------------// A tangent to a circle is at right angles to a radius// Focuses in the point of contact between a segment of a circle and a tangent//------------------------------------------------------------------------------

    class CircleTangent extends Draw // A tangent to a circle is atright angles to a radius {final ColourSet C1 = ColourSetO1, C2 = ColourSetO2, C3 = ColourSetO3; CircleTangent(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final int s = step(); // Step final Canvas c = Canvas; final float S = 1 + outStopBack(), // Zoom in x = radius, // Segment width y = outStopBackExp(50 * x), // Segment height - as this is anexponential movement the multiplier can be chosen inaccurately Y = y, // Y positionof centre of circle containing segment adjusted for offset a = at(y, x), // Angle of segment am = at(y, cx), // Angle of ring todraw so that it goes off edges of screen, but Android does not get a chance to complain it is too big too draw A = a / 2, // Angle of chordfrom apex to segment edge R = d(x,

  • y), // Segment radius r = y
  • final float r = outStopBack(radius), w = radiusWidthRatio(); // Current radius

    outZoomBack(c, radius, 0); drawAxis (c, C1, radius, 0, 90); // Line on right drawRing (c, C1, r, w, w, 0, 359.99f); // Circle drawRing (c, C1, r, w, w, 0, 359.99f); // Circle outline drawRadius (c, C1, r, w, 0); // Radius

    drawAxis (c, C1, radius, 0, 90); // Thin line on right drawRing (c, C1, r, w, w, 0, 359.99f); // Thin line in ring

    if (step() % 3 == 1) {drawRightAngle (c, C1, r, 0, r/2, 90, 180); // Angle lower drawRightAngle (c, C1, r, 0, r/2, 180, 270); // Angle upper } } String title() {return "The shortest distance from a line to a point is a right angle";} }

    //------------------------------------------------------------------------------// Parallel line through a point//------------------------------------------------------------------------------

    class ParallelLineThroughAPoint extends Draw // Parallel line through a point {final ColourSet C1 = ColourSetO1, C2 = ColourSetO2, C3 = ColourSetO3;

    ParallelLineThroughAPoint(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas; final float d = f(Math.toDegrees(2)), // The linear amount the ring will rotate A = outBack(d), // The anglethrough which the ring will rotate a = 90 - d / 2 + A, // Distribute angle r = radius, // Radius x = -r + outBack(2*r), // Constant widthradius same size as axis w = radiusWidthRatio();

    drawAxis (c, C2, 0,-r, 0); // Upper line drawAxis (c, C2, 0); // Middle drawAxis (c, C2, 0, r,

  • 0); // Lower line

    drawRing (c, C2, x, 0, r, w, w, a+0, a+359); // Circle

    drawRadius (c, C2, x, 0, r, w, 90); // Radius lower drawRadius (c, C2, x, 0, r, w, 270); // Radius upper

    drawRightAngle (c, C1, x, 0, r/4, 0, 90); // Right Angles drawRightAngle (c, C2, x, 0, r/4, 90, 180); drawRightAngle (c, C1, x, 0, r/4, 180, 270); drawRightAngle (c, C2, x, 0, r/4, 270, 360); } String title() {return "Parallel line through a point";} }

    //------------------------------------------------------------------------------// Chord//------------------------------------------------------------------------------

    class Chord extends Draw // Chord {final ColourSet C1 = ColourSet1, O1 = ColourSetO1;

    Chord(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas;

    final float s = stepAsFloat(), // Step as afloat a = s*180, A = s*300, // Start and end angles, r = radius, w = radiusWidthRatio(), // Radius, radius width x = xPolar(r, a), y = yPolar(r, a), // Start position X = xPolar(r, A), Y = yPolar(r, A), // End position d = d(X-x, Y-y), // Length of radius R = at(X-x, Y-y); // Rotation of radius

    drawCircle (c, C1); // Circle drawRadius (c, O1, x, y, d, w, R); // Chord } String title() {return "Chord";} }

    //------------------------------------------------------------------------------// Diameter//------------------------------------------------------------------------------

    class Diameter extends

  • Draw // Diameter {final ColourSet C1 = ColourSetO1, C2 = ColourSetO2, C3 = ColourSetO3;

    Diameter(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas; final float a = outBack(180), r = radius, w = radiusWidthRatio(); // Angle, radius, radius width

    drawCircle (c, C3); // Circle drawRadius (c, C3, r, w, a); // Radii drawRadius (c, C3, r, w, 180+a); } String title() {return "Diameter";} }

    //------------------------------------------------------------------------------// Cutting a chord in two//------------------------------------------------------------------------------

    class ChordBisection extends Draw // Cutting a chord in two {final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3;

    ChordBisection(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas;

    final float a = 30, A = 150, // Start and end angles, r = radius, w = radiusWidthRatio(), // Radius, radius width x = xPolar(r, a), y = yPolar(r, a), // Start position X = xPolar(r, A), Y = yPolar(r, A), // End position d = d(X-x, Y-y), // Length of radius R = at(X-x, Y-y), // Rotation of radius = yPolar(r, a), // Short length of bisecting radius - bisecting circle is labelled with bold letters, = stopOutStopBack , r), ( (// Bisecting circle radius - the vertical from the centre to the chord, = ac , ), ( ( // Angle of moving radius to vertical, = yPolar , ), ( ( // x position of moving bisection radius = xPolar , ); ( ( // y position of moving bisection radius

  • if (step() == 0) // Make the action more visible {final float s = 2 -fractionSin(); c.translate(0, fractionSin(r) - r); c.scale(s, s, cx, cy); } else {c.translate(0, -r); c.scale(2, 2, cx, cy); }

    drawCircle (c, C1); // Circle drawRadius (c, C1, r, w, a); // Radius - right drawRadius (c, C1, r, w, A); // Radius - left drawRadius (c, C1, r, w, 90); // Radius - left

    drawRadius (c, C2, x, y, d, w, R); // Chord drawPoint (c, C1, r*w); // Centre drawCircle (c, O3, ); // Bisecting circle drawRadius (c, O3, , w, 90 ); + +// Bisecting radius - left drawRadius (c, O3, , w, 90 ); - -// Bisecting radius - right

    drawRightAngle (c, O1, , , r/6, -90, - 0); // Far left angle drawRightAngle (c, O1, , , r/6, 180, 270 ); + - + -// Far right angle

    drawAngle (c, O2, r/6, 90, 90 ); + +// Top left angle drawAngle (c, O2, r/6, 90 , -90); // Top right angle

    drawRightAngle (c, O3, 0, , r/6, 180, 270); // Centre left right angle drawRightAngle (c, O3, 0, , r/6, 270, 359.99f); // Centre right right angle } int steps() {return 4;} // Number of steps in this animation String title() {return "Cutting a chord in two";} float radiusWidthRatio() {return super.radiusWidthRatio()/2f;} // Make elements thinner }

    //------------------------------------------------------------------------------// Rectangle in a circle//------------------------------------------------------------------------------

    class RectangleInACircle extends Draw // Rectangle in a circle {final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3;

  • RectangleInACircle(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas; final float = outStopBack(1f/4f, 3f/4f), // Fraction = radius, = 2 * , = / 3, // Radius, diameter, right angle radius a = *180%360, A = *360%360, // Start and end angles, x = xPolar , a), X = xPolar , A), (( ( (// Start positions in x y = yPolar , a), Y = yPolar , A), (( ( (// Start positions in x w = radiusWidthRatio()/2; // Width ratio of diameters

    drawCircle (c, C1); // Circle

    drawRightAngle(c, C3, -X, -Y, x, y, X, Y, ); // Corners drawRightAngle(c, C3, -X, -Y, -x, -y, X, Y, ); drawRightAngle(c, C3, -x, -y, X, Y, x, y, ); drawRightAngle(c, C3, -x, -y, -X, -Y, x, y, );

    drawRadius (c, C1, -x, -y, , w, a); // Diagonals drawRadius (c, C1, -X, -Y, , w, A);

    line (c, C3, -x, -y, -X, -Y); // Rectangle border line (c, C2, -x, -y, X, Y);

    line (c, C2, x, y, -X, -Y); line (c, C3, x, y, X, Y);

    angle (c, O1, x, y, X, Y); // Angles with diagonals angle (c, O2, x, y, -X, -Y); angle (c, O2, -x, -y, X, Y); angle (c, O1, -x, -y, -X, -Y);

    angle (c, O1, X, Y, x, y); angle (c, O2, X, Y, -x, -y); angle (c, O2, -X, -Y, x, y); angle (c, O1, -X, -Y, -x, -y); } void line(Canvas c, ColourSet C, float x, float y, float X, float Y) // Line between two points as a radius {final float = X - x, = Y - y, a = at , ), d = d , ), ( ( ( ( w = radius / d * radiusWidthRatio(); // Width independent of length drawRadius(c, C, x, y, d, w, a); } void angle(Canvas c, ColourSet C, float x, float y, float X, float Y) // Angle between centre, first, second points {final float a = at( -x, -y),

  • A = at(X-x, Y-y), q = a(A - a) > 180 ? 360 : 0; drawAngle(c, C, x, y, radius/4, q+m(a, A), M(a, A)); // Draw angle } String title() {return "Rectangle in a circle";} float radiusWidthRatio() {return super.radiusWidthRatio()/2f;} // Make elements thinner }

    //------------------------------------------------------------------------------// Double an angle//------------------------------------------------------------------------------

    class RectDoubleAnAngle extends Draw // Double an angle {final SemiCircle c1 = new SemiCircle(); final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3;

    RectDoubleAnAngle(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas; final float f = outStopBack(6f/4f), // Fraction a = f*90, A = a / 2, // Angle that will be divided r = radius, = 2 * xPolar(r, A), = r / 3, // Radius, chord, angle radius w = radiusWidthRatio(); // Width ratio of diameters

    c.translate(0, r); // Position to observe action c.scale (2, 2, cx, cy);

    c1.draw (c, C1, r, 180, 1f, false); // Semi circle

    drawRadius (c, C3, 0, 0, r, w, 180+a); // Radius drawRadius (c, C3, r, 0, , r*w , / /180+A); // Chord drawRadius (c, C1, 0, 0, r, w/2, 180+A); // Chord

    drawAngle (c, O1, 0, 0, , 180, 180+A); // First angle at centre drawAngle (c, O1, 0, 0, , 180+A, 180+a); // Second angle at centre drawAngle (c, O1, r, 0, , 180, 180+A); // Angle at far right

    drawAngle (c, O1, r - xPolar , A), -yPolar , A), , A, (( ( (2*A); // Overhead angle }

  • String title() {return "Bisect an angle";} float radiusWidthRatio() {return super.radiusWidthRatio()/2f;} // Make radii thinner }

    //------------------------------------------------------------------------------// Bisect an angle//------------------------------------------------------------------------------

    class BisectAnAngle extends Draw // Bisect an angle {final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3; final Pulse pulse = new Pulse(); // Flip flop once per animation cycle BisectAnAngle(Activity Activity) {super(Activity);} // Construct

    private float angle = 30; // Angle to bisect float angle() // Angle to bisect {if (step() % 3 == 0 && pulse.pulse()) angle = 30+random.nextFloat()*60; // Generate a new angle return angle; } void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas; final float a = angle(), // Angle to be bisected r = radius, = r / 3, // Radius, angle radius d = 2 * r, // Length of sides of angle to be bisected x = xPolar(r, 360-a), y = yPolar(r, 360-a), // Touch point on circle of upper side of angle to be bisected = d(r+x, y), // Length of bottomsegment along which parallel transcribing circle runs = a / 2, // Half angle tobe bisected = yPolar(r, ), // Radius of

    transcribing circle = xPolar(r, 360 ), - -// Maximum position of centre of transcribing circle = outStopBack(xPolar , 360 )), = outStopBack(yPolar , 360 )), (- (- ( - ( -// Moving position of centre parallel transcribing circle = d , ), ( ( // Length of bisecting line between two circle centres = radiusWidthRatio(), // Width ratio of diameters w = /

  • 2, // Width ratio of sides of angle to be bisected = r * w; / /// Width ratio of line along which transcribing circle rolls

    if (step() % 3 == 1) // Move to a better position at which to observe the result {final float f = fractionSin(); c.translate(-f , -f ); * * c.scale (1+f, 1+f, cx, cy); }

    drawAngle (c, C1, 0, 0, , 360-a, 359.99f); // Angle to be bisected drawRadius (c, C1, 0, 0, d, w, 360-a); // Radius - upper side of angle drawRadius (c, C1, 0, 0, d, w, 0); // Radius - lower side of angle

    drawCircle (c, O1, 0, 0, r); // Circle centred on angle drawRadius (c, C1, 0, 0, r, , 180- a); // Radius - extension of upper side to formdiameter drawRadius (c, C1, 0, 0, r, , 180); // Radius - extension of lower side to form diameter drawRadius (c, O3, -x, -y, , , 360- ); // Lower line along which bisecting circle

    rolls drawRadius (c, O3, -r, 0, , , 360- ); // Upper line along which the transcribing

    circle rolls drawAngle (c, C2, -x, -y, , 360-a, 360- ); // Half of angle to be bisected

    drawCircle (c, C2, , , ); // Circle rolls forward to drawbisector drawCross (c, C2, , , /4, 90 ); - -// Cross at centre of transcribing circle drawRadius (c, C2, , , , w, 90 ); - -// Lower radius at 90 to bisector drawCross (c, O2, , , /8, 90 , , 90 ); - - - -// Cross at lower edge of transcribing circle drawRadius (c, C2, , , , w, 270 ); - -// Upper radius at 90 to bisector drawCross (c, O2, , , /8, 270 , , 270 ); - - - -// Cross at upper edge of transcribing circle

    drawRadius (c, C3, 0, 0, , w, 360 ); - -// Bisector between centres of each circle } String title() {return "Bisect an angle";} float radiusWidthRatio() {return super.radiusWidthRatio()/2f;} // Make radii thinner }

    //------------------------------------------------------------------------------// Bisect a line segment//------------------------------------------------------------------------------

    class RectBisectALine extends

  • Draw // Bisect a line {final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3;

    RectBisectALine(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas; final float r = radius, = 2 * r, d = outStopBack(r), // Radius, diameter, animated diameter w = radiusWidthRatio(); // Width ratio of diameters

    drawRadius (c, C1, -r, 0, , w, 0); // Line to be bisected drawCircle (c, O1, -r+d, 0, d); // Bisecting circle drawCircle (c, O2, r-d, 0, d); // Bisecting circle

    drawCross (c, O1, -r+d, 0); // Cross at centre of left circle drawPoint (c, O1, -r+d, 0, r*w); // Centre of left bisecting circle

    drawCross (c, O2, r-d, 0); // Cross at centre of right circle drawPoint (c, O2, r-d, 0, r*w); // Centre of right bisecting circle } String title() {return "Bisect a line";} float radiusWidthRatio() {return super.radiusWidthRatio()/2f;} // Make radii thinner }

    //------------------------------------------------------------------------------// Equilateral triangle//------------------------------------------------------------------------------

    class EquilateralTriangle extends Draw // Equilateral triangle {final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3;

    EquilateralTriangle(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas; final float r = radius, d = 1 * r, // Radius, diameter, animated diameter a = 60, x = d / 2, y = yPolar(d, a), // Angle, apex x, apex y w = radiusWidthRatio(), = r * w; // Width ratio of diameters

  • c.translate(0, r/2);

    drawPoint (c, O1, -x, 0, d); // Left side drawPoint (c, O2, x, 0, d); // Right side drawPoint (c, O3, 0, -y, d); // Top

    drawCircle1 (c, O1, -x, 0, d); // Left side drawCircle1 (c, O2, x, 0, d); // Right side drawCircle1 (c, O3, 0, -y, d); // Top

    drawCircle2 (c, O1, -x, 0, d); // Left side drawCircle2 (c, O2, x, 0, d); // Right side drawCircle2 (c, O3, 0, -y, d); // Top

    drawRadius1 (c, C1, -x, 0, d, w, 0); // Base drawRadius1 (c, C1, -x, 0, d, w, 360-a); // Side - left, upper drawRadius1 (c, C1, x, 0, d, w, 180+a); // Side - right, upper

    drawRadius2 (c, C1, -x, 0, d, w, 0); // Base drawRadius2 (c, C1, -x, 0, d, w, 360-a); // Side - left, upper drawRadius2 (c, C1, x, 0, d, w, 180+a); // Side - right, upper } String title() {return "Equilateral triangle";} float radiusWidthRatio() {return super.radiusWidthRatio()/2f;} // Make radii thinner }

    //------------------------------------------------------------------------------// Kite//------------------------------------------------------------------------------

    class Kite extends Draw // Kite {final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3; final Pulse pulse = new Pulse(); // Flip flop once per animation cycle Kite(Activity Activity) {super(Activity);} // Construct

    private float[]angle = new float[]{20, 60}; // On axis half angles float angle(final int i) // Angle to select {if (step() % 3 == 0 && pulse.pulse()) // Generate new angle

  • {//angle[i] = 30+random.nextFloat()*60; } return angle[i]; }

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas; final float a = angle(0), = angle(1), // On axis half angles generated at the start of each animation r = radius, = r / 3, // Radius, angle radius, vertical height in radii D = r / yPolar(1, a), = r / yPolar(1, ), // Scale factor for each side to make height same X = xPolar(D, a), Y = yPolar(D, a), // Size limits left = xPolar , ), = yPolar , ), ( ( ( ( // Size limits right s = M(M(X / cx, Y / cy), M / cx, / cy)), ( ( // Scale factor to make sure element is visible x = -X/s, y = Y/s, d = d(x, y), // Left isosceles triangle dimensions scaled to fit = /s, = /s, = d , ), ( ( // Right isosceles triangle dimensions scaled to fit = - +x)/2, = (y )/2, ( -( -// Redistribute free space w = radiusWidthRatio()/2, // Width ratio of left radii = d * w; / /// Width ratio of right radii to keep them the same dimensions as the ones on the left

    if (false &&step() % 3 == 1) // Move to a better position at which to observe the result {final float f = fractionSin(); c.translate(-f , -f ); * * c.scale (1+f, 1+f, cx, cy); }

    // drawAngle (c, C1, 0, 0, , 360-a, 359.99f); // Angle to be bisected// drawRadius (c, C1, 0, 0, d, w, 360-a); // Radius - upper side of angle// drawRadius (c, C1, 0, 0, d, w, 0); // Radius - lower side of angle

    drawCircle (c, O1, +x, , d); // Left circle drawCircle (c, O1, , , ); + + // Right circle

    drawRadius (c, C1, +x, 0, d, w, 360- a); // Left upper radius drawRadius (c, C1, +x, 0, d, w, a); // Left lower radius drawCross (c, C1, +0, 0, r/4); // Cross at centre

    drawRadius (c, C1, , 0, , , 180 ); + ++ +

  • // Right upper radius drawRadius (c, C1, , 0, , , 180 ); + -+ -// Right lower radius

    // drawRadius (c, C1, 0, 0, r, , 180); // Radius - extension of lower side to form diameter// drawRadius (c, O3, -x, -y, , , 360 ); - -// Lower line along which bisecting circle rolls// drawRadius (c, O3, -r, 0, , , 360 ); - -// Upper line along which the transcribing circle rolls// drawAngle (c, C2, -x, -y, , 360-a, 360 ); - -// Half of angle to be bisected

    // drawCircle (c, C2, , , ); // Circle rolls forward to draw bisector // drawCross (c, C2, , , /4, 90 ); - -// Cross at centre of transcribing circle// drawRadius (c, C2, , , , w, 90 ); - -// Lower radius at 90 to bisector// drawCross (c, O2, , , /8, 90 , , 90 ); - - - -// Cross at lower edge of transcribing circle// drawRadius (c, C2, , , , w, 270 ); - -// Upper radius at 90 to bisector// drawCross (c, O2, , , /8, 270 , , 270 ); - - - -// Cross at upper edge of transcribing circle

    // drawRadius (c, C3, 0, 0, , w, 360 ); - -// Bisector between centres of each circle } String title() {return "kite";} float radiusWidthRatio() {return super.radiusWidthRatio()/2f;} // Make radii thinner }

    //------------------------------------------------------------------------------// Rhombus//------------------------------------------------------------------------------

    class Rhombus extends Draw // Rhombus {final ColourSet C1 = ColourSet1, C2 = ColourSet2, C3 = ColourSet3, O1 = ColourSetO1, O2 = ColourSetO2, O3 = ColourSetO3;

    Rhombus(Activity Activity) {super(Activity);} // Construct

    void drawAnimation(Canvas Canvas) // Draw animation {final Canvas c = Canvas; final float r = radius, d = 1 * r, // Radius, diameter, animated diameter a = 60, x = d / 2, y = yPolar(d, a), // Angle, apex x, apex y w = radiusWidthRatio(); // Width ratio of diameters

    drawCircle (c, O1, -x, 0, d); // Left side drawCircle (c, O2, x, 0, d); // Right side drawCircle (c, O2, 0, y, d); // Top

  • drawCircle (c, O3, 0, -y, d); // Bottom

    drawRadius (c, C1, -x, 0, d, w, 0); // Base drawRadius (c, O1, -x, 0, d, w, 360-a); // Side - left, upper drawRadius (c, O1, -x, 0, d, w, a); // Side - left, lower drawRadius (c, O2, x, 0, d, w, 180+a); // Side - right, upper drawRadius (c, O3, x, 0, d, w, 180-a); // Side - right, lower } String title() {return "Rhombus";} float radiusWidthRatio() {return super.radiusWidthRatio()/2f;} // Make radii thinner }

    //------------------------------------------------------------------------------// Two triangles with matching length sides are congruent//------------------------------------------------------------------------------

    //------------------------------------------------------------------------------// Construct equilateral polygons and stars,3,4,5,6,8,9,10,12,15,16//--------------------------------------------------------------