Skip to content

Instantly share code, notes, and snippets.

@georules
Created April 20, 2014 03:42
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 georules/11104408 to your computer and use it in GitHub Desktop.
Save georules/11104408 to your computer and use it in GitHub Desktop.
unit circle
{"description":"unit circle","endpoint":"","display":"svg","public":true,"require":[],"fileconfigs":{"inlet.js":{"default":true,"vim":false,"emacs":false,"fontSize":12},"style.css":{"default":true,"vim":false,"emacs":false,"fontSize":12},"_.md":{"default":true,"vim":false,"emacs":false,"fontSize":12},"config.json":{"default":true,"vim":false,"emacs":false,"fontSize":12}},"fullscreen":false,"play":true,"loop":true,"restart":false,"autoinit":true,"pause":true,"loop_type":"period","bv":false,"nclones":15,"clone_opacity":0.4,"duration":3000,"ease":"linear","dt":0.01,"thumbnail":"http://i.imgur.com/8FrI9P1.gif","controls":{"Amplitude Top":100,"Frequency Top":1,"top":"sin","Amplitude Right":100,"Frequency Right":1,"right":"cos"},"ajax-caching":true}
//Trigonmetry
//sin = a * Math.sin( t * freq )
//cos = a * Math.cos( t * freq )
var svg = d3.select("svg");
svg.append("rect").attr({ width: "100%", height:"100%", fill: "#E7F8FF"})
console.log(tributary.__controls__);
var cx = tributary.sw/2;
var cy = tributary.sh/2;
var linewidth = tributary.sw / 2 + 100;
var samples = 215;
var xoffset = 0;
var yoffset = 0;
var particleAttr = {
fill: "#3BCA97",
"fill-opacity": 0.408,
stroke: "none",
r: 14
}
var unitAttr = {
fill: "#E98A8A",
"fill-opacity": 0.0264,
stroke: "#E78181",
"stroke-opacity": 0.68
}
var pathAttr = {
fill: "none",
stroke: "#000",
"stroke-width": 3,
"stroke-opacity": 0.3,
"stroke-linecap":"round"
}
var amplitude = +tributary.control({name: "Amplitude Top", min: 30, max: 200, step: 2 });
var frequency = Math.round(tributary.control({name: "Frequency Top", min: 1, max: 8, step: 1 }));
var fnTop = tributary.control({name: "top", options: ["sin", "cos", "tan"]});
var amplitude2 = +tributary.control({name: "Amplitude Right", min: 30, max: 200, step: 2 });
var frequency2 = Math.round(tributary.control({name: "Frequency Right", min: 1, max: 8, step: 1 }));
var fnRight = tributary.control({name: "right", options: ["cos","sin", "tan"]});;
fns = {
"sin": Math.sin,
"cos": Math.cos,
"tan": Math.tan
}
var eqns = [
{
a: amplitude,
fn: fns[fnTop],
freq: frequency
},
{
a: amplitude2,
fn: fns[fnRight],
freq: frequency2
}
];
tributary.duration = 5000;
var linescale = d3.scale.linear()
.domain([0, samples])
.range([0, linewidth]);
var waveline = d3.svg.line()
.x(function(d) {
return d.x;
})
.y(function(d) {
return d.y
})
//these 3 lines set stuff up using functions at the bottom
var sin = trig(eqns[0]);
var cos = trig(eqns[1]);
var line = lineFn();
//generate data for our circle using the functions
var ydata = sample(sin, {start: 0, end:2*Math.PI, n: samples});
var xdata = sample(cos, {start: 0, end: 2*Math.PI, n: samples});
var data = ydata.map(function(d,i) {
return {
x: xdata[i] + cx,
y: ydata[i] + cy
}
})
var cosdata = xSample(0);
var sindata = ySample(0);
//draw unit "circle"
var circle = svg.append("path")
.datum(data)
.attr("d", line)
.attr(unitAttr)
.classed("unit", true)
//make a particle that traces out the unit circle
var particle = svg.append("circle")
.attr(particleAttr)
.classed("particle", true)
//x particle
var xparticle = svg.append("circle")
.attr(particleAttr)
.classed("particle", true)
.classed("xparticle", true)
//y particle
var yparticle = svg.append("circle")
.attr(particleAttr)
.classed("particle", true)
.classed("yparticle", true)
var cosline = svg.append("path")
.datum(cosdata)
.attr("d", waveline)
.attr(pathAttr)
.classed("line", true)
var sinline = svg.append("path")
.datum(sindata)
.attr("d", waveline)
.attr(pathAttr)
.classed("line", true)
//move the particle around the unit circle
tributary.run = function(g, t) {
var theta = (t + 0.0001) * 2 * Math.PI;
particle.attr({
cx: cos(theta) + cx,
cy: sin(theta) + cy
})
xparticle.attr({
cx: cos(theta) + cx,
cy: cy - eqns[0].a + yoffset
})
yparticle.attr({
cx: cx + eqns[1].a + xoffset,
cy: sin(theta) + cy
})
cosdata = xSample(theta);
cosline.datum(cosdata)
.attr("d", waveline)
sindata = ySample(theta);
sinline.datum(sindata)
.attr("d", waveline)
}
function xSample(t) {
return sample(cos, {start: t+2*Math.PI, end: t, n: samples})
.map(function(d,i) {
return {
x: d + cx,
y: -linescale(i) + cy + yoffset - eqns[0].a
}
})
}
function ySample(t) {
return sample(sin, {start: t+2*Math.PI, end: t, n: samples})
.map(function(d,i) {
return {
x: linescale(i) + cx + xoffset + eqns[1].a,
y: d + cy
}
})
}
//opts = {
// start: x0, start of x domain
// end: x1, start of y domain
// n: number of samples
//}
function sample(y, opts) {
if(!opts) opts = {};
var start = opts.start || 0;
var end = opts.end || 1;
var n = opts.n || 50;
var step = (end - start) / n;
var data = d3.range(n);
return data.map(function(i) {
return y(start + i * step)
})
}
//build a trig function from an object
function trig(eqn) {
var fn = function(t) {
return eqn.a * eqn.fn(t * eqn.freq)
}
return fn;
}
//generate line fn
function lineFn() {
var line = d3.svg.line()
.x(function(d,i) {
return d.x;
})
.y(function(d,i) {
return d.y;
})
.interpolate("linear-closed")
return line
}
path.line {
fill: none;
stroke: #000;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment