Straight Skeleton Polygon Offsetting

From: http://stackoverflow.com/a/11970006/796832

by Mallack

HTML

<canvas id="Canvas" width="500" height="500"></canvas>
<script src="
https://cdnjs.cloudflare.com/ajax/libs/jsts/1.2.1/jsts.min.js"></script>

JavaScript

function Vector2(x, y) 
{
    this.x = x;
    this.y = y;
}

var canvas = document.getElementById("Canvas");
var ctx = canvas.getContext("2d");
var poly = [
    new Vector2(150, 170),
    new Vector2(400, 120),
    new Vector2(200, 270),
    new Vector2(350, 400),
    new Vector2(210, 470)
];

/* */
// Regular rectangle
var poly_rect = [
    new Vector2(50, 50),
    new Vector2(125, 50),
    new Vector2(125, 100),
    new Vector2(50, 100)
];
/* */
/* */
// Rotated rectangle
var rotated_poly_rect = [
    new Vector2(250, 20),
    new Vector2(300, 70),
    new Vector2(250, 120),
    new Vector2(200, 70)
];
/* */



draw(poly);
draw(inflatePolygon(poly, 10));

draw(poly_rect);
draw(inflatePolygon(poly_rect, 10));

draw(rotated_poly_rect);
draw(inflatePolygon(rotated_poly_rect, 10));

function draw(p) {
	ctx.beginPath();
	ctx.moveTo(p[0].x, p[0].y);
	for(var i = 1; i < p.length; i++)
	{
		ctx.lineTo(p[i].x, p[i].y);
	}
	ctx.strokeStyle = "#000000";
	ctx.closePath();
	ctx.stroke();
 
}

function inflatePolygon(poly, spacing)
{
  var geoInput = vectorCoordinates2JTS(poly);
  geoInput.push(geoInput[0]);

  var geometryFactory = new jsts.geom.GeometryFactory();

  var shell = geometryFactory.createPolygon(geoInput);
  var polygon = shell.buffer(spacing, jsts.operation.buffer.BufferParameters.CAP_FLAT);

  var inflatedCoordinates = [];
  var oCoordinates;
  oCoordinates = polygon.shell.points.coordinates;
  for (i = 0; i < oCoordinates.length; i++) {
    var oItem;
    oItem = oCoordinates[i];
    inflatedCoordinates.push(new Vector2(Math.ceil(oItem.x), Math.ceil(oItem.y)));
  }
  return inflatedCoordinates;
}

function vectorCoordinates2JTS (polygon) {
  var coordinates = [];

  for (var i = 0; i < polygon.length; i++) {
    coordinates.push(new jsts.geom.Coordinate(polygon[i].x, polygon[i].y));
  }
  return coordinates;
}