Published
Edited
Feb 21, 2021
Insert cell
Insert cell
Insert cell
Insert cell
spsample=spalma({data:Math.sin, min:0, max:40, resolution:100})
Insert cell
function spalma(cfg) {
var defaults = {
min:0,
max:1,
distfun:function(a,b) { return Math.sqrt((a-b)*(a-b));},
resolution:10000,
data:[1,2,3,4,5],
loop: true
}
cfg=Object.assign({}, defaults, cfg);
var {data,min,max,distfun,resolution,loop} = cfg;
if (typeof(data)!='function')
data = Smooth(data, { method: 'cubic', clip: loop?'periodic':'clamp' });

var samples=[];
var dist=[];
for(var i=0; i<resolution; i++) {
let x = min+(max-min)*i/resolution;
samples[i]=data(x);
}
samples[resolution] = loop ? samples[0] : samples[resolution-1];
dist[0]=0;
for(var i=1; i<=resolution; i++) {
var d = distfun(samples[i-1], samples[i]);
dist[i] = dist[i-1]+d;
}
var totdist=dist[resolution];
var xmark=[];
var step = totdist/resolution;
var m = Smooth(dist, { method: 'cubic', clip: 'clamp' });
for(var i=0; i<=resolution; i++) {
var d=totdist*i/resolution;
var left=0, right=1;
for(var j=0; j<30; j++) {
var mean = (left+right)/2;
//if (j==29)
// console.log(`i=${i} j=${j} left=${left} right=${right} mean=${mean}`);
var md = m(resolution*mean);
if (md>d)
right=mean;
else
left=mean;
}
xmark[i] = (left+right)/2;
}
xmark[0]=0;
xmark[resolution] = 1;
var remapped = [];
for(var i=0; i<=resolution; i++)
remapped[i]=data(min+xmark[i]*(max-min));
xmark=null;
dist=null;
samples=null;
return remapped;

}
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more