Remapping values to bias a uniform set towards a certain curvature I'm trying to generate random numbers that would be distributed according to a sample curve that I provide in the shape of vertices. 

I came up with this: 

function curve_map(curve) {
    //  convert to sorted points
    var points = [];
    for (var x in curve) { var y = Number(curve[x]);
        points.push( {'x' : Number(x), 'y' : y} );
    }
    points.sort(function(a,b) {return a.x - b.x});

    //  create segments
    this.segments = [];
    var posy = 0;   
    for (var i = 1; i &lt; points.length; i++) {
        var n = points[i].y + points[i - 1].y;
        var seg = {
            'x0' : points[i - 1].x,     'x1' : points[i].x, 
            'y0' : points[i - 1].y,     'y1' : points[i].y,
            'n0' : posy,                'n1' : posy + n
        };
        posy = seg.n1;
        this.segments.push(seg);
    }

    //  normalize n
    for (var i = 0; i &lt; this.segments.length; i++) {
        this.segments[i].n0 /= posy;
        this.segments[i].n1 /= posy;
        this.segments[i].nr = this.segments[i].n1 - this.segments[i].n0;
    }

    //  func
    this.apply = function(x) {
        for (var i = 0; i &lt; this.segments.length; i++) {
            var seg = this.segments[i];
            if (x &gt;= seg.n0 &amp;&amp; x &lt;= seg.n1) {
                var along = (x - seg.n0) / seg.nr;
                //along = seg.y0 / (seg.y1 - seg.y0);

                var val = seg.x0 + (seg.x1 - seg.x0) * along;
                return val;
            }
        }
    }.bind(this);
}


What this does is 


take 2 points and make a segment, preserving the original coordinates
each segment's length is equal to the sum of Y of both points
after creating a segment between all the points, normalize so the chain of segments reaches from 0 to 1


So now I have a chain of segments. If I feed it a value, it looks up which segment it belongs to, checks how far along in the segment it is and remaps the location to the original interpolated x coordinates of the segment.

In theory I expected this to shave off the corners of the original curve since I don't know how to account for the difference in Y values in each segment.

Anyways, the result is quite different:



The red curve is what I fed the "curve_map" and what it should mimic

The black one is ~10k uniformly distributed random values put through the algorithm.

At least it sorta follows the line... but this is nowhere near good enough. Also I'm out of ideas on how to fix it.

Does anybody know if what I'm trying to do actually has a name? So I could read up on it or maybe find a neat algorithm to port..
For continuous distributions, you can use the inverse transform sampling method.  See also https://stats.stackexchange.com/q/176955/2921 and https://en.wikipedia.org/wiki/Ziggurat_algorithm.

For discrete distributions, you just generate a random floating point number in the range [0,1], and then figure out which of the buckets $[0,p_1)$, $[p_1,p_1+p_2)$, $[p_1+p_2,p_1+p_2+p_3)$, ..., $[..,1]$ it falls into, where $p_1,p_2,p_3,\ldots$ are the desired probabilities of the possible values.  See also https://stats.stackexchange.com/q/26858/2921 and http://www.keithschwarz.com/darts-dice-coins/.