Skip to content

Instantly share code, notes, and snippets.

@mbostock
Forked from mbostock/.block
Last active February 9, 2016 01:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mbostock/2962888 to your computer and use it in GitHub Desktop.
Save mbostock/2962888 to your computer and use it in GitHub Desktop.
Rectilinear Grid
license: gpl-3.0

The above grid shows the effect of rectilinear distortion. Move the mouse to change the focal point. I wouldn't recommend this technique; see my post on fisheye distortion for a better example of Cartesian distortion.

(function() {
d3.fisheye = function() {
var radius = 200,
power = 2,
k0,
k1,
center = [0, 0];
function fisheye(d) {
var x = d[0] - center[0],
y = d[1] - center[1],
dx = Math.abs(x),
dy = Math.abs(y),
kx = !x || dx >= radius ? 1 : k0 * (1 - Math.exp(-dx * k1)) / dx * .75 + .25,
ky = !y || dy >= radius ? 1 : k0 * (1 - Math.exp(-dy * k1)) / dy * .75 + .25;
return [center[0] + x * kx, center[1] + y * ky];
}
function rescale() {
k0 = Math.exp(power);
k0 = k0 / (k0 - 1) * radius;
k1 = power / radius;
return fisheye;
}
fisheye.radius = function(_) {
if (!arguments.length) return radius;
radius = +_;
return rescale();
};
fisheye.power = function(_) {
if (!arguments.length) return power;
power = +_;
return rescale();
};
fisheye.center = function(_) {
if (!arguments.length) return center;
center = _;
return fisheye;
};
return rescale();
};
})();
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.background {
fill: none;
pointer-events: all;
}
path {
fill: none;
stroke: #333;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="fisheye.js"></script>
<script>
var width = 960,
height = 500,
xStepsBig = d3.range(10, width, 20),
yStepsBig = d3.range(10, height, 20),
xStepsSmall = d3.range(0, width + 6, 6),
yStepsSmall = d3.range(0, height + 6, 6);
var fisheye = d3.fisheye().power(3);
var line = d3.svg.line();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(-.5,-.5)");
svg.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height);
svg.selectAll(".x")
.data(xStepsBig)
.enter().append("path")
.attr("class", "x")
.datum(function(x) { return yStepsSmall.map(function(y) { return [x, y]; }); });
svg.selectAll(".y")
.data(yStepsBig)
.enter().append("path")
.attr("class", "y")
.datum(function(y) { return xStepsSmall.map(function(x) { return [x, y]; }); });
var path = svg.selectAll("path")
.attr("d", line);
svg.on("mousemove", function() {
fisheye.center(d3.mouse(this));
path.attr("d", function(d) { return line(d.map(fisheye)); });
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment