Skip to content

Instantly share code, notes, and snippets.

@kekscom
Created December 3, 2012 10:43

Revisions

  1. Jan Marsch revised this gist Dec 3, 2012. No changes.
  2. Jan Marsch renamed this gist Dec 3, 2012. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  3. Jan Marsch created this gist Dec 3, 2012.
    100 changes: 100 additions & 0 deletions Thick Line to Polygon
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,100 @@
    /**
    * @author Jan Marsch (@kekscom)
    * @example see http://jsfiddle.net/osmbuildings/2e5KX/5/
    * @example thickLineToPolygon([{x:50,y:155}, {x:75,y:150}, {x:100,y:100}, {x:50,y:100}], 20)
    * @param polyline {array} a list of point objects in format {x:75,y:150}
    * @param thickness {int} line thickness
    */

    var thickLineToPolygon = (function () {
    function getOffsets(a, b, thickness) {
    var
    dx = b.x - a.x,
    dy = b.y - a.y,
    len = Math.sqrt(dx * dx + dy * dy),
    scale = thickness / (2 * len)
    ;
    return {
    x: -scale * dy,
    y: scale * dx
    };
    }

    function getIntersection(a1, b1, a2, b2) {
    // directional constants
    var
    k1 = (b1.y - a1.y) / (b1.x - a1.x),
    k2 = (b2.y - a2.y) / (b2.x - a2.x),
    x, y,
    m1, m2
    ;

    // if the directional constants are equal, the lines are parallel
    if (k1 === k2) {
    return;
    }

    // y offset constants for both lines
    m1 = a1.y - k1 * a1.x;
    m2 = a2.y - k2 * a2.x;

    // compute x
    x = (m1 - m2) / (k2 - k1);

    // use y = k * x + m to get y coordinate
    y = k1 * x + m1;

    return { x:x, y:y };
    }

    function me(points, thickness) {
    var
    off,
    poly = [],
    isFirst, isLast,
    prevA, prevB,
    interA, interB,
    p0a, p1a, p0b, p1b
    ;

    for (var i = 0, il = points.length - 1; i < il; i++) {
    isFirst = !i;
    isLast = (i === points.length - 2);

    off = getOffsets(points[i], points[i+1], thickness);

    p0a = { x:points[i ].x + off.x, y:points[i ].y + off.y };
    p1a = { x:points[i+1].x + off.x, y:points[i+1].y + off.y };
    p0b = { x:points[i ].x - off.x, y:points[i ].y - off.y };
    p1b = { x:points[i+1].x - off.x, y:points[i+1].y - off.y };

    if (!isFirst) {
    if (interA = getIntersection(prevA[0], prevA[1], p0a, p1a)) {
    poly.unshift(interA);
    }
    if (interB = getIntersection(prevB[0], prevB[1], p0b, p1b)) {
    poly.push(interB);
    }
    }

    if (isFirst) {
    poly.unshift(p0a);
    poly.push(p0b);
    }

    if (isLast) {
    poly.unshift(p1a);
    poly.push(p1b);
    }

    if (!isLast) {
    prevA = [p0a, p1a];
    prevB = [p0b, p1b];
    }
    }

    return poly;
    }

    return me;
    }());