block by nitaku ee6cc32a90cc7d1b6fec

Properties of archimedean spirals

Full Screen

TBC

The arc length of an archimedean spiral: http://fiji.sc/downloads/snapshots/arc_length.pdf Number of turns: http://www.physicsforums.com/showthread.php?t=601610 Manca un po’ di matematica.

index.js

(function() {
  var COILS, D, HEIGHT, SAMPLES, THETA, WIDTH, a, b, line_generator, number_of_points, points, radius, randint, s, spiral, svg, svg_s;

  randint = function(n) {
    return Math.round(Math.random() * n);
  };

  a = 0;

  D = 8 + randint(16);

  b = D / (2 * Math.PI);

  COILS = 2 + randint(6);

  THETA = 2 * Math.PI * COILS;

  SAMPLES = 48;

  number_of_points = Math.ceil(THETA / (2 * Math.PI) * SAMPLES) + 1;

  points = d3.range(0, number_of_points).map(function(i) {
    var theta;

    theta = i * 2 * Math.PI / SAMPLES;
    return {
      theta: theta - Math.PI / 2,
      r: a + b * theta
    };
  });

  WIDTH = 960;

  HEIGHT = 500;

  svg = d3.select('body').append('svg').attr({
    width: WIDTH,
    height: HEIGHT
  }).append('g').attr({
    transform: "translate(" + (WIDTH / 2) + "," + (HEIGHT / 2) + ")"
  });

  radius = a + b * THETA;

  svg.append('circle').attr({
    "class": 'radius_indicator',
    r: radius
  });

  svg.append('line').attr({
    "class": 'axis',
    x1: -WIDTH,
    x2: WIDTH
  });

  svg.append('line').attr({
    "class": 'axis',
    y1: -HEIGHT,
    y2: HEIGHT
  });

  line_generator = d3.svg.line().x(function(d) {
    return d.r * Math.cos(d.theta);
  }).y(function(d) {
    return d.r * Math.sin(d.theta);
  }).interpolate('linear');

  spiral = svg.append('path').datum(points).attr({
    "class": 'spiral',
    d: line_generator
  });

  s = Math.PI * D * COILS * COILS;

  svg_s = spiral[0][0].getTotalLength();

  svg.append('text').text("a = " + a).attr({
    "class": 'label',
    x: -WIDTH / 2 + 20,
    y: -HEIGHT / 2 + 20,
    dy: '0.35em'
  });

  svg.append('text').text("b ≈ " + (d3.format('.3f')(b))).attr({
    "class": 'label',
    x: -WIDTH / 2 + 20,
    y: -HEIGHT / 2 + 45,
    dy: '0.35em'
  });

  svg.append('text').text("D = 2πb =  " + D).attr({
    "class": 'label',
    x: -WIDTH / 2 + 20,
    y: +HEIGHT / 2 - 45,
    dy: '0.35em'
  });

  svg.append('text').text("n = " + COILS).attr({
    "class": 'label',
    x: -WIDTH / 2 + 20,
    y: +HEIGHT / 2 - 20,
    dy: '0.35em'
  });

  svg.append('text').text("r ≈ " + (d3.format('.0f')(radius))).attr({
    "class": 'label',
    x: radius + 10,
    dy: '-0.25em'
  });

  svg.append('text').text("s ≈ " + (d3.format(',.0f')(s))).style({
    fill: 'black'
  }).attr({
    "class": 'label',
    x: 6,
    y: -radius,
    dy: '-0.25em'
  });

  svg.append('text').text("E ≈ " + (d3.format(',.3f')(svg_s - s))).style({
    fill: 'brown',
    'font-size': '14px'
  }).attr({
    "class": 'label',
    x: 6,
    y: -radius - 20,
    dy: '-0.25em'
  });

}).call(this);

index.html

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="description" content="Properties of archimedean spirals" />
  <title>Properties of archimedean spirals</title>
  <link rel="stylesheet" href="index.css">
  <script src="//d3js.org/d3.v3.min.js"></script>
</head>
<body>
  <script src="index.js"></script>
</body>
</html>

index.coffee

# random spiral parameters
randint = (n) -> Math.round( Math.random()*n )

# WARNING the following assumes a=0
a = 0
D = 8 + randint(16)
b = D/(2*Math.PI)

COILS = 2 + randint(6)
THETA = 2*Math.PI * COILS

# angle samples per turn (not good for large spirals!)
SAMPLES = 48

number_of_points = Math.ceil( THETA/(2*Math.PI) * SAMPLES ) + 1
points = d3.range(0, number_of_points).map (i) ->
  theta = i*2*Math.PI/SAMPLES
  # PI/2 is subtracted from angles to have the spiral end at the top
  return {theta: theta-Math.PI/2, r: a + b*theta}

WIDTH = 960
HEIGHT = 500

svg = d3.select('body').append('svg')
  .attr
    width: WIDTH
    height: HEIGHT
  .append('g')
    .attr
      transform: "translate(#{WIDTH/2},#{HEIGHT/2})"
    
# draw the radius
radius = a + b * THETA

svg.append('circle')
  .attr
    class: 'radius_indicator'
    r: radius
    
# draw axes
svg.append('line')
  .attr
    class: 'axis'
    x1: -WIDTH
    x2: WIDTH
    
svg.append('line')
  .attr
    class: 'axis'
    y1: -HEIGHT
    y2: HEIGHT
    
# draw the spiral
line_generator = d3.svg.line()
  .x((d) -> d.r * Math.cos(d.theta))
  .y((d) -> d.r * Math.sin(d.theta))
  .interpolate('linear')

spiral = svg.append('path')
  .datum(points)
  .attr
    class: 'spiral'
    d: line_generator
    
# compute the length
s = Math.PI * D * COILS*COILS
svg_s = spiral[0][0].getTotalLength()

# draw the parameters
svg.append('text')
  .text("a = #{a}")
  .attr
    class: 'label'
    x: -WIDTH/2+20
    y: -HEIGHT/2+20
    dy: '0.35em'
    
svg.append('text')
  .text("b ≈ #{d3.format('.3f')(b)}")
  .attr
    class: 'label'
    x: -WIDTH/2+20
    y: -HEIGHT/2+45
    dy: '0.35em'
    
svg.append('text')
  .text("D = 2πb =  #{D}")
  .attr
    class: 'label'
    x: -WIDTH/2+20
    y: +HEIGHT/2-45
    dy: '0.35em'
    
svg.append('text')
  .text("n = #{COILS}")
  .attr
    class: 'label'
    x: -WIDTH/2+20
    y: +HEIGHT/2-20
    dy: '0.35em'
    
svg.append('text')
  .text("r ≈ #{d3.format('.0f')(radius)}")
  .attr
    class: 'label'
    x: radius + 10
    dy: '-0.25em'
    
svg.append('text')
  .text("s ≈ #{d3.format(',.0f')(s)}")
  .style({fill: 'black'})
  .attr
    class: 'label'
    x: 6
    y: -radius
    dy: '-0.25em'
    
svg.append('text')
  .text("E ≈ #{d3.format(',.3f')(svg_s-s)}")
  .style({fill: 'brown', 'font-size': '14px'})
  .attr
    class: 'label'
    x: 6
    y: -radius - 20
    dy: '-0.25em'
    

index.css

svg {
  background-color: white;
}
.spiral {
  fill: none;
  stroke: black;
  stroke-width: 2px;
}
.radius_indicator {
  fill: none;
  stroke: gray;
  stroke-dasharray: 3 6;
}
.axis {
  fill: none;
  stroke: lightgray;
  stroke-dasharray: 24 6 2 6;
  shape-rendering: crispEdges;
}
.label {
  fill: gray;
  font-family: Georgia;
  font-style: italic;
  font-size: 20px;
}