Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active November 30, 2018 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save HarryStevens/9d2714bc1bf022e68afd05c78a09a9ee to your computer and use it in GitHub Desktop.
Save HarryStevens/9d2714bc1bf022e68afd05c78a09a9ee to your computer and use it in GitHub Desktop.
Cartesian Points In A Circle
license: gpl-3.0
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
body {
margin: 0 auto;
display: table;
}
text {
text-anchor: middle;
font-family: "Helvetica Neue", sans-serif;
}
.outline {
fill: none;
stroke: black;
stroke-width: 2px;
}
.center {
fill: tomato;
}
.circle {
stroke-width: 2px;
fill: none;
}
.line {
stroke-width: 2px;
}
</style>
</head>
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="https://unpkg.com/geometric@0.0.6/build/geometric.js"></script>
<script>
var radius,
margin = 2,
dot_radius = 3,
center_radius = 30,
circles_data = [];
var svg = d3.select("body").append("svg");
var g = svg.append("g")
.attr("transform", "translate(" + margin + ", " + margin + ")");
var outline = g.append("circle")
.attr("class", "outline");
var center = g.append("circle")
.attr("class", "center")
.attr("r", center_radius);
var text = g.append("text").attr("dy", 5);
window.onload = _ => {
resize();
makeNewCircle();
redraw();
d3.interval(_ => {
makeNewCircle();
redraw();
}, 500);
window.onresize = resize;
};
function resize(){
radius = Math.min(window.innerWidth, window.innerHeight) - margin * 2;
d3.select("div").style("left", (window.innerWidth / 2) + "px").style("top", (radius / 2) + "px");
text.attr("x", radius / 2).attr("y", radius / 2)
svg.attr("width", radius + margin * 2).attr("height", radius + margin * 2);
outline
.attr("r", radius / 2)
.attr("cx", radius / 2)
.attr("cy", radius / 2);
center
.attr("cx", radius / 2)
.attr("cy", radius / 2);
// Recalculate current points based on new radius.
circles_data.forEach(d => {
d.coordinates = geometric.translateDegrees([radius / 2, radius / 2], d.angle, d.distance_pct * radius / 200);
return d;
});
redraw();
}
function redraw(){
var circles = g.selectAll(".circle")
.data(circles_data, d => d.id);
var lines = g.selectAll(".line")
.data(circles_data, d => d.id);
var dots = g.selectAll(".dot")
.data(circles_data, d => d.id);
circles
.attr("cx", radius / 2)
.attr("cy", radius / 2)
.attr("r", d => radius * d.distance_pct / 200)
.transition()
.style("stroke", "#ccc")
.style("opacity", .1);
lines
.attr("x1", radius / 2)
.attr("y1", radius / 2)
.attr("x2", d => d.coordinates[0])
.attr("y2", d => d.coordinates[1])
.transition()
.style("opacity", .1);
dots
.attr("cx", d => d.coordinates[0])
.attr("cy", d => d.coordinates[1])
.transition()
.style("opacity", .8);
circles.enter().append("circle")
.attr("class", "circle")
.attr("r", d => radius * d.distance_pct / 200)
.attr("cx", radius / 2)
.attr("cy", radius / 2)
.style("stroke", "steelblue")
.style("opacity", 1e-6)
.transition()
.duration(250)
.style("opacity", 1);
lines.enter().append("line")
.attr("class", "line")
.attr("x1", radius / 2)
.attr("y1", radius / 2)
.attr("x2", radius / 2)
.attr("y2", radius / 2)
.style("stroke", "steelblue")
.transition()
.delay(125)
.duration(250)
.attr("x2", d => d.coordinates[0])
.attr("y2", d => d.coordinates[1]);
dots.enter().append("circle")
.attr("class", "dot")
.attr("r", dot_radius)
.attr("cx", d => d.coordinates[0])
.attr("cy", d => d.coordinates[1])
.attr("opacity", 1e-6)
.transition()
.delay(250)
.duration(500)
.attr("opacity", 1);
center.raise();
text.raise();
}
function makeNewCircle(distance, angle){
var new_obj = {
distance_pct: Math.max((center_radius + dot_radius * 2) / radius * 100, randomPercent()),
angle: randomAngle(),
id: circles_data.length
};
text.text(new_obj.angle);
new_obj.coordinates = geometric.translateDegrees([radius / 2, radius / 2], new_obj.angle, new_obj.distance_pct * radius / 200)
circles_data.push(new_obj);
}
function randomPercent(){
return randomBetween(0, 100);
}
function randomAngle(){
return randomBetween(0, 360);
}
function randomBetween(min, max){
return Math.floor(Math.random() * (max - min + 1) + min);
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment