Enjoyable Introduction to Programming using Drawings

by Dr. Jeyakesavan Veerasamy, CS faculty,

University of Texas at Dallas, USA.

 

Follow these steps to get the maximum value out of the workshop:

-      Review the tutorials provided by Khan Academy

-      Try to do the exercises on your own.

-      Review the solution videos to help you complete or to see how I completed them.

 

All the tutorials are under www.khanacademy.org/cs/programming:

 

Tutorials/Lessons

Exercises

Session 0: Core Programming Concepts - Sequence, selection and repetition are 3 pillars of programming! Flash/YouTube,PPT

/PDF

 

 

Session 1: Introduction

 

khanacademy.org/cs/programming/intro-to-programming: Watch these 2 tutorials.

 

khanacademy.org/cs/programming/drawing-basics: Watch these 2 tutorials. Challenges are simple exercises for you to complete along the way - hint is displayed at every step – complete them too.

 

Go to main page khanacademy.org/cs and click on

Or click on this direct link to start:

khanacademy.org/cs/new

 

1. Now, let your creativity run wild and create interesting drawings using a series of rect(), ellipse() and line() functions!

 

Feel free to use these drawings as starters to kick-start your creativity! No need to draw exactly these…

 

 

  

 

2. Click here to learn to draw a triangle too. Here are a few interesting drawings using triangles:

 

 

 

3. Now, draw a nice house using all the functions we have covered so far.

 

khanacademy.org/cs/programming/coloring: Complete the tutorials and challenges to learn about colors. Final item is a project and it is quite open-ended – keep it simple and enjoy the experience!

 

Welcome to the colorful world! You can go back and add colors to the drawings we did earlier!

 

1. Random numbers play an important role in gaming and security. For example, random(0, 400) will generate a random number between 0 and 400. Look at the following one line of code:

ellipse(200, 200, random(0,400), random(0,400));

 

As you can see, it is ok to use the result of a function as a parameter in another function. OK, what will this line do? Think about it for a minute before testing it out! Then, enhance it to draw a random ellipse in a random color at a random location (it is ok if it is sliced off).

 

2. By default, all enclosed shapes (ellipse, rectange, triangle, etc.) are filled with white color. There is another in-built function noFill() that enables us to draw the shape without any fill. For example, here is triangle based drawing shown in the previous section, with noFill() at the top.

 

Note that noFill() will be effective until fill() is invoked again. Use your creativity and draw a picture of your own mixing noFill() and fill() along the way.

 

3. Redraw your house with colors! Submit this one as Week 1 assignment.

 

Session 2: Variables

 

khanacademy.org/cs/programming/variables:

 

 

We learned to draw random ellipses in the previous section. How to restrict to circles? See the power of variable!

 

noStroke();

fill(random(0,255),random(0,255), random(0,255));

var diameter = random(0,100);

ellipse(random(0,400), random(0,400), diameter, diameter);

 

Alternate way to draw the circle!

 

stroke(random(0,255),random(0,255), random(0,255));

strokeWeight(random(0,100));

point(random(0,400), random(0,400));

 

How will you draw a random square instead of ellipse? Note: Unlike ellipse(), x and y parameters in rect() indicate the top, left corner. So, you may need to make a few adjustments for proper display of Squares.

 

 

Now that we understand variables and we can write equations using them, we can reduce our mental computations! Here is one example:

 

var x1 = 200;

var y1 = 50;

var x2 = 50;

var y2 = 300;

var x3 = 350;

var y3 = 300;

 

triangle(x1, y1, x2, y2, x3, y3);

 

//adjust the values of few variables

y1 += 10;

x3 -= 9;

y3 -= 5;

triangle(x1, y1, x2, y2, x3, y3);

//copy & paste these 4 lines lots of times to get the following:

 

Now that we know how to add colors, make this drawing to look similar to this one using random colors:

We can also make fill() color a function of variables like

fill(y1*2, (350-x3) * 2, (y3-200) * 2);

to make the color change smoothly. How does this work?

