Question

I want to programm this cool visualization with javascrip:

http://imgur.com/ZCUW7js

I have this: http://test.wikunia.de/pi/ but unfortunately I have no idea how to draw the lines that there is a black circle in the middle. Any idea? I am using quadraticCurveTo now, but maybe bezier curve is a better option...

My full code:

var canvas = document.getElementById('myCanvas');
var color_arr = new Array("yellow","orange","OrangeRed","red","violetred","MediumSlateBlue","blue","aquamarine","green","greenyellow");
var sA = (Math.PI / 180) * 270;
var pA = (Math.PI / 180) * 36;
if (canvas && canvas.getContext) {
  var ctx = canvas.getContext("2d");
  if (ctx) {
  ctx.fillStyle = "black";
  ctx.fillRect(0,0,ctx.canvas.width, ctx.canvas.height);



  for (var i=0; i <= 9; i++) {
      ctx.strokeStyle = color_arr[i];
      ctx.lineWidth = 5;
      ctx.beginPath();
      ctx.arc (350,  350,  250,  sA+(i)*pA,  sA+(i+1)*pA,  false);
      ctx.stroke();
      ctx.closePath();
      ctx.fillStyle = "white";
      ctx.strokeStyle = "white";
      ctx.font = "italic 30pt Arial";
      if (i > 4 && i < 8) {
        ctx.fillText(i.toString(), 350+290*Math.cos(sA+(i+0.5)*pA),350+290*Math.sin(sA+(i+0.5)*pA));
      } else {
        if (i == 3 || i == 4 || i == 8) {
            ctx.fillText(i.toString(), 350+275*Math.cos(sA+(i+0.5)*pA),350+275*Math.sin(sA+(i+0.5)*pA));
        } else {
            ctx.fillText(i.toString(), 350+260*Math.cos(sA+(i+0.5)*pA),350+260*Math.sin(sA+(i+0.5)*pA));
        }
      }
  }




  var pi = '31415...';
  for (i = 0; i <= 250; i++) {
      line(parseInt(pi.substr(i,1)),parseInt(pi.substr(i+1,1)));
  }
}
}

function line(no_1,no_2) {
  var rand_1 = Math.random();
  var rand_2 = Math.random();
  var grad= ctx.createLinearGradient(350+250*Math.cos(sA+(no_1+rand_1)*pA), 350+250*Math.sin(sA+(no_1+rand_1)*pA), 350+250*Math.cos(sA+(no_2+rand_2)*pA), 350+250*Math.sin(sA+(no_2+rand_2)*pA));
  grad.addColorStop(0, color_arr[no_1]);
  grad.addColorStop(1, color_arr[no_2]);
  ctx.lineWidth = 1;
  ctx.strokeStyle = grad;
  ctx.beginPath();

  ctx.moveTo(350+250*Math.cos(sA+(no_1+rand_1)*pA), 350+250*Math.sin(sA+(no_1+rand_1)*pA));
  ctx.quadraticCurveTo(350,350,350+250*Math.cos(sA+(no_2+rand_2)*pA),350+250*Math.sin(sA+(no_2+rand_2)*pA));
  ctx.stroke();
  }

No correct solution

OTHER TIPS

Interesting!

The black circle in the middle is just an absence of curves.

The "lines" are cubic Bezier curves.

The beziers appear to be anchored on both ends to the circle circumference at intervals.

Here's my try at a simplified version of that PI: http://jsfiddle.net/m1erickson/Ju6E8/

This could be addictive so I'm leaving my attempt simple!

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:50px; }
    #canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var PI2=Math.PI*2;
    var cx=150;
    var cy=150;
    var r=100;

    ctx.arc(cx,cy,r,0,Math.PI*2);
    ctx.closePath();
    ctx.stroke();

    for(var a=0;a<PI2;a+=PI2/20){
        ctx.strokeStyle="blue";
        curve(a,PI2/2.5,25);
        ctx.strokeStyle="green";
        curve(a,PI2/5,50);
        ctx.strokeStyle="red";
        curve(a,PI2/10,75);
    }

    function curve(rotation,offset,innerRadius){
        var x1=cx+r*Math.cos(rotation);
        var y1=cy+r*Math.sin(rotation);
        var x2=cx+innerRadius*Math.cos(rotation+offset/3.5);
        var y2=cy+innerRadius*Math.sin(rotation+offset/3.5);
        var x3=cx+innerRadius*Math.cos(rotation+offset/1.5);
        var y3=cy+innerRadius*Math.sin(rotation+offset/1.5);
        var x4=cx+r*Math.cos(rotation+offset);
        var y4=cy+r*Math.sin(rotation+offset);
        ctx.beginPath();
        ctx.moveTo(x1,y1);
        ctx.bezierCurveTo(x2,y2,x3,y3,x4,y4);
        ctx.stroke();
    }


    $("#stop").click(function(){});

}); // end $(function(){});
</script>

</head>

<body>
    <button id="stop">Stop</button><br>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top