~jagtalon/long-exposure-art

367fddc5d287761ebd3e5b737b945d538468dc68 — Jag Talon 1 year, 10 months ago 42d4c62
Use a better algorithm for drawing star trails

Instead of getting the hypotenuse of (0,0) and a random (x,y), simply generate random distances. This way we wouldn't have to compute two random numbers (just the distance instead of x and y) and we also don't have to compute the hypotenuse.
4 files changed, 41 insertions(+), 47 deletions(-)

M long-exposure-art.coffee
M long-exposure-art.js
M tiny-canvas.coffee
M tiny-canvas.js
M long-exposure-art.coffee => long-exposure-art.coffee +12 -16
@@ 11,14 11,13 @@ sketch = ->
		draw = new TinyCanvas(context)

		# Helper Functions
		# ---------
		# ----------------

		# drawStarTrails
		# 1. We compute the hypotenuse between (0,0) and (x,y).
		# 2. Create an arc with an angle theta.
		# 3. Rotate the arc to a random angle (Math.random() * 2π)
		drawStarTrails = (x, y, theta) ->
			draw.circle 0, 0, Math.hypot(x, y), 0, theta
		# 1. For each radius, create an arc with an angle theta.
		# 2. Rotate the arc to a random angle (Math.random() * 2π)
		drawStarTrails = (radius, theta) ->
			draw.circle 0, 0, radius, 0, theta
			draw.stroke "#DEE2E6", Math.random() * 15, "round"
			draw.rotate Math.random() * 2 * Math.PI



@@ 26,22 25,19 @@ sketch = ->
		# -------

		# Set the night sky.
		draw.rectFill 0, 0, width, height, "#212529"
		draw.rect 0, 0, width, height, "fill", "#212529"

		# Translate to the center of the canvas.
		# Set the coordinates of the rotation.
		draw.translate width * .6, height * 0.8

		# Create stars
		# We generate random x-y points multiple times and assign them
		# to an array so that we can use them later.
		stars = ([Math.random() * width, Math.random() * height] for n in [1..1000])
		
		# Set an angle that will be used everywhere.
		# This can be any arbitrary angle.
		# This can be any arbitrary angle, but it
		# must be the same for all star trails.
		theta = Math.PI/4

		# Draw arcs for each star we generated previously.
		drawStarTrails star[0], star[1], theta for star in stars
		# Generate radii
		# We generate random radii then create star trails for each one.
		(drawStarTrails Math.random() * height, theta) for n in [1..1000]


canvasSketch sketch, settings
\ No newline at end of file

M long-exposure-art.js => long-exposure-art.js +14 -25
@@ 13,17 13,16 @@

  sketch = function() {
    return function({context, width, height}) {
      var draw, drawStarTrails, i, len, n, results, star, stars, theta;
      var draw, drawStarTrails, i, n, results, theta;
      draw = new TinyCanvas(context);
      // Helper Functions
      // ---------
      // ----------------

      // drawStarTrails
      // 1. We compute the hypotenuse between (0,0) and (x,y).
      // 2. Create an arc with an angle theta.
      // 3. Rotate the arc to a random angle (Math.random() * 2π)
      drawStarTrails = function(x, y, theta) {
        draw.circle(0, 0, Math.hypot(x, y), 0, theta);
      // 1. For each radius, create an arc with an angle theta.
      // 2. Rotate the arc to a random angle (Math.random() * 2π)
      drawStarTrails = function(radius, theta) {
        draw.circle(0, 0, radius, 0, theta);
        draw.stroke("#DEE2E6", Math.random() * 15, "round");
        return draw.rotate(Math.random() * 2 * Math.PI);
      };


@@ 31,29 30,19 @@
      // -------

      // Set the night sky.
      draw.rectFill(0, 0, width, height, "#212529");
      // Translate to the center of the canvas.
      draw.rect(0, 0, width, height, "fill", "#212529");
      // Set the coordinates of the rotation.
      draw.translate(width * .6, height * 0.8);
      // Create stars
      // We generate random x-y points multiple times and assign them
      // to an array so that we can use them later.
      stars = (function() {
        var i, results;
        results = [];
        for (n = i = 1; i <= 1000; n = ++i) {
          results.push([Math.random() * width, Math.random() * height]);
        }
        return results;
      })();
      
      // Set an angle that will be used everywhere.
      // This can be any arbitrary angle.
      // This can be any arbitrary angle, but it
      // must be the same for all star trails.
      theta = Math.PI / 4;
      results = [];
      for (i = 0, len = stars.length; i < len; i++) {
        star = stars[i];
        // Draw arcs for each star we generated previously.
        results.push(drawStarTrails(star[0], star[1], theta));
      for (n = i = 1; i <= 1000; n = ++i) {
        // Generate radii
        // We generate random radii then create star trails for each one.
        results.push(drawStarTrails(Math.random() * height, theta));
      }
      return results;
    };

M tiny-canvas.coffee => tiny-canvas.coffee +7 -3
@@ 14,9 14,13 @@ module.exports = class TinyCanvas
	rotate: (angle) ->
		@context.rotate(angle)

	rectFill: (x, y, width, height, color = "#000000") ->
		@context.fillStyle = color
		@context.fillRect 0, 0, width, height
	rect: (x, y, width, height, mode = "fill", color = "#000000") ->
		if mode == "fill"
			@context.fillStyle = color
			@context.fillRect 0, 0, width, height
		else
			@context.strokeStyle = color
			@context.strokeRect 0, 0, width, height

	translate: (x, y) ->
		@context.translate x, y

M tiny-canvas.js => tiny-canvas.js +8 -3
@@ 23,9 23,14 @@
      return this.context.rotate(angle);
    }

    rectFill(x, y, width, height, color = "#000000") {
      this.context.fillStyle = color;
      return this.context.fillRect(0, 0, width, height);
    rect(x, y, width, height, mode = "fill", color = "#000000") {
      if (mode === "fill") {
        this.context.fillStyle = color;
        return this.context.fillRect(0, 0, width, height);
      } else {
        this.context.strokeStyle = color;
        return this.context.strokeRect(0, 0, width, height);
      }
    }

    translate(x, y) {