Utilizing the power of variables & the beauty of colors, create your own artistic creation. We will use this as Week 2 assignment.

 

Session 3: Animation basics

 

khanacademy.org/cs/programming/animation-basics: Animation basics – exciting stuff!

 

Mouse Interaction tutorial seems messed up – use this one instead: mouseinteraction.swf

 

Take the code for “Exploding Sun”. In addition to making the sun bigger, let it rise slowly too. Then, reverse the size – start with a big sun and reduce the size as the sun rises to the sky.

 

Use the power of docs to learn about Math functions sin() and cos(). Instead of a ball moving left to right, move it around in circular fashion. Compute x and y position with the following equations:

var x = 100 * sin(angle);

var y = 100 * cos(angle);

 

In the project Crazy Painter, following discrepancy creates uneven distribution of colors: Each color component’s range is 0 to 255, while mouseX and mouseY goes from 0 to 399. Use an equation to map the mouse position to color better.

 

Enhance the project Crazy Painter by using Math expressions to change the colors. You can also utilize random() to add some spice J Here is an example:

fill(mouseX, random(100,200), mouseY/2);

 

You can also use a counter variable and increment it within draw() function and use it in fill(). That will enable you to change color over time!

 

Combine this counter based color change idea with ball moving in circular fashion. Use modulo operator to reset the color values if needed.

 

var counter;

counter++;

counter = counter % 256;

 

Use 3 different variables and increment bit differently for each one to get full range of colors! Submit this code as Week 3 assignment.

 

Session 4: Text & Strings, Functions

 

https://www.khanacademy.org/computing/cs/programming/text-basics:

 

 

https://www.khanacademy.org/computing/cs/programming/functions:


Following program was used to generate the image below using mouse:

 

var px, py;

 

var mousePressed = function() {

    px = mouseX;

    py = mouseY;

    stroke(random(0,255), random(0,255), random(0,255));

};

 

var mouseDragged = function() {

    line(px, py, mouseX, mouseY);

};

 

 

Modify the code to

-      draw circles,

-      ellipses using move events:

 

      

 

Use a function to a complex object (in other words, it should require a few lines code!) Utilize mouse related APIs to draw it at mouse location whenever mouse is clicked. Submit this as Assignment 4.

 

Session 5: Logic and if Statements

 

This version is bit slow compared to loops, but nice to see, right?

 

var sz = 50;

var limit = 400;

translate(200,200);

 

var draw = function() {

    ellipse(0,0,sz,sz);

    sz += 5;

    if (sz > limit) {

        sz = 50;

        limit -= 25;

    }

};

 

Same using squares:

var sz = 50;

var limit = 400;

translate(200,200);

 

var draw = function() {

    rect(-sz/2,-sz/2,sz,sz);

    sz += 5;

    if (sz > limit) {

        sz = 50;

        limit -= 25;

    }

};

 

 

 

 

We have covered random circles & ellipses earlier. How can we make the whole circle to appear inside the canvas area? In other words, we want to ensure that the circles are never cut off at the edges.

 

Idea is to push the circle in if it is too close to the boundaries. Realize the power of IF statements!

 

noStroke();

fill(random(0,255),random(0,255), random(0,255));

var dia = random(0,200);

var x = random(0,400);

var y = random(0,400);

var rad = dia / 2;

if (x < rad) {

    x = rad;

}

if (x > 400 - rad) {

    x = 400 - rad;

}                    

if (y < rad) {

    y = rad;

}

if (y > 400 - rad) {

    y = 400 - rad;

}

 

ellipse(x, y, dia, dia);

 

Extra: What are the code changes if you want to do the same for ellipses?

 

Alternate approach: Both Software Engineering perfectionists and Mathematicians make like the following one better! Why?

 

noStroke();

fill(random(0,255),random(0,255), random(0,255));

var dia = random(0,200);

var rad = dia / 2;

var x = random(rad,400-rad);

var y = random(rad,400-rad);

ellipse(x, y, dia, dia);

 

 

Combine the concepts you learned in the tutorial on “If Statements” and “Challenge: Bouncy Ball” to make the ball to move around within the viewable area bouncing off all 4 walls.

 

Make it more interesting by assigning a random speed and color for the ball when it bounces.

 

 

Enhance the code in “More Mouse Interaction” tutorial to make the ball move left-right when the mouse is not pressed, but the ball should move up-down when the mouse is pressed (use just one ball). Make the movements smooth – when the ball transitions between left-right and up-down, ball position should NOT change drastically.

 

 

Lesson covered drawing circle/ellipse within the canvas area – how will you make your square to appear within the canvas area? Let us go one step further –avoid the edges all-together – make the squares appear within the rectangular area of (10,10) to (390,390).

 

Extra: What if we want to do the same for any rectangle?

 

Make the expanding circles/squares start with a different color each time. Remove the border black lines too. Submit this one as Assignment 5.

 

  

 

 

Power of Creativity:

 

Here is the code to draw random colored circle wherever mouse is clicked or pressed and dragged.

 

var draw = function() {

    if (mouseIsPressed) {

        stroke(random(0,255), random(0,255), random(0,255));

        strokeWeight(random(0,50));

        point(mouseX, mouseY);

    }

};

 

 

Try to draw a human face or necklace or your favorite image :-)

Session 6: Loops

 

http://utd.edu/~veerasam/js/index_files/image056.jpg

 

Draw 10 random circles!

 

for(var i=0 ; i<10 ; i++) {

    stroke(random(0,255),random(0,255), random(0,255));

    strokeWeight(random(0,100));

    point(random(0,400), random(0,400));

}

 

Now, click near 10 and drag the mouse left or right. What happens?

 

 

Video: Waiter carrying the elliptical plates in a fancy way...

 

With random colors:

 

noStroke();

for (var i = 10; i > 0; i--) {

    fill(random(0,255),random(0,255), random(0,255));

    ellipse(200, 200, i * 20, i * 40);

    ellipse(200, 200, i * 40, i * 20);

}

 

With a color pattern:

 

noStroke();

for (var i = 10; i > 0; i--) {

    fill(i*25,50,(10-i)*25);

    ellipse(200, 200, i * 20, i * 40);

    ellipse(200, 200, i * 40, i * 20);

}

 

 

 

 

 

 

 

Now, try to draw 10 concentric randomly colored circles. What does “concentric” mean? Will you draw in the order of small to large circles, or other way around?

 

 

Extra: Define a variable n at the top and write the generic code to draw n concentric circles instead.

var n=10;

...

Change n by clicking near 10 and dragging mouse left or right. Does your code work properly? Can you make some code changes so that all the circles will appear properly for any value of n?

 

 

Adjust the color pattern covered in the lesson to use a loop of 20, then change the color pattern such that Green color appears in the middle as shown in the image.

 

Extra: Can you make it perfect Green in the middle?

 

 

With n specified at the top, how will you generate n x n equally distributed circles? Keep 50 as the default diameter size for circles, but reduce as needed to avoid overlapping with other circles.

 

Take it easy & draw just one line of n equally distributed circles first, then expand it to n x n circles. Submit this one as Assignment 6.

 

n = 3:                                      n = 5:

n = 10:

 

Extra: How to draw circles in diamond formation? Middle row should have n circles, adjacent rows should have (n-2) circles, their adjacent rows should have (n-4) circles, so on. Top and bottom rows should have only 1 or 2 circles in the middle.

 

Session 7: translate(), rotate() and scale() functions

 

Play time! Use these code segments individually to learn about the behavior of translate(), rotate() and scale() – replace A,B,C and D with various values and try to understand the results!

 

fill(255,0,0);

ellipse(100,100,50,50);

translate(A,B);

ellipse(100,100,50,50);

translate(C,D);

ellipse(100,100,50,50);

 

 

angleMode = "degrees";

fill(255,0,0);

translate(200,200);

ellipse(100,100,50,50);

rotate(A);

ellipse(100,100,50,50);

 

 

angleMode = "degrees";

fill(255,0,0);

translate(200,200);

ellipse(100,100,50,50);

scale(B, C);

ellipse(100,100,50,50);

 

Now, try to use rotate() and scale() together. Add for loop & random fill color, then adjust the angle – that will take you to artistic creations shown below!

 

Video: Drawing Bonus: Rotation!  www.khanacademy.org/cs/drawing-bonus-rotation/906448125

 

Warning: Sometimes, browsers’ default setting of degrees vs. radians is unpredictable. You may want to add a line

angleMode = "degrees";

to the top of your program if you want the angles to be specified in degrees. Also, you can use the following line to use radians instead (note: 360 degrees = 2 * PI radians):

angleMode = "radians";

This setting affects the behavior of rotate(), sin(), cos(), tan(), etc.

 

 

Another generation of shrinking squares!

 

noStroke();

translate(200,200);

 

var y = 200;

var dir = 1;

var len = 500;

var angle = 0;

var draw = function() {

    fill(random(0,255), random(0, 255), random(0,255));

    rotate(angle);

    rect(-len, -len, 2*len, 2*len);

    y -= dir;

    angle+= 5;

    len /= 1.1;

};

 

 

 

 

Endless distribution of playing cards! Card size gets smaller, then gets bigger, then smaller again, bigger again ...

 

strokeWeight(2);

translate(200,200);

 

var y = 200;

var dir = 1;

var len = 1;

var angle = 10;

var draw = function() {

    fill(random(0,255), random(0, 255), random(0,255));

    rotate(angle);

    rect(len, 0, y / 2, y);

    y -= dir;

    angle+= 10;

    if (y < 20) {

        dir = -1;

    }

    if (y > 200) {

        dir = 1;

    }

};

 

 

Extra: How about slow color change, instead of random colors?

 

Video: Artistic creations including rotating & shrinking squares/ellipses – change the angle within rotate() and see the wonders! translate() is used to move (0,0) to the center so that we can see all quadrants, as we do the rotations. scale() is used to change the size gradually ...

 

noStroke();

translate(200,200);

for (var i = 500; i > 0; i--) {

    fill(i * 7 % 256, i * 17 % 256, i * 13 % 256);

    rect(0,0,400,400);

    scale(0.99,0.99);

    rotate(5);

}

 

 

 

noStroke();

translate(200,200);

for (var i = 500; i > 0; i--) {

    fill(i * 7 % 256, i * 17 % 256, i * 13 % 256);

    rect(0,0,400,400);

    scale(0.99,0.99);

    rotate(30);

}

 

 

Discussion: You can see colors become bolder, but why they change suddenly?

 

noStroke();

translate(200,200);

