block by nitaku 16933e96f51571fbbcd6

Random(ish) polygon

Full Screen

This example generates a random polygon with a round look. Reload the page to generate a new one.

index.js

(function() {
  var N, angles, height, points, side, sum, svg, theta_prev, vis, width;

  svg = d3.select('svg');

  width = svg[0][0].getBoundingClientRect().width;

  height = svg[0][0].getBoundingClientRect().height;

  side = Math.min(width, height);

  vis = svg.append('g').attr({
    transform: "translate(" + (width / 2) + " " + (height / 2) + ")"
  });

  N = 20 + 20 * Math.round(Math.random());

  angles = d3.range(N).map(function(i) {
    return Math.random();
  });

  sum = d3.sum(angles);

  theta_prev = 0;

  points = angles.map(function(a) {
    var rho, theta;

    theta = theta_prev + a * 2 * Math.PI / sum;
    theta_prev = theta;
    rho = d3.random.normal(side / 3, side / 32)();
    return [rho * Math.cos(theta), rho * Math.sin(theta)];
  });

  vis.append('path').datum(points).attr({
    "class": 'polygon',
    d: function(points) {
      return "M" + (points.join('L')) + "Z";
    }
  });

  vis.selectAll('.dots').data(points).enter().append('circle').attr({
    "class": 'dot',
    cx: function(p) {
      return p[0];
    },
    cy: function(p) {
      return p[1];
    },
    r: 2.5
  });

}).call(this);

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="description" content="Random(ish) polygon" />
  <title>Random(ish) polygon</title>
  <link rel="stylesheet" href="index.css">
  <script src="//d3js.org/d3.v3.min.js"></script>
</head>
<body>
  <svg height="500" width="960">
  </svg>
  <script src="index.js"></script>
</body>
</html>

index.coffee

svg = d3.select('svg')
width = svg[0][0].getBoundingClientRect().width
height = svg[0][0].getBoundingClientRect().height
side = Math.min(width, height)

vis = svg.append('g')
  .attr
    transform: "translate(#{width/2} #{height/2})"

# generate N random points
N = 20 + 20 * Math.round(Math.random())
angles = d3.range(N).map (i) -> Math.random()
sum = d3.sum(angles)
theta_prev = 0
points = angles.map (a) ->
  theta = theta_prev + a * 2*Math.PI/sum
  theta_prev = theta
  rho = d3.random.normal(side/3, side/32)()
  return [rho*Math.cos(theta), rho*Math.sin(theta)]
      
vis.append('path')
  .datum(points)
  .attr
    class: 'polygon'
    d: (points) -> "M#{points.join('L')}Z"
    
vis.selectAll('.dots')
    .data(points)
  .enter().append('circle')
    .attr
      class: 'dot'
      cx: (p) -> p[0]
      cy: (p) -> p[1]
      r: 2.5

index.css

svg {
  background-color: white;
}
.polygon {
  stroke: gray;
  fill: #DDD;
}
.dot {
  fill: white;
  stroke: black;
}