Simulation of Spirograph Toy
//---------------------------------------------------------
// Spirograph
//
// Simulate the spirograph toy.
//
// D. Searls
// Asbury College
// Feb 2010
//---------------------------------------------------------
#include<graphics.h>
#include<iostream>
#include<cmath>
#include "worldType.h"
using namespace std;
const int MAXSIZE = 10;
const double PI = 3.14159265358979;
//---------------------------------------------------------
// GCD
//
// Return the greatest common divisor of i and j.
//
// In parameters: i, j
//---------------------------------------------------------
int GCD(int i, int j)
{
if (j == 0)
{
return i;
}
else
{
return GCD(j, i % j);
}
}
//---------------------------------------------------------
// drawEpitrochoid
//
// Draw the specified epitrochoid in the specifed world.
//
// In parameter: w, color, radius1, radius2, radius3
//---------------------------------------------------------
void drawEpitrochoid(worldType w, int color, int radius1, int radius2, int radius3)
{
double r1 = double(radius1);
double r2 = double(radius2);
double r3 = double(radius3);
int oldColor = getcolor();
setcolor(color);
int n = 360 * radius2 / GCD(abs(radius1), abs(radius2));
double degree = PI / 180.0;
double theta, phi;
w.moveTo(r1 + r2 - r3, 0.0);
for (int i = 0; i < n - 1; i++)
{
theta = double(i) * degree;
phi = (r1 + r2) / r2 * theta;
w.lineTo((r1 + r2) * cos(theta) - r3 * cos(phi),
(r1 + r2) * sin(theta) - r3 * sin(phi));
}
w.lineTo(r1 + r2 - r3, 0.0);
setcolor(oldColor);
}
//---------------------------------------------------------
// drawHypotrochoid
//
// Draw the specified hypotrochoid in the specifed world.
//
// In parameter: w, color, radius1, radius2, radius3
//---------------------------------------------------------
void drawHypotrochoid(worldType w, int color, int radius1, int radius2, int radius3)
{
double r1 = double(radius1);
double r2 = double(radius2);
double r3 = double(radius3);
int oldColor = getcolor();
setcolor(color);
int n = 360 * radius2 / GCD(abs(radius1), abs(radius2));
double degree = PI / 180.0;
double theta, phi;
w.moveTo(r1 - r2 + r3, 0.0);
for (int i = 0; i < n - 1; i++)
{
theta = double(i) * degree;
phi = (r1 - r2) / r2 * theta;
w.lineTo((r1 - r2) * cos(theta) + r3 * cos(phi),
(r1 - r2) * sin(theta) - r3 * sin(phi));
}
w.lineTo(r1 - r2 + r3, 0.0);
setcolor(oldColor);
}
//*********************************************************
// M A I N D R I V E R
//*********************************************************
int main()
{
int size;
int r1, r2, r3;
if (getmaxwidth() > getmaxheight())
{
size = getmaxheight();
}
else
{
size = getmaxwidth();
}
size = size - 50;
worldType w(601, 601, 0,0,
-100.0, -100.0, 100.0, 100.0, "Spirograph");
cout << " SPIROGRAPH\n\n";
cout << "When asked to enter a radius or distance\n";
cout << "enter integer values.\n\n";
cout << "The world coordinates extend from -100 to\n";
cout << "100 in both directions.\n";
do
{
cout << "\nEnter radius of stationary circle (0 to exit): ";
cin >> r1;
if (r1 > 0)
{
cout << "Enter radius of rolling circle: ";
cin >> r2;
cout << "Enter distance from center to pen: ";
cin >> r3;
cleardevice();
drawEpitrochoid(w, LIGHTRED, r1, r2, r3);
drawHypotrochoid(w, LIGHTBLUE, r1, r2, r3);
}
}while (r1 > 0);
closegraph();
return 0;
}