for (var i = 0; i <16 ; i++) {

    fill(random(0,255), random(0,255), random(0,255));

    ellipse(50,100,50,200);

    rotate(23);

 

 

 

noStroke();

translate(200,200);

for (var i = 50; i > 0; i--) {

    fill(random(0,255),random(0,255), random(0,255));

    rect(-200,-200,400,400);

    scale(0.9,0.9);

    rotate(5);

}

 

 

noStroke();

translate(200,200);

for (var i = 500; i > 0; i--) {

    fill(sin(i*2)*128+128, sin(4*i)*128+128, sin(7*i)*128+128);

    rect(0,0,400,400);

    scale(0.99,0.99);

    rotate(16);

}

 

 

 

Discussion: Why color change is smooth for the previous one, bit more abrupt for the next one?

 

noStroke();

translate(200,200);

for (var i = 500; i > 0; i--) {

    fill(sin(i*5)*128+128, sin(12*i)*128+128, sin(17*i)*128+128);

    ellipse(200,200,400,400);

    scale(0.99,0.99);

    rotate(5);

}

 

 

noStroke();

translate(200,200);

for (var i = 1000; i > 0; i--) {

    fill(sin(i*2)*128+128, sin(4*i)*128+128, sin(6*i)*128+128);

    ellipse(200,200,100,400);

    scale(0.995,0.995);

    rotate(24);

}

 

noStroke();

translate(200,200);

for (var i = 500; i > 0; i--) {

    fill(random(0,255), random(0,255), random(0,255));

    ellipse(200,200,400,400);

    scale(0.93,0.93);

    rotate(63);

}

 

 

Here are a few other images:

 

  

 

Let your creativity run wild & make a few fancy artistic images of your own by making various changes to code segments in the lessons.

 

You have seen the examples using ellipses and rectangles. Try the same using triangles (rotations & scaling down).

Functions: Circle of rockets!

 

noStroke();

 

var drawRacket = function() {

    fill(255, 0, 102);

    triangle(150,0,200,-40,200,40);

    fill(0, 255, 9);

    rect(125,-25,50,50);

    fill(9, 0, 255);

    triangle(125,-25,125,25,100,0);

};

 

translate(200,200);

 

var n = 12;

for(var i=0; i<n ; i++) {   

        rotate(360/n);

        drawRacket();

}

 

 

Circle of cars - make them face each other as shown below. Hint: scale(-1,1) can make it reflect across y axis. Here is the start-up code to draw one car! Complete this exercise and submit it as Assignment 7.

 

Functions bring modularity to the programs and we can invoke them any # of times wherever we want.

 

var drawCar = function() {

    noStroke();

    // draw the car body

    fill(255, 0, 115);

    rect(90, 0, 100, 20);

    rect(105, -28, 70, 40);

   

    // draw the wheels

    fill(77, 66, 66);

    ellipse(115, 21, 24, 24);

    ellipse(165, 21, 24, 24);

};

 

translate(0,100);

drawCar();

 

Session 8: Recursion!

 

Recursion is an advanced concept in Computer Science. Beginners are welcome to skip this portion! You can always come back later to tackle whenever you want...

 

Growing squares at corners: functions with parameters & recursion

 

Recursive functions are unique – they invoke themselves in the body of the function. In the following code, drawSquare() is invoked 4 times within drawSquare() itself.

 

That sounds like a formula for trouble, right? If we are not careful, infinite recursion can occur & programs can get stuck or crash. We control the recursion depth.

 

noStroke();

 

var drawSquare = function(level, x, y, len) {

    fill(x, len, y);

    rect(x, y, len, len);

    if (level > 0) {

        drawSquare(level-1, x-len/2, y-len/2, len/2);

        drawSquare(level-1, x+len, y-len/2, len/2);

        drawSquare(level-1, x-len/2, y+len, len/2);

        drawSquare(level-1, x+len, y+len, len/2);

    }

};

 

drawSquare(8, 150, 150, 100);

 

 

Growing triangles at corners: functions with parameters & recursion

 

 

var drawTriangle = function(level, x1, y1, x2, y2, x3, y3) {

    fill(x1, y1, x2-y2);

    strokeWeight(level+1);

    triangle(x1, y1, x2, y2, x3, y3);

    if (level > 0) {

       drawTriangle(level-1, x1, y1, x1-(x2-x1)/2, y1-(y2-y1)/2, x1-(x3-x1)/2, y1-(y3-y1)/2);

       drawTriangle(level-1, x2, y2, x2-(x1-x2)/2, y2-(y1-y2)/2, x2-(x3-x2)/2, y2-(y3-y2)/2);

       drawTriangle(level-1, x3, y3, x3-(x1-x3)/2, y3-(y1-y3)/2, x3-(x2-x3)/2, y3-(y2-y3)/2);

    }

   

};

 

drawTriangle(5, 200, 125, 125, 250, 275, 250);

 

 

 

Growing circles at corners: functions with parameters & recursion

 

noStroke();

 

var drawCircle = function(level, x, y, len) {

    fill(128+127*sin(x*(level+1)), 128+127*cos(len*(level+1)), 128+127*sin(y*(level+1)));

    ellipse(x, y, len, len);

    if (level > 0) {

        drawCircle(level-1, x-len/2, y-len/2, len/2);

        drawCircle(level-1, x+len/2, y-len/2, len/2);

        drawCircle(level-1, x-len/2, y+len/2, len/2);

        drawCircle(level-1, x+len/2, y+len/2, len/2);

    }

};

 

drawCircle(3, 200, 200, 200);

 

 

Use the following image as guidance to draw Koch curve recursively. Then, use your creativity to build fancy images using Koch curves as components & submit it as Assignment 8.

http://aziarts.com/air/Resource%20Pics/fractals/Koch-curve.jpg

Slide show of wonderful images! You can replace the code in drawIteration() with any code that we have seen for various artistic creations...

 

noStroke();

 

var angle = 1;

 

var drawIteration = function() {

translate(200,200);

for (var i = 1000; i > 0; i--) {

    fill(sin(i*2)*128+128, sin(4*i)*128+128, sin(6*i)*128+128);

    ellipse(200,200,100,400);

    scale(0.995,0.995);

    rotate(angle);

}

};

 

var counter = 0;

var draw = function() {

    counter++;

    if (counter > 25) {

        counter = 0;

        background(0, 0, 0);

        angle++;

        resetMatrix();

        drawIteration();

    }

};

 

Converting for loop to use draw():

 

stroke(random(0,255),random(0,255), random(0,255));

translate(50,100);

for(var i=0 ; i<100 ; i++) {

    line(0,0,300,0);

    translate(300,0);

    rotate(121);

}

 

can be re-written with draw() function. To avoid endless drawings, let us use mouseIsPressed flag (you need to press the mouse in the canvas area to draw) – this enables us to stop the drawing at any time! Since the drawing matrix is reset every time before invoking draw(), I threw in pushMatrix() just to try – that made it work properly!
 

translate(50,100);

stroke(random(0,255),random(0,255), random(0,255));

var draw = function() {

    if (mouseIsPressed) {

        line(0,0,300,0);

        translate(300,0);

        rotate(121);

        pushMatrix();

    }

};

 

Discussion: why rotate(121) degrees?

 

Hypnoswirl: http://www.khanacademy.org/cs/hypnoswirl/826002294

 

Make the necessary changes to make your drawing close to each one of these.

 

Paddle ball: http://www.khanacademy.org/cs/paddle-ball/830543654

 

 

Make the ball pick-up speed every time when it hits the paddle.

 

Another option is to select a random speed within a range when the ball hits the paddle and bounces.

 

What is a game without the score? Define a variable score and come up with a meaningful mechanism to increment it & reset it, then use the following code add the score in the bottom.

 

rect(100,360,200,40);

textSize(40);

fill(0,0,0);

text(score,150,395);

 

 

Session 9: Arrays

 

 

 

Based on the knowledge you gained from the tutorials, write a program to output Texas Lotto numbers. You need to output 6 numbers - each number should be between 1 and 50 and the numbers should not be repeated. Submit this one as Assignment 9.

Session 9: Objects

 

 

Browse and find your favorite game/program in Khan Academy and make a few modifications (write a short description about your changes as comments at the top of the program) and submit it as Assignment 10.

 

Few more games/programs:

 

https://www.khanacademy.org/cs/disco-ball/5654816797229056
https://www.khanacademy.org/cs/basketball-with-gravity/4894623197036544
https://www.khanacademy.org/cs/eq/6687018093903872
https://www.khanacademy.org/cs/paddleball-with-difficulty/6020289345880064
https://www.khanacademy.org/cs/burn/6013107736936448
https://www.khanacademy.org/cs/slot-machine/6547903560024064
https://www.khanacademy.org/cs/day-to-night-and-back-on-mouse-click/6236512185745408

 

Additional resources:

 

·         Khan Academy JavaScript documentation: www.khanacademy.org/cs/docs

·         Processing.js documentation: processingjs.org/reference

·         Sketchpad CC IDE: sketchpad.cc

·         OpenProcessing IDE: www.openprocessing.org/sketch/create

·         Processing examples: processing.org/examples