A generalization of d3.geoCircle
with a parametric curve generator:
d3.geoCircle() == d3.geoShape().generator(t => [Math.cos(t), Math.sin(t)])
TODO: add a .rotate()
method, based on:
// rotation
var r = angle * Math.PI/180,
c = Math.cos(r),
s = Math.sin(r);
return [x * c - y * s, y * c + x * s];
```
See the code at [github:Fil/d3-geo/geoShape](https://github.com/Fil/d3-geo/commit/cd6ad7a916ed99d5f74bd6004cd9ad66a67a6266)
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="geoshape.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<script>
// Feel free to change or delete any of the code you see in this editor!
const svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500)
const projection = d3.geoConicEqualArea(),
path = d3.geoPath(projection);
var parametricShapes = [
t => [Math.cos(t), Math.sin(t)*Math.cos(t)],
t => [Math.cos(t), Math.sin(t)],
t => [Math.sin(t+0.1), Math.sin(t)],
t => [Math.round(Math.cos(t)), Math.sin(t)],
t => {let a = 0.95 + 0.1*Math.random(); return [a*Math.cos(t), a*Math.sin(t)]},
t => {
let x = Math.cos(t), y = Math.sin(t);
let mx = 0.85, my = 0.7;
x = Math.max(x,-mx)
x = Math.min(x,mx)
y = Math.max(y,-my)
y = Math.min(y,my)
return [x,y];
}
]
svg.append("path")
.datum({type: "Sphere"})
.attr('d', path)
.attr('fill', 'none')
.attr('stroke', '#444');
shapes = svg.append('g')
.selectAll("path")
.data(parametricShapes)
.enter()
.append('path')
.attr('fill', (_,i) => d3.schemeCategory10[i])
.attr('fill-opacity', 0.3)
.attr('stroke', '#444');
d3.interval(function(){
shapes
.transition()
.attr('d', d => {
let r = d3.geoShape().generator(d)
.radius(30 + 30 * Math.random())
.center([360*Math.random(),90*(Math.random()*Math.random()-Math.random()*Math.random())])
.precision(1);
return path(r())
});
}, 800)
</script>
</body>
https://d3js.org/d3.v4.min.js