Create a gist now

Instantly share code, notes, and snippets.

@mbostock /.block
Last active Jul 11, 2018

Embed
What would you like to do?
Epicyclic Gearing
license: gpl-3.0

From Wikipedia:

Epicyclic gearing or planetary gearing is a gear system consisting of one or more outer gears, or planet gears, revolving about a central, or sun gear. … Epicyclic gearing systems also incorporate the use of an outer ring gear or annulus, which meshes with the planet gears.

Use the menu in the top-left to change the frame of reference, fixing the specified gear in-place.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
form {
position: absolute;
top: 1em;
left: 1em;
}
path {
fill-rule: evenodd;
stroke: #333;
stroke-width: 2px;
}
.sun path {
fill: #6baed6;
}
.planet path {
fill: #9ecae1;
}
.annulus path {
fill: #c6dbef;
}
</style>
<form>
<input type="radio" name="reference" id="ref-annulus">
<label for="ref-annulus">Annulus</label><br>
<input type="radio" name="reference" id="ref-planet" checked>
<label for="ref-planet">Planets</label><br>
<input type="radio" name="reference" id="ref-sun">
<label for="ref-sun">Sun</label>
</form>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var width = 960,
height = 500,
radius = 80,
x = Math.sin(2 * Math.PI / 3),
y = Math.cos(2 * Math.PI / 3);
var offset = 0,
speed = 4,
start = Date.now();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(.55)")
.append("g");
var frame = svg.append("g")
.datum({radius: Infinity});
frame.append("g")
.attr("class", "annulus")
.datum({teeth: 80, radius: -radius * 5, annulus: true})
.append("path")
.attr("d", gear);
frame.append("g")
.attr("class", "sun")
.datum({teeth: 16, radius: radius})
.append("path")
.attr("d", gear);
frame.append("g")
.attr("class", "planet")
.attr("transform", "translate(0,-" + radius * 3 + ")")
.datum({teeth: 32, radius: -radius * 2})
.append("path")
.attr("d", gear);
frame.append("g")
.attr("class", "planet")
.attr("transform", "translate(" + -radius * 3 * x + "," + -radius * 3 * y + ")")
.datum({teeth: 32, radius: -radius * 2})
.append("path")
.attr("d", gear);
frame.append("g")
.attr("class", "planet")
.attr("transform", "translate(" + radius * 3 * x + "," + -radius * 3 * y + ")")
.datum({teeth: 32, radius: -radius * 2})
.append("path")
.attr("d", gear);
d3.selectAll("input[name=reference]")
.data([radius * 5, Infinity, -radius])
.on("change", function(radius1) {
var radius0 = frame.datum().radius, angle = (Date.now() - start) * speed;
frame.datum({radius: radius1});
svg.attr("transform", "rotate(" + (offset += angle / radius0 - angle / radius1) + ")");
});
d3.selectAll("input[name=speed]")
.on("change", function() { speed = +this.value; });
function gear(d) {
var n = d.teeth,
r2 = Math.abs(d.radius),
r0 = r2 - 8,
r1 = r2 + 8,
r3 = d.annulus ? (r3 = r0, r0 = r1, r1 = r3, r2 + 20) : 20,
da = Math.PI / n,
a0 = -Math.PI / 2 + (d.annulus ? Math.PI / n : 0),
i = -1,
path = ["M", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)];
while (++i < n) path.push(
"A", r0, ",", r0, " 0 0,1 ", r0 * Math.cos(a0 += da), ",", r0 * Math.sin(a0),
"L", r2 * Math.cos(a0), ",", r2 * Math.sin(a0),
"L", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
"A", r1, ",", r1, " 0 0,1 ", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
"L", r2 * Math.cos(a0 += da / 3), ",", r2 * Math.sin(a0),
"L", r0 * Math.cos(a0), ",", r0 * Math.sin(a0));
path.push("M0,", -r3, "A", r3, ",", r3, " 0 0,0 0,", r3, "A", r3, ",", r3, " 0 0,0 0,", -r3, "Z");
return path.join("");
}
d3.timer(function() {
var angle = (Date.now() - start) * speed,
transform = function(d) { return "rotate(" + angle / d.radius + ")"; };
frame.selectAll("path").attr("transform", transform);
frame.attr("transform", transform); // frame of reference
});
</script>
@Pomax

This comment has been minimized.

Show comment
Hide comment
@Pomax

Pomax Sep 28, 2013

basedon the wiki quote, the sun and annulus radio buttons need their labels exchanged =)

Pomax commented Sep 28, 2013

basedon the wiki quote, the sun and annulus radio buttons need their labels exchanged =)

@alvineadel

This comment has been minimized.

Show comment
Hide comment
@alvineadel

alvineadel Dec 5, 2013

This example is amazing indeed! :)

alvineadel commented Dec 5, 2013

This example is amazing indeed! :)

@Manjulajntuk

This comment has been minimized.

Show comment
Hide comment
@Manjulajntuk

Manjulajntuk Aug 25, 2016

Hello sir i want to perform intersection with two geojson files with draw tool. I have tried with by using example https://bl.ocks.org/pgiraud/2ed05b0a9e394c5652b3. By using it i can able to perform intersection to one geojson with draw tool. Now my intension is to perform intersection to the two geojson files and then find intersection of the one geojson with other geojson, i have tried with the code like below for reference sir.

<title>Select features example</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.10.1/ol-debug.js"></script> <script src="ol.js"></script> <script src="jsts_geom_Polygon.js"></script> <script src="https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages/lib/0.16.0/javascript.util.min.js"></script> <script src="https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages/lib/0.16.0/jsts.min.js"></script> <script src="jsts_io_GeoJSONParser.js"></script> <style> html, body { padding: 0; margin: 0; } html, body, .map { height: 100%; width: 100%; } </style>

<script> var geojsonFormat = new ol.format.GeoJSON(); var style = new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.3)' }), stroke: new ol.style.Stroke({ color: 'rgba(255, 120, 0, 0.6)', width: 1 }) }); var styles = [style]; var highlightStyle = [ new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255, 120, 0, 0.3)' }), stroke: new ol.style.Stroke({ color: 'rgba(255, 120, 0, 0.6)', width: 1 }) }) ]; var vector3 = new ol.layer.Vector({ maxResolution: 0.8, source: new ol.source.Vector({ url: 'ap_taluk.geojson', format: new ol.format.GeoJSON({ defaultDataProjection:'EPSG:4326' }) }), style: styles }); var vector2 = new ol.layer.Vector({ maxResolution: 0.8, source: new ol.source.Vector({ url: 'flood.geojson', format: new ol.format.GeoJSON({ defaultDataProjection:'EPSG:4326' }) }), style: styles }); var layer1 = new ol.layer.Tile({ title: 'India', source: new ol.source.TileWMS({ url: '', params: {LAYERS: ''} }), transparent: false }); var dist = new ol.layer.Tile({ title: 'flood', source: new ol.source.TileWMS({ url: '', params: {LAYERS: ''} }) }); var distaluk = new ol.layer.Tile({ title: 'taluk', source: new ol.source.TileWMS({ url: '', params: {LAYERS: ''} }) }); intersectionLayer = new ol.layer.Vector({ source: new ol.source.Vector() }); var map = new ol.Map({ layers: [layer1,vector2,vector3,intersectionLayer,distaluk], target: 'map', view: new ol.View({ projection: 'EPSG:4326', center: [79.419,15.428], zoom: 8 }) }); var draw_inter = new ol.interaction.Draw({ type: 'Polygon' }); map.addInteraction(draw_inter); draw_inter.on('drawstart', function(evt) { intersectionLayer.getSource().clear(); }); var olParser = new jsts.io.olParser(); var geojsonParser = new jsts.io.GeoJSONParser(); draw_inter.on('drawend', function(evt) { var poly1 = olParser.read(evt.feature.getGeometry()); var extent1 = evt.feature.getGeometry().getExtent(); var source = vector2.getSource(); var source2 = vector3.getSource(); //var source4 = vector4.getSource(); var features = source.getFeatures(); var features2 = source2.getFeatures(); // var features4 = source4.getFeatures(); features.forEach(function(feature) { if (!ol.extent.intersects(extent1, feature.getGeometry().getExtent())) { return; } var poly2 = olParser.read(feature.getGeometry()); var intersection = poly1.intersection(poly2); //alert(intersection); intersection = geojsonParser.write(intersection); if(intersection.type === 'GeometryCollection' && intersection.geometries.length === 0) { return; } else { intersectionLayer.getSource().addFeature(geojsonFormat.readFeature({ type: 'Feature', properties: {}, geometry: intersection })); //alert("flood"+feature.get('geometry')); } }); features2.forEach(function(feature) { if (!ol.extent.intersects(extent1, feature.getGeometry().getExtent())) { return; } var poly3 = olParser.read(feature.getGeometry()); var intersection = poly1.intersection(poly3); //alert(intersection); intersection = geojsonParser.write(intersection); if(intersection.type === 'GeometryCollection' && intersection.geometries.length === 0) { return; } else { alert("village"+feature.get('taluk')); /*intersectionLayer.getSource().addFeature(geojsonFormat.readFeature({ type: 'Feature', properties: {}, geometry: intersection })); /*layersize = intersectionLayer.getSource().getFeatures().length; alert(" size"+layersize); for(i=0;i 10000) { output = (Math.round(totalarea / 1000000 * 100) / 100) + ' ' + 'km2'; } else { output = (Math.round(totalarea * 100) / 100) + ' ' + 'm2'; } alert(output); }); </script>

Manjulajntuk commented Aug 25, 2016

Hello sir i want to perform intersection with two geojson files with draw tool. I have tried with by using example https://bl.ocks.org/pgiraud/2ed05b0a9e394c5652b3. By using it i can able to perform intersection to one geojson with draw tool. Now my intension is to perform intersection to the two geojson files and then find intersection of the one geojson with other geojson, i have tried with the code like below for reference sir.

<title>Select features example</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/ol3/3.10.1/ol-debug.js"></script> <script src="ol.js"></script> <script src="jsts_geom_Polygon.js"></script> <script src="https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages/lib/0.16.0/javascript.util.min.js"></script> <script src="https://cdn.rawgit.com/bjornharrtell/jsts/gh-pages/lib/0.16.0/jsts.min.js"></script> <script src="jsts_io_GeoJSONParser.js"></script> <style> html, body { padding: 0; margin: 0; } html, body, .map { height: 100%; width: 100%; } </style>

<script> var geojsonFormat = new ol.format.GeoJSON(); var style = new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.3)' }), stroke: new ol.style.Stroke({ color: 'rgba(255, 120, 0, 0.6)', width: 1 }) }); var styles = [style]; var highlightStyle = [ new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255, 120, 0, 0.3)' }), stroke: new ol.style.Stroke({ color: 'rgba(255, 120, 0, 0.6)', width: 1 }) }) ]; var vector3 = new ol.layer.Vector({ maxResolution: 0.8, source: new ol.source.Vector({ url: 'ap_taluk.geojson', format: new ol.format.GeoJSON({ defaultDataProjection:'EPSG:4326' }) }), style: styles }); var vector2 = new ol.layer.Vector({ maxResolution: 0.8, source: new ol.source.Vector({ url: 'flood.geojson', format: new ol.format.GeoJSON({ defaultDataProjection:'EPSG:4326' }) }), style: styles }); var layer1 = new ol.layer.Tile({ title: 'India', source: new ol.source.TileWMS({ url: '', params: {LAYERS: ''} }), transparent: false }); var dist = new ol.layer.Tile({ title: 'flood', source: new ol.source.TileWMS({ url: '', params: {LAYERS: ''} }) }); var distaluk = new ol.layer.Tile({ title: 'taluk', source: new ol.source.TileWMS({ url: '', params: {LAYERS: ''} }) }); intersectionLayer = new ol.layer.Vector({ source: new ol.source.Vector() }); var map = new ol.Map({ layers: [layer1,vector2,vector3,intersectionLayer,distaluk], target: 'map', view: new ol.View({ projection: 'EPSG:4326', center: [79.419,15.428], zoom: 8 }) }); var draw_inter = new ol.interaction.Draw({ type: 'Polygon' }); map.addInteraction(draw_inter); draw_inter.on('drawstart', function(evt) { intersectionLayer.getSource().clear(); }); var olParser = new jsts.io.olParser(); var geojsonParser = new jsts.io.GeoJSONParser(); draw_inter.on('drawend', function(evt) { var poly1 = olParser.read(evt.feature.getGeometry()); var extent1 = evt.feature.getGeometry().getExtent(); var source = vector2.getSource(); var source2 = vector3.getSource(); //var source4 = vector4.getSource(); var features = source.getFeatures(); var features2 = source2.getFeatures(); // var features4 = source4.getFeatures(); features.forEach(function(feature) { if (!ol.extent.intersects(extent1, feature.getGeometry().getExtent())) { return; } var poly2 = olParser.read(feature.getGeometry()); var intersection = poly1.intersection(poly2); //alert(intersection); intersection = geojsonParser.write(intersection); if(intersection.type === 'GeometryCollection' && intersection.geometries.length === 0) { return; } else { intersectionLayer.getSource().addFeature(geojsonFormat.readFeature({ type: 'Feature', properties: {}, geometry: intersection })); //alert("flood"+feature.get('geometry')); } }); features2.forEach(function(feature) { if (!ol.extent.intersects(extent1, feature.getGeometry().getExtent())) { return; } var poly3 = olParser.read(feature.getGeometry()); var intersection = poly1.intersection(poly3); //alert(intersection); intersection = geojsonParser.write(intersection); if(intersection.type === 'GeometryCollection' && intersection.geometries.length === 0) { return; } else { alert("village"+feature.get('taluk')); /*intersectionLayer.getSource().addFeature(geojsonFormat.readFeature({ type: 'Feature', properties: {}, geometry: intersection })); /*layersize = intersectionLayer.getSource().getFeatures().length; alert(" size"+layersize); for(i=0;i 10000) { output = (Math.round(totalarea / 1000000 * 100) / 100) + ' ' + 'km2'; } else { output = (Math.round(totalarea * 100) / 100) + ' ' + 'm2'; } alert(output); }); </script>
@Kyeongan

This comment has been minimized.

Show comment
Hide comment
@Kyeongan

Kyeongan commented Sep 2, 2016

Amazing!

@Tracy2014

This comment has been minimized.

Show comment
Hide comment
@Tracy2014

Tracy2014 Oct 21, 2016

Hi, this question is actually relates to the D3 graph stated here http://bl.ocks.org/mbostock/7607535. I'm very interested in using this graph. However, could you suggest a bit on how to include "hover" behaviour for every node (include parent and children nodes) please?

Tracy2014 commented Oct 21, 2016

Hi, this question is actually relates to the D3 graph stated here http://bl.ocks.org/mbostock/7607535. I'm very interested in using this graph. However, could you suggest a bit on how to include "hover" behaviour for every node (include parent and children nodes) please?

@xmyLydia

This comment has been minimized.

Show comment
Hide comment
@xmyLydia

xmyLydia Apr 19, 2017

Does anyone has the data called 'airport.csv' and 'flights.csv' because in the example :https://bl.ocks.org/mbostock/7608400 , these two files are used but there is no source, I want to figure out the format of these files and use my own data to replace them.

xmyLydia commented Apr 19, 2017

Does anyone has the data called 'airport.csv' and 'flights.csv' because in the example :https://bl.ocks.org/mbostock/7608400 , these two files are used but there is no source, I want to figure out the format of these files and use my own data to replace them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment