diff --git a/README.md b/README.md index 836fa4e..5cda6fe 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # PolyTree -Starting from a central polygon, one can imagine a tree _P_ of polygons created by attaching otherpolygons at each edge of the central one and iterating. Of course, many of the resulting polygons overlap. PolyTree selects and displays non-overlapping subtrees of _P_ in a variety of ways. +Starting from a central polygon, one can imagine a tree _P_ of polygons created by attaching other polygons at each edge of the central one and iterating. Of course, many of the resulting polygons overlap. PolyTree selects and displays non-overlapping subtrees of _P_ in a variety of ways. ## Implementation -As a first pass, PolyTree will consist of a Processing sketch written in CoffeeScript along with a minimal framework for deploying it (a bit of HTML and JavaScript). +As a first pass, PolyTree will consist of a Processing sketch written in CoffeeScript along with some utility classes and a minimal framework for deploying it (a bit of HTML and JavaScript). ## Running -Although you can use any server and CoffeeScript compiler you like, one path of low resistance for running PolyTree is to use Node.js. Hence, the following procedure assumes you have the node package manager (npm) already installed. +Although you can use any server and CoffeeScript compiler you like, one path of low resistance for running PolyTree is to use Node.js. Hence, the following procedure assumes you have the Node package manager (npm) already installed. Make sure you have http-server and CoffeeScript installed globally (note you may need to run the following with sudo depending on your setup): ```bash @@ -21,9 +21,9 @@ git clone https://code.studioinfinity.org/glen/polytree.git cd polytree ``` -Set coffee to compile the main script (the "--watch" flag is only necessary if you may be editing the script and would like the files being served to update automatically), and start serving the files: +Set coffee to compile the scripts in this directory (the "--watch" flag is only necessary if you may be editing the code and would like the files being served to update automatically), and start serving the files: ``` -coffee --watch -c polytree.coffee & +coffee --watch -c *.coffee & http-server ``` diff --git a/deque.coffee b/deque.coffee new file mode 100644 index 0000000..809eee5 --- /dev/null +++ b/deque.coffee @@ -0,0 +1,43 @@ +# Roughly following https://learnersbucket.com/tutorials/data-structures/implement-deque-data-structure-in-javascript/ + +export default class Deque + constructor: -> + @clear() + + insertLeft: (elm) -> # Add an item on the left + if @left_full > 0 + @items[--@left_full] = elm + else + @right_open++ + @items.unshift elm + + insertRight: (elm) -> # Add an item on the right of the list + @items[@right_open++] = elm + + removeLeft: -> # Remove the item from the left + @nonempty() and @items[@left_full++] + + removeRight: -> # Remove the item from the right + @nonempty() and @items[--@right_open] + + left: -> # Peek the leftmost element + @nonempty and @items[@left_full] + + right: -> # Peek the last element + @nonempty and @items[@right_open - 1] + + nonempty: -> # Returns null if no elements + (@right_open > @left_full) or null + + empty: -> # Returns null if any elements + (@right_open is @left_full) or null + + size: -> # Number of elements + @right_open - @left_full + + clear: -> # Remove all elements + @right_open = @left_full = 0 + @items = [] + + toString: -> + "<#{@items[@left...@right].join(",")}>" diff --git a/polytree.coffee b/polytree.coffee index 17049a9..2d36dde 100644 --- a/polytree.coffee +++ b/polytree.coffee @@ -1,11 +1,15 @@ # PolyTree, intended to be loaded as a module import {p5, p5loaded, p5vector} from './lib/loadp5.js' +import Deque from './deque.js' # Weird to write it this way when + # it's implemented in deque.coffee, but oh well. sketch = (p) -> - pos = null - vel = null - abs = Math.abs # For convenience + leaves = new Deque() + leaves.insertRight p.createVector 0 + sides = 5 + length = 20 + steps = (p5vector.fromAngle(i*p.TAU/sides).mult length for i in [0...sides]) p.setup = => p.createCanvas window.innerWidth, 575, p.WEBGL @@ -14,12 +18,10 @@ sketch = (p) -> pos = p.createVector p.width, p.height p.draw = => - if abs(pos.x) > p.width/2 or abs(pos.y) > p.height/2 - pos = p.createVector 0 - vel = p5vector.random2D().mult 32 - else - pos.add vel - p.point pos + current = leaves.removeRight() + p.point current + for step in steps + leaves.insertLeft current.copy().add(step) show = () -> P5 = new p5 sketch