Virtual hands-on workshop : “Enjoyable Introduction to Programming using  Drawings”

by Dr. Jeyakesavan Veerasamy, CS faculty,

University of Texas at Dallas, USA.

 

While these materials have been targeted for workshops, they can certainly be used for self-paced learning from your home as well. Just that it can be more enjoyable experience if you have at least a partner to discuss and exchange ideas! Some background in programming concepts will enable you to enjoy the material – so I recommend you to complete Alice workshop first.

 

Start the workshop with one of the shows in following directory – click on any showX.html (press F11 and go full-screen for the full effect!): http://www.utdallas.edu/~jeyv/KAJS/shows

All with just ~20 lines of code in Processing.js that contain a few simple math equations! Math is beautiful :-) You will understand the code behind these images in this workshop, then you can write your own code & generate your own dazzling images!!

 

Description

Materials/Images

KhanAcademy-JavaScript installation and lab setup – There is no software to download and install, since JavaScript is interpreted by the browser. Mozilla Firefox is the officially “tested” browser – Google Chrome may work too, but it is not fully tested for the examples given below. We need Internet connection to access Khan Academy site just to get started, then we can work locally as long as you don’t click on Khan Academy examples.

Why does it make sense to go through this Drawings workshop? (Why not learn C/C++/Java directly?)

PPT/PDF

Welcome to Drawings workshop! Here are a few suggestions to get the maximum value from this workshop.

We will cycle through 3 modes for each topic/example: Watching, Doing it individually, helping each other to complete and work on something extra.

You can use www.online-stopwatch.com to make sure that the workshop is progressing in timely manner.

Core programming concepts – Sequence, selection and repetition are 3 pillars of programming!

Flash/YouTube, PPT/PDF

Introduction to KhanAcademy-JavaScript environmentwww.khanacademy.org/cs - Visual Programming – free-form typing – you can see the output immediately or with one-click.

Fun with examples: Click on All Programs or click here www.khanacademy.org/cs/browse/all-programs to go there directly. Scroll down and click on a few interest ones and have fun! After completing this workshop, you can generate similar or even better images!

Goto https://www.khanacademy.org/cs/programming:

Review all the tutorials listed under first 2 headings:

Intro to programming

Drawing basics

 

Assignment 1: Draw a nice house!

I decided NOT to give a sample house and derail your imagination! :-)

Documentation: Click on Documentation or click here www.khanacademy.org/cs/docs  & processingjs.org/reference. Each API comes with a sample usage too.

Goto https://www.khanacademy.org/cs/programming:

Review all the tutorials listed under

Coloring

 

Video: Draw a ellipse with random size & random color!

Documentation: random()

 

noStroke();

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

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

 

You can comment out individual lines with // and multiple lines with /* ... */

Also, what happens if these lines are out of order? Try it!

 

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));

 

Flash/YouTube

 

 

Assignment 2: Add a random square! Unlike ellipse(), x and y parameters in rect() indicate the top, left corner.

Video: make the circle appear fully 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);

Flash/YouTube

Assignment 3: Make your square to appear within the canvas area too – let us go one step further – let us 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?

For loops: Video: 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?

Flash/YouTube

Assignment 4: 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?

 

 

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);

}

 

Assignment 5: Adjust the color pattern 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?

Assignment 6: 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.

 

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

n = 3:                                                      n = 5:

n = 10:

Play time! Use these code segments indvidually 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.

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);

}

 

       

 

Assignment 7: Rotating and shrinking triangles – you have seen the examples using ellipses and rectangles. Try the same using triangles.

Flash/YouTube

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();

}

 

Discussion: How will you write this code if we cannot define a new function?

Assignment 8: Circle of cars - make them face each other: scale(-1,1) can make it reflect across y axis. Here is the start-up code to draw one car!

 

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();

 

Discussion: How will you write this code if we cannot define a new function?

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);

   

Special function: draw() – KAJS environment invokes draw() repeatedly & automatically forever.

 

Tutorial: Animation www.khanacademy.org/cs/intro-to-animation/830742281

 

Assignment 9: Make the car go back and forth. Here is the start-up code:

 

var drawCar = function(x, y) {

    noStroke();

    // draw the car body

    fill(255, 0, 115);

    rect(x, y, 100, 20);

    rect(x + 15, y-22, 70, 40);

   

    // draw the wheels

    fill(77, 66, 66);

    ellipse(x + 25, y+21, 24, 24);

    ellipse(x + 75, y+21, 24, 24);

};

 

var x = 10;

var draw = function() {

    drawCar(x, 200);

};

 

 

Tutorial: IF statements & animation: www.khanacademy.org/cs/if-statements/836708402

 

Assignment 10: Make the ball bounce around all 4 walls. Also, change color and speed with each bounce. Here is the start-up code:

 

// position of the ball

var x = 50;

// how far the ball moves every time

var speed = 3;

 

var draw = function() {

    background(202, 255, 97);

   

    fill(66, 66, 66);

    ellipse(x, 200, 50, 50);

 

    // move the ball

    x = x + speed;

};

 

Extra: introduce random speed when ball bounces off the walls, also change color too!

 

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;

    }

};

  

Assignment 11: make the expanding circles/squares start with a different color each time. Remove the border black lines too.

 

 

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?

Magic pen:

mouseX and mouseY are global variables that track the position of the mouse. Come up with a mechanism for the brush color to change slowly over time.

 

Power of Creativity:

mouseX and mouseY are global variables that track the position of the mouse. 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);

    }

};

 

Open-ended Assignment 12: Try to draw a human face or necklace or your favorite one :-) Now, put your thinking cap ON, close your eyes, let your creativity run wild and think for a few minutes about what you can do with a magical brush & build something that is awesome!

Play with sin() wave: Keep track of the total angle is another approach to get around “drawing matrix reset” issue associated with draw().

 

translate(200,200);

var angle = 0;

var m = 4;

var draw = function() {

        rotate(angle);  

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

        line(0,0,75+75*sin(m*angle),0);

        angle+= 0.5;

};

 

Does the output make sense? Change the multiplication factor m to some other value and see what happens.

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?

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;

};

 

 

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

 

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

  

Effect of circles expanding over time and random colors

 

strokeWeight(2);

translate(200,200);

point(0,0);

 

var sz = 1;

var len = 1;

var angle = 10;

var draw = function() {

    rotate(angle);

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

    ellipse(len, 0, sz, sz);

    angle+=20;

    len++;

    sz += 1;

};

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

 

Assignment 14: 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 incremenet 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);

Pebbles going all around:

 

strokeWeight(2);

translate(200,200);

point(0,0);

 

var sz = 1;

var len = 10;

var angle = 10;

var draw = function() {

    rotate(angle*180/PI);

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

    ellipse(len, 0, sz % 10 + 10, sz % 10 + 5);

    angle++;

    len++;

    sz += 1;

};

 

Following variation shows endless collection of coins! Use strokeWeight(2) instead of noStroke() to see another interesting effect.

 

translate(200,200);

 

var sz = 1;

 

noStroke();

 

var drawPebbles = function(x) {

 

    var len = 10;

    rotate(x);

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

        rotate(1);

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

        ellipse(len, 0, sz % 10 + 10, sz % 10 + 5);

        len++;

        sz += 1;

    }

};

 

var x = 1;

var draw = function() {

    x++;

    drawPebbles(x);

};

 

 

Arrays:

Multiple balls bouncing off all 4 walls. Let us use different color for each ball. That means, we need to remember the colors. That is where arrays come in.

 

Here is sample code to use arrays – it generates and stores 10 random colors, then randomly selects one color from that list.

 

var colors = [];

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

 colors.push(color(random(0,255),random(0,255), random(0,255)));

}

 

fill(colors[random(0,10)]);

 

Extra: For more complexity, balls can bounce off each other too! But which direction each ball should go?

 

 

Assignment 15: Generate Texas Lotto numbers – we need to generate 6 unique numbers between 1 and 50.

 

You can use the following code to output the values:

textSize(40);

text(value, x, y);

 

Does your program scale up easily if we want to generate 20 unique numbers between 1 and 1000. That is why, we like to write the code as generic as possible – so that future modifications/expansions will be as easy as possible.

 

Assignment 16: Paddle ball game using 2 balls.

 

Assignment 17: How long can you keep the balls in the air? Press on each air-blower to push the ball up! Game ends whenever any ball touches the air-blower.

 

If possible, do realistic ball movements - change the gravity settings and see the effect!

 

Assignment 18: “Hit-the-heads” game: Images randomly replace circles which are arranged in matrix format. Score should reflect the user’s response speed, negative points for clicking on circles.

 

Read the documentation on

image(myImage, x, y);

www.khanacademy.org/cs/imageimage-x-y/937672662

 

Assignment 19: Implement the memory game.

 

Assignment 20: Implement Connect4 game.

 

 

 

 

 

Additional Topics

 

Item

Description

Material

Duration

A1

Running the JavaScript programs in full screen:

http://www.utdallas.edu/~jeyv/KAJS/shows

 

 

 

 

 

 

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

 

A few advanced examples (mostly Recursion):

 

var depth = 4;

var length = 200;

var factors = [1/3, 1/3, 1/3, 1/3, 1/3];

var turns = [-90, 90, 90, -90, 0];

var copies = 4;

var angle = 90;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200-length/2, 200-length/2);

 

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

  fractal(depth,length);

  rotate(angle); 

}

 

rotate(90);

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

  fractal(depth,length);

  rotate(-angle); 

}

 

Koch Curve & Snowflake (JavaScript)

 

https://www.khanacademy.org/cs/koch-curve-using-arrays/5909184489979904

 

var depth = 5;

var length = 325;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var copies = 3;

var angle = 120;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        //line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200-length/2, 200-length/3.5);

 

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

  fractal(depth,length);

  rotate(angle); 

}

 

Machine generated alternative text:

 

 

 

 

 

var depth = 4;

var length = 200;

var factors = [1/3, 1/3, 1/3, 1/3, 1/3];

var turns = [-90, 90, 90, -90, 0];

var copies = 4;

var angle = 90;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200-length/2, 200-length/2);

 

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

  fractal(depth,length);

  rotate(angle); 

}

 

Machine generated alternative text:

 

var depth = 4;

var length = 200;

var factors = [1/3, 1/3, 1/3, 1/3, 1/3];

var turns = [-90, 90, 90, -90, 0];

var copies = 4;

var angle = 90;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        //line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200-length/2, 200-length/2);

 

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

  fractal(depth,length);

  rotate(angle); 

}

 

Machine generated alternative text:

 

 

var depth = 4;

var length = 250;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var copies = 4;

var angle = 90;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        //line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200-length/2, 200-length/2);

 

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

  fractal(depth,length);

  rotate(angle); 

}

 

 

Machine generated alternative text:

 

var depth = 5;

var length = 250;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var copies = 4;

var angle = 90;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        //line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200-length/2, 200-length/2);

 

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

  fractal(depth,length);

  rotate(angle); 

}

 

rotate(90);

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

  fractal(depth,length);

  rotate(-angle); 

}

 

Machine generated alternative text:

 

var depth = 4;

var length = 250;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var copies = 4;

var angle = 90;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200-length/2, 200-length/2);

 

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

  fractal(depth,length);

  rotate(angle); 

}

Machine generated alternative text:

 

 

 

Jewelry Design (JavaScript)

 

var depth = 5;

var length = 325;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var copies = 3;

var angle = 120;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        //line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200, 25);

rotate(90);

fractal(depth,length);

rotate(180);

fractal(depth,length);

 

Machine generated alternative text:

 

var depth = 3;

var length = 200;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var copies = 3;

var angle = 120;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        //line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200, 200);

rotate(90);

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

    fractal(depth,length);

    rotate(180);

    fractal(depth,length);

    rotate(180);

    rotate(10);

}

 

 

Machine generated alternative text:

 

 

var depth = 5;

var length = 200;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var copies = 3;

var angle = 1;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        //line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200, 200);

rotate(90);

 

var draw = function() {

    if (mouseIsPressed) {

        rotate(angle);

        angle+=5;

        fractal(depth,length);

        rotate(180);

        fractal(depth,length);

        rotate(180);       

    }

};

 

Machine generated alternative text:

 

 

Machine generated alternative text:

 

Machine generated alternative text:

 

var depth = 5;

var length = 200;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var copies = 3;

var angle = 1;

 

var r = random(0,255);

var g = random(0,255);

var b = random(0,255);

 

var adjustColor = function() {

    r += random(-20,20);

    g += random(-20,20);

    b += random(-20,20);

    if (r > 255) {

        r = 512 - r;

    }

    if (g > 255) {

        g = 512 - g;

    }

    if (b > 255) {

        b = 512 - b;

    }

    if (r < 0) {

        r = -r;

    }

    if (g < 0) {

        g = - g;

    }

    if (b < 0) {

        b = - b;

    }

    stroke(r, g, b);

};

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200, 200);

rotate(random(0,360));

 

var draw = function() {

    if (mouseIsPressed) {

        rotate(angle);

        angle+=5;

        adjustColor();

        fractal(depth,length);

        rotate(180);

        fractal(depth,length);

        rotate(180);       

    }

};

 

 

 

Machine generated alternative text:

 

var depth = 5;

var length = 200;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var angle = 1;

 

var r = random(0,255);

var g = random(0,255);

var b = random(0,255);

 

var adjustColor = function() {

    r += random(-20,20);

    g += random(-20,20);

    b += random(-20,20);

    if (r > 255) {

        r = 512 - r;

    }

    if (g > 255) {

        g = 512 - g;

    }

    if (b > 255) {

        b = 512 - b;

    }

    if (r < 0) {

        r = -r;

    }

    if (g < 0) {

        g = - g;

    }

    if (b < 0) {

        b = - b;

    }

    stroke(r, g, b);

};

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200, 200);

rotate(random(0,360));

 

var draw = function() {

    if (mouseIsPressed) {

        rotate(angle);

        angle+=3;

        adjustColor();

        fractal(depth,length);

        rotate(180);

    }

};

 

Machine generated alternative text:

var depth = 4;

var length = 200;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var copies = 3;

var angle = 120;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        //line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200, 200);

rotate(90);

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

    fractal(depth,length);

    rotate(180);

    fractal(depth,length);

    rotate(180);

    rotate(60);

}

 

Machine generated alternative text:

 

 

var depth = 4;

var length = 200;

var factors = [1/3, 1/3, 1/3, 1/3];

var turns = [-60, 120, -60, 0];

var copies = 3;

var angle = 120;

 

var fractal = function(level, length) {

 

    if (level < 1) {

        line(0,0,length,0);

        translate(length,0);

    } else {

        //line(0,0,length,0);

        for(var i = 0 ; i < factors.length ; i++) {

            fractal(level-1, length * factors[i]);

            rotate(turns[i]);

        }

    }

};

 

angleMode="degrees";

translate(200, 150);

rotate(90);

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

    fractal(depth,length);

    rotate(180);

    fractal(depth,length);

    rotate(180);

    rotate(120);

}

 

Machine generated alternative text:

 

 

 

Machine generated alternative text:

https://www.khanacademy.org/cs/recursive-triangles/5279369537781760

 

 

var depth = 3;

 

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

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

    if (depth > 0) {

        var x12 = (x1 + x2) / 2;

        var x13 = (x1 + x3) / 2;

        var x23 = (x2 + x3) / 2;

        var y12 = (y1 + y2) / 2;

        var y13 = (y1 + y3) / 2;

        var y23 = (y2 + y3) / 2;

        depth--;

        drawTriangle(depth, x1, y1, x12, y12, x13, y13);

        drawTriangle(depth, x2, y2, x12, y12, x23, y23);

        drawTriangle(depth, x3, y3, x13, y13, x23, y23);

    }

};

 

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

strokeWeight(2);

drawTriangle(depth, 200,10, 10,390, 390,390);

 

Machine generated alternative text: