Last active
January 6, 2017 03:31
-
-
Save topologicallytony/9e32ba064d2f552bad456d3fe3ca106a to your computer and use it in GitHub Desktop.
Achimedes Approximation to Pi
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>Archimedes Pi</title> | |
<!-- D3.js --> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<!-- Latest compiled and minified CSS --> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> | |
<style type="text/css"> | |
.inner { | |
fill: none; | |
stroke: steelblue; | |
stroke-width: 1.5px; | |
} | |
.outer { | |
fill: none; | |
stroke: steelblue; | |
stroke-width: 1.5px; | |
} | |
/*************************************************/ | |
/********************Axis*************************/ | |
/*************************************************/ | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: black; | |
shape-rendering: crispEdges; | |
} | |
.axis text { | |
font-family: sans-serif; | |
font-size: 11px; | |
} | |
</style> | |
</head> | |
<body> | |
<div> | |
Click to add sides | |
</div> | |
<div id="container"> | |
<script type="text/javascript"> | |
//Width and height of the visualization. Smaller numbers will zoom in, larger numbers zoom out | |
var w = 500; | |
var h = 500; | |
//padding creates a buffer of white space around the chart to make it a little easier to look at | |
var padding = 15; | |
//Generate Base Dataset | |
//Start with Triangle | |
var numDataPoints = 3; | |
//Create the scales used to map datapoints | |
var xScale = d3.scaleLinear() | |
.domain([-2,2]) | |
.range([padding, w - padding]); | |
var yScale = d3.scaleLinear() | |
.domain([-2,2]) | |
.range([h - padding, padding]); | |
//Create a canvas to display the chart on | |
var svg = d3.select("div#container") | |
.append("div") | |
.classed("svg-container", true) | |
.append("svg") | |
.attr("width", w) | |
.attr("height", h) | |
// .attr("viewBox", "0 0 " + w + " " + h) | |
.attr("id", "vis"); | |
//Create group elements to layer the svg | |
//This is an easy way to make sure things you want on top are on top, and things you want behind stay behind | |
var layer1 = svg.append('g'); | |
var layer2 = svg.append('g'); | |
//Create line function to plot the data | |
var line = d3.line() | |
.x(function(d) { return xScale(d[0]);}) | |
.y(function(d) { return yScale(d[1]);}); | |
//Define axes | |
//var xAxis = d3.axisBottom() | |
// .scale(xScale) | |
// .ticks(5); | |
//var yAxis = d3.axisLeft() | |
// .scale(yScale) | |
// .ticks(4); | |
//Create axes | |
//svg.append("g") | |
// .attr("class", "axis") | |
// .attr("transform", "translate(0," + (h - padding) + ")") | |
// .call(xAxis); | |
//svg.append("g") | |
// .attr("class", "axis") | |
// .attr("transform", "translate(" + padding + ",0)") | |
// .call(yAxis); | |
function createPolygons(numDataPoints) { | |
//This will hold the end ponits of the circle in polar coordinates | |
var inner_data = []; | |
var outer_data = []; | |
console.log(inner_data); | |
for (var i = 0; i <= (numDataPoints); i++) { | |
//Partition [0,2Pi] into buckets | |
var theta = ((i*2*Math.PI)/(numDataPoints)) + ((Math.PI)/(2)); | |
//Initialize the input as random numbers. This will iterate over time, so it doesn't matter what it holds | |
var inner_r = 1; | |
var outer_r = (1/Math.cos(Math.PI/numDataPoints)); | |
var inner_x = inner_r * Math.cos(theta); | |
var inner_y = inner_r * Math.sin(theta); | |
var outer_x = outer_r * Math.cos(theta); | |
var outer_y = outer_r * Math.sin(theta); | |
inner_data.push([inner_x, inner_y]); | |
outer_data.push([outer_x, outer_y]); | |
} | |
var inner_line = layer2.selectAll(".inner") | |
.data(inner_data, function(d){ return numDataPoints;}); | |
inner_line | |
.attr("class", "hide"); | |
inner_line | |
.enter() | |
.append("path") | |
.datum(inner_data) | |
.attr("d", line) | |
.attr("class", "inner"); | |
inner_line.exit().remove(); | |
var outer_line = layer2.selectAll(".outer") | |
.data(inner_data, function(d){ return numDataPoints;}); | |
outer_line | |
.attr("class", "hide"); | |
outer_line | |
.enter() | |
.append("path") | |
.datum(outer_data) | |
.attr("d", line) | |
.attr("class", "outer"); | |
outer_line.exit().remove(); | |
var avg = layer1.selectAll(".avg") | |
.data([0]); | |
avg.text("Pi is approximately "+ ((numDataPoints * Math.sin(Math.PI / numDataPoints)) + (numDataPoints * Math.tan(Math.PI / numDataPoints)))/2); | |
avg.enter().append("text") | |
.attr("x", xScale(0)) | |
.attr("y", yScale(0)) | |
.text("Pi is approximately " + numDataPoints * Math.tan(Math.PI / numDataPoints)) | |
.attr("font-size", "12px") | |
.attr("text-anchor", "middle") | |
.attr("class", "avg"); | |
avg.exit().remove(); | |
var min = layer1.selectAll(".min") | |
.data([0]); | |
min.text("Lower "+ numDataPoints * Math.sin(Math.PI / numDataPoints)); | |
min.enter().append("text") | |
.attr("x", xScale(0)) | |
.attr("y", yScale(-.85)) | |
.text("Lower " + numDataPoints * Math.tan(Math.PI / numDataPoints)) | |
.attr("font-size", "12px") | |
.attr("text-anchor", "middle") | |
.attr("class", "min"); | |
min.exit().remove(); | |
var max = layer1.selectAll(".max") | |
.data([0]); | |
max.text("Upper "+ numDataPoints * Math.tan(Math.PI / numDataPoints)); | |
max.enter().append("text") | |
.attr("x", xScale(0)) | |
.attr("y", yScale(1.15)) | |
.text("Upper " + numDataPoints * Math.tan(Math.PI / numDataPoints)) | |
.attr("font-size", "12px") | |
.attr("text-anchor", "middle") | |
.attr("class", "max"); | |
max.exit().remove(); | |
var numSides = layer1.selectAll(".sides") | |
.data([0]); | |
numSides.text(numDataPoints + " Sides"); | |
numSides.enter().append("text") | |
.attr("x", xScale(-1.5)) | |
.attr("y", yScale(1.5)) | |
.text(numDataPoints + " Sides") | |
.attr("font-size", "12px") | |
// .attr("text-anchor", "middle") | |
.attr("class", "sides"); | |
numSides.exit().remove(); | |
} | |
var circle = layer1.selectAll("circle") | |
.data([0]) | |
.enter() | |
.append("circle") | |
.attr("cx", xScale(0)) | |
.attr("cy", yScale(0)) | |
.attr("r", xScale(1) - xScale(0)) | |
.attr("stroke", "steelblue") | |
.attr("stroke-width", "1.5px") | |
.attr("fill", "none"); | |
createPolygons(3); | |
d3.select("body") | |
.on("click", function(){ | |
numDataPoints++; | |
createPolygons(numDataPoints); | |
}); | |
d3.select("body") | |
.on("touchstart", function(){ | |
numDataPoints++; | |
createPolygons(numDataPoints); | |
}); | |
</script> | |
</div> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment