From c8fb681b6fca571d27ae787ee3d03cc94d833dad Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 1 May 2016 12:43:03 -0400 Subject: [PATCH] change file mode. --- d3/drag6/fx.js | 109 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 108 insertions(+), 1 deletion(-) mode change 120000 => 100644 d3/drag6/fx.js diff --git a/d3/drag6/fx.js b/d3/drag6/fx.js deleted file mode 120000 index e5391b1..0000000 --- a/d3/drag6/fx.js +++ /dev/null @@ -1 +0,0 @@ -../drag5/fx.js \ No newline at end of file diff --git a/d3/drag6/fx.js b/d3/drag6/fx.js new file mode 100644 index 0000000..d5b4736 --- /dev/null +++ b/d3/drag6/fx.js @@ -0,0 +1,108 @@ +!function() { + /* module for working with a particular one-parameter function -- call it f(x) */ + + var fx + = { /*procedure to evaluate f(x)*/ + target_fn: null, + /* like target_fn(), but returns a point */ + eval_fn: null + }; + + /* the (linear) function of (x) that is + * tangent to fx.target_fn at x0 + */ + fx.make_tangent_fn = function(x0, fn, fn_deriv) { + var fx0 = fn(x0); + var dfx0 = fn_deriv(x0); + + return function(x) { return fx0 + (x - x0) * dfx0; } + } /*make_tangent_fn*/ + + /* f :: num -> num + * returns pf :: num -> Point, pf(x) = {x: x, y: f(x)} + */ + fx.make_pt_fn = function(f) { + return function(x) { return {x: x, y: f(x)}; }; + } /*make_pt_fn*/ + + /* x0 :: num + * fn :: num -> num + * fn_deriv :: num -> num + * returns :: (num -> Point) + */ + fx.make_tangent_pt_fn = function(x0, fn, fn_deriv) { + return fx.make_pt_fn(fx.make_tangent_fn(x0, fn, fn_deriv)); + } /*make_tangent_pt_fn*/ + + /* transform points using d3 scales + * f({x,y}) = {xscale(x),yscale(y)} + * + * xscale :: D3scale + * yscale :: D3scale + */ + fx.scale_fn = function(xscale, yscale) + { + return function(p) { + return {x: xscale(p.x), y: yscale(p.y)}; + } + } /*scale_fn*/ + + /* transform points using d3 scales, inverted + * f({x,y}) = {xscale.invert(x),yscale.invert(y)} + * + * xscale :: D3scale + * yscale :: D3scale + */ + fx.invert_scale_fn = function(xscale, yscale) + { + return function(p) { + return {x: xscale.invert(p.x), y: yscale.invert(p.y)}; + } + } /*invert_scale_fn*/ + + /* make an array of points, representing + * fx evaluated at regularly-spaced intervals; + * clip so that all points returned fall within the rectangle + * defined by (0,0) and box_pt + * + * fx :: number -> Point + * lo_x, hi_x :: number + * n_pt :: number + * xyscale :: Xyscale + * box_pt :: Point + */ + fx.make_target_pt_v = function(fx, lo_x, hi_x, n_pt, xyscale, box_pt) + { + var target_pt_v = []; + var target_pt_i = 0; + var p = null; + var pm1 = null; + + /* evaluate f(x) at regularly spaced x-coordinates on interval [lo_x, hi_x] + * keep only points with screen coords that fall inside the rectangle + * with corners {(0,0), box_pt}, plus: + * one point just before and one point just after + */ + for(var i=0; i