Algorithms_in_C  1.0.0
Set of algorithms implemented in C.
spirograph.c File Reference

Implementation of Spirograph More...

#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
Include dependency graph for spirograph.c:

Macros

#define _USE_MATH_DEFINES
 required for MSVC compiler
 

Functions

void spirograph (double *x, double *y, double l, double k, size_t N, double rot)
 Generate spirograph curve into arrays x and y such that the i^th point in 2D is represented by (x[i],y[i]). More...
 
void test (void)
 Test function to save resulting points to a CSV file.
 
int main (int argc, char **argv)
 Main function.
 

Detailed Description

Implementation of Spirograph

Author
Krishna Vedala

Implementation of the program is based on the geometry shown in the figure below:

Spirograph geometry from Wikipedia

Function Documentation

◆ spirograph()

void spirograph ( double *  x,
double *  y,
double  l,
double  k,
size_t  N,
double  rot 
)

Generate spirograph curve into arrays x and y such that the i^th point in 2D is represented by (x[i],y[i]).

The generating function is given by:

\begin{eqnarray*} x &=& R\left[ (1-k) \cos (t) + l\cdot k\cdot\cos \left(\frac{1-k}{k}t\right) \right]\\ y &=& R\left[ (1-k) \sin (t) - l\cdot k\cdot\sin \left(\frac{1-k}{k}t\right) \right] \end{eqnarray*}

where

  • \(R\) is the scaling parameter that we will consider \(=1\)
  • \(l=\frac{\rho}{r}\) is the relative distance of marker from the centre of inner circle and \(0\le l\le1\)
  • \(\rho\) is physical distance of marker from centre of inner circle
  • \(r\) is the radius of inner circle
  • \(k=\frac{r}{R}\) is the ratio of radius of inner circle to outer circle and \(0<k<1\)
  • \(R\) is the radius of outer circle
  • \(t\) is the angle of rotation of the point i.e., represents the time parameter

Since we are considering ratios, the actual values of \(r\) and \(R\) are immaterial.

Parameters
[out]xoutput array containing absicca of points (must be pre-allocated)
[out]youtput array containing ordinates of points (must be pre-allocated)
lthe relative distance of marker from the centre of inner circle and \(0\le l\le1\)
kthe ratio of radius of inner circle to outer circle and \(0<k<1\)
Nnumber of sample points along the trajectory (higher = better resolution but consumes more time and memory)
num_rotthe number of rotations to perform (can be fractional value)
58 {
59  double dt = rot * 2.f * M_PI / N;
60  double t = 0.f, R = 1.f;
61  const double k1 = 1.f - k;
62 
63  for (size_t dk = 0; dk < N; dk++, t += dt)
64  {
65  x[dk] = R * (k1 * cos(t) + l * k * cos(k1 * t / k));
66  y[dk] = R * (k1 * sin(t) - l * k * sin(k1 * t / k));
67  }
68 }