|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
|
|
.frame { |
|
fill: none; |
|
stroke: #000; |
|
} |
|
|
|
.axis text { |
|
font: 10px sans-serif; |
|
} |
|
|
|
#params { |
|
font:35px "Helvetica Neue"; |
|
} |
|
.axis line, |
|
.axis circle { |
|
fill: none; |
|
stroke: #777; |
|
stroke-dasharray: 1,4; |
|
} |
|
|
|
.axis :last-of-type circle { |
|
stroke: #333; |
|
stroke-dasharray: none; |
|
} |
|
|
|
.line { |
|
fill: none; |
|
stroke: red; |
|
stroke-width: 1.5px; |
|
} |
|
input { |
|
vertical-align: middle; |
|
font:20px "Helvetica Neue"; |
|
} |
|
#sub { |
|
font:35px "Helvetica Neue"; |
|
} |
|
|
|
</style> |
|
<body> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<div id="params" style="position:absolute;"> |
|
<form name="main" onsubmit="return update()" action="" method="get"> |
|
N : <input id="na" size="1" type="number" min="0" max="10" value="5" step="1"> / |
|
<input id="nb" size="1" type="number" min="1" max="10" value="2" step="1"> |
|
<br> |
|
E : <input id="e" type="number" min="0" max="5" value="2.9" step="0.1"> |
|
<br> |
|
<input type="submit" id="sub" value="Redraw"> |
|
</form> |
|
<span style="font-size:25px">f(α) = (1+cos(nα))</span> |
|
</div> |
|
|
|
<script> |
|
|
|
d3.interpolators.push(function(a,b){ |
|
if (Array.isArray(a[0]) && Array.isArray(b[0])) { |
|
var x = [], |
|
c = [], |
|
na = a.length, |
|
nb = b.length, |
|
n0 = Math.min(a.length, b.length), |
|
i, |
|
delta = b.length - a.length, |
|
newSize; |
|
for (i=0; i < na; ++i) c[i] = b[i]; |
|
newSize; |
|
return function(t) { |
|
newSize = a.length + delta*t; |
|
//console.log(newSize,c.length,t,delta); |
|
if (newSize>c.length){ |
|
for (i=c.length;i<newSize;i++) c.push(b[i]); |
|
} |
|
return c; |
|
} |
|
} |
|
}); |
|
|
|
//http://www.mathcurve.com/courbes2d/conchoidderosace/conchoidderosace.shtmlv |
|
var n = 5/2 |
|
var factor = 2.9; |
|
|
|
var data = d3.range(-16*Math.PI, 16*Math.PI, .01).map(function(t) { |
|
return [t, (1+factor*Math.cos((n)*t))/(1+factor)]; |
|
}); |
|
var empty = d3.range(0, 2*Math.PI, .01).map(function(t) { |
|
return [0,0]; |
|
}); |
|
|
|
|
|
var margin = 30; |
|
// radius is the minimal dimension, minus the margin |
|
var width = 960, |
|
height = 500, |
|
radius = Math.min(width, height) / 2 - margin; |
|
|
|
|
|
var r = d3.scale.linear() |
|
.domain([0, 1]) |
|
.range([0, radius]); |
|
|
|
|
|
//default accessor [[x1,y1]] => radian and angle |
|
var line = d3.svg.line.radial() |
|
.radius(function(d){; return (r(d[1])); }) // will change between -1 and 1 |
|
.angle(function(d) { ;return d[0];}); |
|
|
|
|
|
var svg = d3.select("body").append("svg") |
|
.attr("width", width) |
|
.attr("height", height) |
|
.append("g") |
|
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")"); |
|
// radius axis |
|
// cheat with CSS |
|
var gr = svg.append("g") |
|
.attr("class", "r axis") |
|
.selectAll("g") |
|
.data(r.ticks(10).slice(0)) |
|
.enter().append("g"); |
|
|
|
gr.append("circle") |
|
.attr("r", function(d,i){console.log("=>",d,i,r(d));return r(d)}); |
|
|
|
gr.append("text") |
|
.attr("y", function(d) { return -r(d) - 4; }) |
|
.attr("transform", "rotate(50)") |
|
.style("text-anchor", "middle") |
|
.text(function(d) { return d; }); |
|
|
|
var ga = svg.append("g") |
|
.attr("class", "a axis") |
|
.selectAll("g") |
|
.data(d3.range(0, 360, 15)) |
|
.enter().append("g") |
|
.attr("transform", function(d) { return "rotate(" + (d-90) + ")"; }); |
|
|
|
ga.append("line") |
|
.attr("x2", radius); |
|
|
|
ga.append("text") |
|
.attr("x", radius + 6) |
|
.attr("dy", ".35em") |
|
.style("text-anchor", function(d) { return d < 270 && d > 90 ? "end" : null; }) |
|
.attr("transform", function(d) { return d < 270 && d > 90 ? "rotate(180 " + (radius + 6) + ",0)" : null; }) |
|
.text(function(d) { return d + "°"; }); |
|
// a bit cheating |
|
var path = |
|
svg.append("path") |
|
.datum(data) |
|
.attr("class", "line") |
|
.attr("d", line); |
|
var totalLength = path.node().getTotalLength(); |
|
|
|
path.transition().duration(1000).attrTween("d",function(d){ |
|
console.log(empty,d); |
|
var interpolate = d3.interpolate( [[0,0]],d); |
|
return function(t) { return line(interpolate(t))}; |
|
}) |
|
|
|
function update() { |
|
|
|
|
|
var nfa = parseFloat(document.getElementById("na").value); |
|
var nfb = parseFloat(document.getElementById("nb").value); |
|
var e = parseFloat(document.getElementById("e").value); |
|
console.log(nfa,nfb,e); |
|
var _n = nfa/nfb; |
|
var _factor = e; |
|
|
|
var _data = d3.range(-16*Math.PI, 16*Math.PI, .01).map(function(t) { |
|
return [t, ( 1+_factor*Math.cos((_n)*t))/(1+_factor)]; |
|
}); |
|
path.datum(_data).transition(2000).attr("d",line); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
</script> |
|
</body> |
|
|