{"id":69020,"date":"2021-11-13T23:51:35","date_gmt":"2021-11-14T04:51:35","guid":{"rendered":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/?p=69020"},"modified":"2021-11-13T23:51:35","modified_gmt":"2021-11-14T04:51:35","slug":"project-11-generative-landscape-3","status":"publish","type":"post","link":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/2021\/11\/13\/project-11-generative-landscape-3\/","title":{"rendered":"Project 11: Generative Landscape"},"content":{"rendered":"<!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD HTML 4.0 Transitional\/\/EN\" \"http:\/\/www.w3.org\/TR\/REC-html40\/loose.dtd\">\n<html><body><div class=\"wp-block-file\"><a class=\"p5_sketch_link\" data-height=\"300\" data-width=\"480\" href=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2021\/11\/sketch-48.js\">sketch<\/a><a href=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2021\/11\/sketch-48.js\" class=\"wp-block-file__button\" download>Download<\/a><iframe src=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/plugins\/p5-embedder\/p5_iframe.html\" class=\"p5_exampleFrame\" width=\"480\" height=\"300\"><\/iframe><pre class=\"language-javascript\"><code class=\"p5_editor language-javascript\">\/\/ this program displays a landscape of a stone path along a stream in the woods.\n\n\/\/ empty arrays for objects:\nvar bkgrndtrees = [];\nvar path = [];\nvar stream = [];\nvar trees = [];\nvar allArrays = [bkgrndtrees, path, stream, trees];\n\n\/\/ speed of landscape shift, per frame\n\/\/ adjusted for background+foreground so 'closer' objects move faster than 'far away' ones\nvar shift = -1;\n\nfunction setup() {\n    createCanvas(480, 300);\n    background(80, 125, 60);\n    frameRate(200);\n\n    \/\/ create initial collections of objects:\n    fillBkgrndtrees();\n    fillPath();\n    fillStream();\n    fillTrees();\n\n    \/\/ sort objects in arrays to be drawn properly:\n    for (a=0; a&lt;allArrays.length; a++) {\n        if (allArrays[a]!=stream){          \/\/ stream should not be ordered\n            orderObjects(allArrays[a]);\n        }\n    }\n}\n\n\/\/ fills backgroundTrees array with initial trees:\nfunction fillBkgrndtrees() {\n    for (var i = 0; i &lt; 320; i++) {\n        var rx = random(width+75);\n        var ry = random(-height\/25, 2*height\/5);      \/\/ top of canvas = background\n        bkgrndtrees[i] = makeTree(rx, ry);\n    }\n}\n\n\/\/ fills foreground tree array with initial trees:\nfunction fillTrees() {\n    for (var i = 0; i &lt; 5; i++) {\n        var rx = random(width+75);\n        var ry = random(4*height\/5, 3*height\/2);    \/\/ bottom of canvas = foreground\n        trees[i] = makeTree(rx, ry);\n    }\n}\n\n\/\/ fills path array with initial stones:\nfunction fillPath() {\n    for (var i = 0; i &lt; 15; i++) {\n        var size = random(width\/25, width\/10);\n        var col = color(random(90, 120));\n        var x = i*50;\n        var ry = random(height\/2, 3*height\/5);\n        path[i] = makeStone(x, ry, size, col);\n    }\n}\n\n\/\/ fills stream array with objects based on stone path:\nfunction fillStream() {\n    for (var i = 0; i &lt; path.length; i++) {\n        var x = i*50;\n        var y = path[i].y + path[i].size;\n        stream[i] = makePoint(x, y);\n    }\n}\n\n\/\/ creates a tree object\nfunction makeTree(tx, ty) {\n    \/\/ background trees:\n    if (ty &lt; height\/2) {\n        var tree = {x:tx,\n                    y:ty,\n                    age:random(2, 11),\n                    trunkc: color(random(70, 90), random(55, 75), random(30, 55)),\n                    leavesc: color(random(0, 75), random(65, 175), random(50)),\n                    show: showTree,\n                    move: moveObject,\n                    speed: shift*.85 }\n    }\n    \/\/ foreground trees:\n    else {\n        var tree = {x:tx,\n                    y:ty,\n                    age:random(4, 7),\n                    trunkc: color(random(50, 80), random(20, 50), random(10, 20)),\n                    leavesc: color(random(0, 100), random(100, 200), random(30)),\n                    show: showTree,\n                    move: moveObject,\n                    speed: shift*1.15 }\n    }\n\n    return tree;\n}\n\n\/\/ creates a stone object\nfunction makeStone(sx, sy, ssize, scol) {\n    var stone = {x:sx,\n                 y:sy,\n                 size:ssize,\n                 c: scol,\n                 show: showStone,\n                 move: moveObject,\n                 speed: shift}\n    return stone;\n}\n\n\/\/ creates a point object (for stream curve);\nfunction makePoint(px, py) {\n    var pnt = {x:px,\n               y:py,\n               size:width\/50,\n               c: color(50, 125, 175),\n               show: showStone,\n               move: moveObject,\n               speed: shift}\n    return pnt;\n}\n\nfunction draw() {\n    background(80, 125, 60);\n\n    \/\/ draw all objects in all arrays:\n    for (j=0; j&lt;allArrays.length; j++) {\n        thisArray = allArrays[j];\n        drawObjects(thisArray);\n        if (thisArray!=stream) {        \/\/ stream is updated with path\n            \/\/ order and updates arrays:\n            orderObjects(thisArray);\n            updateArray(thisArray);\n        }\n    }\n}\n\n\/\/ draws and moves objects in an array\nfunction drawObjects(array) {\n    for (i=0; i&lt;array.length; i++) {\n        thisObj = array[i];\n        thisObj.show();\n        thisObj.move();\n    }\n    if (array==stream) {\n        drawStream();\n    }\n}\n\n\/\/ uses curve shape and array points ot draw stream\nfunction drawStream() {\n    push();\n    noFill();\n    stroke(50, 125, 175);\n    strokeWeight(15);\n    curveTightness(-.2);\n    beginShape();\n    curveVertex(stream[0].x, stream[0].y);\n    curveVertex(stream[0].x, stream[0].y);\n    for (var m=1; m&lt;stream.length-1; m++){\n        curveVertex(stream[m].x, stream[m].y);\n    }\n    curveVertex(stream[stream.length-1].x, stream[stream.length-1].y);\n    endShape();\n    pop();\n}\n\n\/\/ sorts objects in an array according to the y feild\n\/\/ this ordering ensures accurate depth on canvas\nfunction orderObjects(array) {\n    for (var j=0; j&lt;array.length-1; j++) {\n        var counter = 0;\n        for (var i=0; i&lt;array.length-1; i++) {\n            if (array[i].y &gt; array[i+1].y) {\n                var tmp = array[i];\n                array[i] = array[i+1];\n                array[i+1] = tmp;\n                counter += 1;\n            }\n        }\n        if (counter==0) {\n            break;\n        }\n    }\n}\n\n\/\/ updates all allArrays\n\/\/ adds new objects to end and deletes unused objects (off canvas)\nfunction updateArray(array) {\n    if (array==trees || array==bkgrndtrees) {\n        \/\/ add new trees to array off-canvas:\n        \/\/ background trees:\n        var treeLikelihoodB = 320\/555;\n        if (random(1) &lt; treeLikelihoodB) {\n            var ry = random(-height\/25, 2*height\/5);    \/\/ top of canvas = background\n            bkgrndtrees.push(makeTree(width+75, ry));\n        }\n        \/\/ foreground trees:\n        var treeLikelihoodF = 5\/555;\n        if (random(1) &lt; treeLikelihoodF) {\n            var ry = random(3*height\/4, 3*height\/2);      \/\/ bottom of canvas = foreground\n            trees.push(makeTree(width+75, ry));\n        }\n    }\n    else {\n        \/\/ path and stream use fixed x values:\n        if (frameCount%50==0) {\n            var size = random(width\/25, width\/10);\n            var col = color(random(90, 120));\n            var ry = random(height\/2, 3*height\/5);\n            path.push(makeStone(700, ry, size, col));\n            col = color(0, 50, 150);\n                var y = ry + size;\n            stream.push(makePoint(700, y));\n        }\n    }\n\n    \/\/ remove any object no longer on canvas:\n    var keep = [];\n    for (var k=0; k&lt;array.length; k++) {\n        if (array[k].x &gt; 0) {\n            keep.push(array[k]);\n        }\n    }\n    array = keep;\n}\n\n\/\/ draws tree based on age\nfunction showTree() {\n    if (this.y &lt; height\/2) {     \/\/ top of canvas = background\n        var h = this.age*10;\n        var w = this.age*2;\n    }\n    else {                      \/\/ bottom of canvas = foreground\n        var h = this.age*12;\n        var w = this.age*2.5;\n    }\n    var cx = this.x + w\/2;\n    var cy = this.y - h*1.5;\n\n    if (this.age &gt; 5) {             \/\/ older trees\n        stroke(50, 40, 30);\n        fill(this.trunkc);\n        rect(this.x, this.y-h, w, h);\n        fill(this.leavesc);\n        for (var i=0; i&lt;3; i++) {\n            stroke(0, 75, 0);\n            circle(cx - (this.age*4*i) + (this.age*4),\n                   cy - (this.age*1.5) + (this.age*3*i),\n                   this.age*5);\n            circle(cx + (this.age*4*i) - (this.age*4),\n                   cy - (this.age*1.5) + (this.age*3*i),\n                   this.age*5);\n            ellipse(cx - (this.age*6*i) + (this.age*6),\n                    cy + this.age,\n                    this.age*5,\n                    this.age*6);\n            ellipse(cx,\n                    cy - (this.age*3) + (this.age*4*i),\n                    this.age*7,\n                    this.age*5);\n        }\n        noStroke();\n        ellipse(cx, cy + this.age, this.age*12, this.age*9);\n    }\n    else {                          \/\/ younger trees\n        stroke(50, 40, 30);\n        fill(this.trunkc);   \/\/ tree trunk lighter brown\n        rect(this.x, this.y-h, w\/2, h);\n        fill(this.leavesc);\n        for (var i=0; i&lt;3; i++) {\n            stroke(0, 75, 0);\n            circle(cx - (this.age*3*i) + (this.age*3),\n                   cy - (this.age*1.5) + (this.age*2*i),\n                   this.age*4);\n            circle(cx + (this.age*3*i) - (this.age*3),\n                   cy - (this.age*1.5) + (this.age*2*i),\n                   this.age*4);\n            ellipse(cx - (this.age*4*i) + (this.age*4),\n                    cy + this.age,\n                    this.age*4,\n                    this.age*5);\n            ellipse(cx,\n                    cy - (this.age*4) + (this.age*4*i),\n                    this.age*6,\n                    this.age*4);\n        }\n        noStroke();\n        ellipse(cx, cy + this.age\/2, this.age*11, this.age*9);\n    }\n}\n\n\/\/ draws stone for path\nfunction showStone() {\n    stroke(75);\n    fill(this.c);\n    ellipse(this.x, this.y, this.size, this.size\/2);\n}\n\n\/\/ updates x values to move the landscape along\nfunction moveObject() {\n    this.x += this.speed;\n}\n<\/code><\/pre><\/div>\n\n\n\n<p>For this project, I was inspired by a trail I used to walk a lot growing up. I struggled a bit to order the objects in a way that looks nice and is recognizable as a landscape, but I think the orderObjects() function that I created helped a lot with that. I also found it difficult to create the stream using a curve shape, but I am again really pleased with how well it came out. I wanted the path and stream to flow along together, and they do. To give more of a landscape effect, I adjusted the shift values for moving the objects so that  things in the foreground move faster than things in the background. <\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"1024\" height=\"768\" src=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2021\/11\/IMG_2177-scaled-e1636865445415-1024x768.jpg\" alt=\"\" class=\"wp-image-69025\" srcset=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2021\/11\/IMG_2177-scaled-e1636865445415-1024x768.jpg 1024w, https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2021\/11\/IMG_2177-scaled-e1636865445415-300x225.jpg 300w, https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2021\/11\/IMG_2177-scaled-e1636865445415-768x576.jpg 768w, https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2021\/11\/IMG_2177-scaled-e1636865445415-1536x1152.jpg 1536w, https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2021\/11\/IMG_2177-scaled-e1636865445415-2048x1536.jpg 2048w, https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-content\/uploads\/2021\/11\/IMG_2177-scaled-e1636865445415-1200x900.jpg 1200w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 1362px) 62vw, 840px\"><figcaption>My initial sketch of the stream in the woods.<\/figcaption><\/figure><p><\/p><\/body><\/html>\n","protected":false},"excerpt":{"rendered":"<p>sketchDownload \/\/ this program displays a landscape of a stone path along a stream in the woods. \/\/ empty arrays for objects: var bkgrndtrees = []; var path = []; var stream = []; var trees = []; var allArrays = [bkgrndtrees, path, stream, trees]; \/\/ speed of landscape shift, per frame \/\/ adjusted for &hellip; <a href=\"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/2021\/11\/13\/project-11-generative-landscape-3\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Project 11: Generative Landscape&#8221;<\/span><\/a><\/p>\n","protected":false},"author":673,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[115,56,1],"tags":[],"_links":{"self":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/posts\/69020"}],"collection":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/users\/673"}],"replies":[{"embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/comments?post=69020"}],"version-history":[{"count":3,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/posts\/69020\/revisions"}],"predecessor-version":[{"id":69026,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/posts\/69020\/revisions\/69026"}],"wp:attachment":[{"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/media?parent=69020"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/categories?post=69020"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/courses.ideate.cmu.edu\/15-104\/f2021\/wp-json\/wp\/v2\/tags?post=69020"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}