Lecture Notes 02

Author

Anand Chitipothu

Published

July 29, 2024

Warning

This lecture notes is still work in progress. Not all programs covered in the class are added here yet. The remaining ones will be added soon!

Introduction

Why should you learn programming?

A powerful programming language is more than just a means for instructing a computer to perform tasks. The language also serves as a framework within which we organize our ideas about processes.

– Structure and Interpretation of Computer Programs

Every powerful language has three mechanisms for accomplishing this:

  • primitive expressions, which represent the simplest entities the language is concerned with,
  • means of combination, by which compound elements are built from simpler ones, and
  • means of abstraction, by which compound elements can be named and manipulated as units.

– Structure and Interpretation of Computer Programs

Diving in

A Circle

#include <sketch.h>

int main()
{
    // draw a circle with center as (0, 0) and radius 100
    draw_circle(0, 0, 100);

    // save all the shapes draws to lesson2.svg
    save_sketch("lesson2.svg");
}

Two Circles

How do we draw two circles instead of just one?

#include <sketch.h>

int main()
{
    draw_circle(-100, 0, 100);
    draw_circle(100, 0, 100);

    save_sketch("lesson2.svg");
}

Concentric Circles

How about drawing two concentic circles?

#include <sketch.h>

int main()
{
    draw_circle(0, 0, 200);
    draw_circle(0, 0, 100);

    save_sketch("lesson2.svg");
}

What if we want three circles?

#include <sketch.h>

int main()
{
    float r = 150;

    draw_circle(0, 0, r / 3);
    draw_circle(0, 0, 2 * r / 3);
    draw_circle(0, 0, r);

    save_sketch("lesson2.svg");
}

Candle Lights

#include <sketch.h>

void bottle_circle(float bx, float by, float r)
{
    float cx = bx;
    float cy = by + r;

    draw_circle(cx, cy, r);
}

void draw_candle_light(float x, float y, float r)
{
    bottle_circle(x, y, r / 3);
    bottle_circle(x, y, 2 * r / 3);
    bottle_circle(x, y, r);
}

int main()
{
    draw_candle_light(-100, 0, 100);
    draw_candle_light(100, 0, 100);

    save_sketch("lesson2.svg");
}

Concentric Circles

#include <sketch.h>

void concentric_circles(float x, float y, float r, float n)
{
    for (int i = 1; i <= n; i++)
    {
        draw_circle(x, y, i * r / n);
    }
}

int main()
{
    concentric_circles(0, 0, 250, 10);

    save_sketch("lesson2.svg");
}

Random Concentric Circles

#include <sketch.h>
#include <stdlib.h>
#include <time.h>

void random_concentric_circles(float x, float y, int r, float n)
{
    for (int i = 1; i <= n; i++)
    {
        // pick a random number from 1 to r
        float r1 = 1 + rand() % r;

        draw_circle(x, y, r1);
    }
}

int main()
{
    // initialize the random number generator
    srand(time(NULL));

    random_concentric_circles(0, 0, 250, 10);

    save_sketch("lesson2.svg");
}

Try running this program again and you’ll get completely different circles!

String Art

Let’s add a bit more complexity. How do you find N points equidistant on a circle?

Yes, trigonometry!

#include <sketch.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>

#define N 36

float X[N];
float Y[N];

// initialze the X and Y for N points
// on circle of radius r
void make_circle(float r)
{
    for (int i = 0; i < N; i++)
    {
        float theta = 2 * M_PI / N * i;
        X[i] = r * cos(theta);
        Y[i] = r * sin(theta);
        draw_circle(X[i], Y[i], 2);
    }
}

int main()
{
    make_circle(250);

    save_sketch("lesson2.svg");
}

Connecting Points

What if we connect some points?

#include <sketch.h>
#include <math.h>

#define N 36

float X[N];
float Y[N];

// initialze the X and Y for N points
// on circle of radius r
void make_circle(float r)
{
    for (int i = 0; i < N; i++)
    {
        float theta = 2 * M_PI / N * i;
        X[i] = r * cos(theta);
        Y[i] = r * sin(theta);
        draw_circle(X[i], Y[i], 2);
    }
}

void connect(int i, int j)
{
    i = i % N;
    j = j % N;
    draw_line(X[i], Y[i], X[j], Y[j]);
}

int main()
{
    make_circle(250);

    connect(0, 4);
    connect(1, 5);

    save_sketch("lesson2.svg");
}

Connecting All Points

Let’s go one step further and connect all the points.

#include <sketch.h>
#include <math.h>

#define N 36

float X[N];
float Y[N];

// initialze the X and Y for N points
// on circle of radius r
void make_circle(float r)
{
    for (int i = 0; i < N; i++)
    {
        float theta = 2 * M_PI / N * i;
        X[i] = r * cos(theta);
        Y[i] = r * sin(theta);
        draw_circle(X[i], Y[i], 2);
    }
}

void connect(int i, int j)
{
    i = i % N;
    j = j % N;
    draw_line(X[i], Y[i], X[j], Y[j]);
}

void connect_all(int delta)
{
    for (int i = 0; i < N; i++)
    {
        connect(i, i + delta);
    }
}

int main()
{
    make_circle(250);

    connect_all(10);

    save_sketch("lesson2.svg");
}

A Pattern

We could use connect_all multiple times to generate very interesting pattern.

#include <sketch.h>
#include <math.h>

#define N 36

float X[N];
float Y[N];

// initialze the X and Y for N points
// on circle of radius r
void make_circle(float r)
{
    for (int i = 0; i < N; i++)
    {
        float theta = 2 * M_PI / N * i;
        X[i] = r * cos(theta);
        Y[i] = r * sin(theta);
        // draw_circle(X[i], Y[i], 2);
    }
}

void connect(int i, int j)
{
    i = i % N;
    j = j % N;
    draw_line(X[i], Y[i], X[j], Y[j]);
}

void connect_all(int delta)
{
    for (int i = 0; i < N; i++)
    {
        connect(i, i + delta);
    }
}

int main()
{
    make_circle(250);

    connect_all(16);
    connect_all(12);
    connect_all(7);

    save_sketch("lesson2.svg");
}

Cardoid

#include <sketch.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>

#define N 72

float X[N];
float Y[N];

// initialze the X and Y for N points
// on circle of radius r
void make_circle(float r)
{
    for (int i = 0; i < N; i++)
    {
        float theta = 2 * M_PI / N * i;
        X[i] = r * cos(theta);
        Y[i] = r * sin(theta);
        // draw_circle(X[i], Y[i], 2);
    }
}

void connect(int i, int j)
{
    i = i % N;
    j = j % N;
    draw_line(X[i], Y[i], X[j], Y[j]);
}

void connect_all(int delta)
{
    for (int i = 0; i < N; i++)
    {
        connect(i, i + delta);
    }
}

int main()
{
    // initialize the random number generator
    srand(time(NULL));

    make_circle(250);

    for (int i = 0; i < N; i++)
    {
        connect(i, 2 * i);
    }

    save_sketch("lesson2.svg");
}

Final Touch

#include <sketch.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>

#define N 720

float X[N];
float Y[N];

// initialze the X and Y for N points
// on circle of radius r
void make_circle(float r)
{
    for (int i = 0; i < N; i++)
    {
        float theta = 2 * M_PI / N * i;
        X[i] = r * cos(theta);
        Y[i] = r * sin(theta);
        // draw_circle(X[i], Y[i], 2);
    }
}

void connect(int i, int j)
{
    i = i % N;
    j = j % N;
    draw_line(X[i], Y[i], X[j], Y[j]);
}

void connect_all(int delta)
{
    for (int i = 0; i < N; i++)
    {
        connect(i, i + delta);
    }
}

int main()
{
    // initialize the random number generator
    srand(time(NULL));

    set_stroke_width(0.5);
    set_stroke("#44444480");

    make_circle(250);

    // connect_all(16);
    // connect_all(12);
    // connect_all(7);

    for (int i = 0; i < N; i++)
    {
        int d = N / 6;

        connect(i, (i * i) % d);
    }

    save_sketch("lesson2.svg");
}

References