|
(function() { |
|
var _symbol = d3.svg.symbol(), |
|
_line = d3.svg.line(); |
|
|
|
d3.superformula = function() { |
|
var type = _symbol.type(), |
|
size = _symbol.size(), |
|
segments = size, |
|
params = {}; |
|
|
|
function superformula(d, i) { |
|
var n, p = _superformulaTypes[type.call(this, d, i)]; |
|
for (n in params) p[n] = params[n].call(this, d, i); |
|
return _superformulaPath(p, segments.call(this, d, i), Math.sqrt(size.call(this, d, i))); |
|
} |
|
|
|
superformula.type = function(x) { |
|
if (!arguments.length) return type; |
|
type = d3.functor(x); |
|
return superformula; |
|
}; |
|
|
|
superformula.param = function(name, value) { |
|
if (arguments.length < 2) return params[name]; |
|
params[name] = d3.functor(value); |
|
return superformula; |
|
}; |
|
|
|
// size of superformula in square pixels |
|
superformula.size = function(x) { |
|
if (!arguments.length) return size; |
|
size = d3.functor(x); |
|
return superformula; |
|
}; |
|
|
|
// number of discrete line segments |
|
superformula.segments = function(x) { |
|
if (!arguments.length) return segments; |
|
segments = d3.functor(x); |
|
return superformula; |
|
}; |
|
|
|
return superformula; |
|
}; |
|
|
|
function _superformulaPath(params, n, diameter) { |
|
var i = -1, |
|
dt = 2 * Math.PI / n, |
|
t, |
|
r = 0, |
|
x, |
|
y, |
|
points = []; |
|
|
|
while (++i < n) { |
|
t = params.m * (i * dt - Math.PI) / 4; |
|
t = Math.pow(Math.abs(Math.pow(Math.abs(Math.cos(t) / params.a), params.n2) |
|
+ Math.pow(Math.abs(Math.sin(t) / params.b), params.n3)), -1 / params.n1); |
|
if (t > r) r = t; |
|
points.push(t); |
|
} |
|
|
|
r = diameter * Math.SQRT1_2 / r; |
|
i = -1; while (++i < n) { |
|
x = (t = points[i] * r) * Math.cos(i * dt); |
|
y = t * Math.sin(i * dt); |
|
points[i] = [Math.abs(x) < 1e-6 ? 0 : x, Math.abs(y) < 1e-6 ? 0 : y]; |
|
} |
|
|
|
return _line(points) + "Z"; |
|
} |
|
|
|
var _superformulaTypes = { |
|
asterisk: {m: 12, n1: .3, n2: 0, n3: 10, a: 1, b: 1}, |
|
bean: {m: 2, n1: 1, n2: 4, n3: 8, a: 1, b: 1}, |
|
butterfly: {m: 3, n1: 1, n2: 6, n3: 2, a: .6, b: 1}, |
|
circle: {m: 4, n1: 2, n2: 2, n3: 2, a: 1, b: 1}, |
|
clover: {m: 6, n1: .3, n2: 0, n3: 10, a: 1, b: 1}, |
|
cloverFour: {m: 8, n1: 10, n2: -1, n3: -8, a: 1, b: 1}, |
|
cross: {m: 8, n1: 1.3, n2: .01, n3: 8, a: 1, b: 1}, |
|
diamond: {m: 4, n1: 1, n2: 1, n3: 1, a: 1, b: 1}, |
|
drop: {m: 1, n1: .5, n2: .5, n3: .5, a: 1, b: 1}, |
|
ellipse: {m: 4, n1: 2, n2: 2, n3: 2, a: 9, b: 6}, |
|
gear: {m: 19, n1: 100, n2: 50, n3: 50, a: 1, b: 1}, |
|
heart: {m: 1, n1: .8, n2: 1, n3: -8, a: 1, b: .18}, |
|
heptagon: {m: 7, n1: 1000, n2: 400, n3: 400, a: 1, b: 1}, |
|
hexagon: {m: 6, n1: 1000, n2: 400, n3: 400, a: 1, b: 1}, |
|
malteseCross: {m: 8, n1: .9, n2: .1, n3: 100, a: 1, b: 1}, |
|
pentagon: {m: 5, n1: 1000, n2: 600, n3: 600, a: 1, b: 1}, |
|
rectangle: {m: 4, n1: 100, n2: 100, n3: 100, a: 2, b: 1}, |
|
roundedStar: {m: 5, n1: 2, n2: 7, n3: 7, a: 1, b: 1}, |
|
square: {m: 4, n1: 100, n2: 100, n3: 100, a: 1, b: 1}, |
|
star: {m: 5, n1: 30, n2: 100, n3: 100, a: 1, b: 1}, |
|
triangle: {m: 3, n1: 100, n2: 200, n3: 200, a: 1, b: 1} |
|
}; |
|
|
|
d3.superformulaTypes = d3.keys(_superformulaTypes); |
|
})(); |