polygon-offset
Advanced tools
+228
-229
@@ -1,159 +0,60 @@ | ||
| !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Offset=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
| !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Offset=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ | ||
| var Polygon = _dereq_('./polygon'); | ||
| /** | ||
| * @preserve Licensed under MIT License | ||
| * Clip driver | ||
| * @api | ||
| * @param {Array.<Array.<Number>>} polygonA | ||
| * @param {Array.<Array.<Number>>} polygonB | ||
| * @param {Boolean} sourceForwards | ||
| * @param {Boolean} clipForwards | ||
| * @return {Array.<Array.<Number>>} | ||
| */ | ||
| (function(root, factory) { | ||
| if (typeof define === 'function' && define.amd) { | ||
| define([], factory); | ||
| } else if (typeof exports === 'object') { | ||
| module['exports'] = factory(); | ||
| } else { | ||
| /** | ||
| * @api | ||
| * @export | ||
| */ | ||
| window['greinerHormann'] = factory(); | ||
| } | ||
| }(this, function() { | ||
| // ES5 15.4.3.2 Array.isArray ( arg ) | ||
| // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray | ||
| Array.isArray = Array.isArray || function(o) { | ||
| return Boolean(o && Object.prototype.toString.call(Object(o)) === '[object Array]'); | ||
| module.exports = function(polygonA, polygonB, eA, eB) { | ||
| var result, source = new Polygon(polygonA), | ||
| clip = new Polygon(polygonB), | ||
| result = source.clip(clip, eA, eB); | ||
| return result; | ||
| }; | ||
| /** | ||
| * Vertex representation | ||
| * | ||
| * @param {Number|Array.<Number>} x | ||
| * @param {Number=} y | ||
| * | ||
| * @constructor | ||
| */ | ||
| var Vertex = function(x, y) { | ||
| if (arguments.length === 1) { | ||
| // Coords | ||
| if (Array.isArray(x)) { | ||
| y = x[1]; | ||
| x = x[0]; | ||
| } else { | ||
| y = x.y; | ||
| x = x.x; | ||
| } | ||
| } | ||
| },{"./polygon":4}],2:[function(_dereq_,module,exports){ | ||
| var clip = _dereq_('./clip'); | ||
| module.exports = { | ||
| /** | ||
| * X coordinate | ||
| * @type {Number} | ||
| * @api | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonA | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonB | ||
| * @return {Array.<Array.<Number>>|Array.<Array.<Object>|Null} | ||
| */ | ||
| this.x = x; | ||
| union: function(polygonA, polygonB) { | ||
| return clip(polygonA, polygonB, false, false); | ||
| }, | ||
| /** | ||
| * Y coordinate | ||
| * @type {Number} | ||
| * @api | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonA | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonB | ||
| * @return {Array.<Array.<Number>>|Array.<Array.<Object>>|Null} | ||
| */ | ||
| this.y = y; | ||
| intersection: function(polygonA, polygonB) { | ||
| return clip(polygonA, polygonB, true, true); | ||
| }, | ||
| /** | ||
| * Next node | ||
| * @type {Vertex} | ||
| * @api | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonA | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonB | ||
| * @return {Array.<Array.<Number>>|Array.<Array.<Object>>|Null} | ||
| */ | ||
| this.next = null; | ||
| diff: function(polygonA, polygonB) { | ||
| return clip(polygonA, polygonB, false, true); | ||
| }, | ||
| /** | ||
| * Previous vertex | ||
| * @type {Vertex} | ||
| */ | ||
| this.prev = null; | ||
| /** | ||
| * Corresponding intersection in other polygon | ||
| */ | ||
| this._corresponding = null; | ||
| /** | ||
| * Distance from previous | ||
| */ | ||
| this._distance = 0.0; | ||
| /** | ||
| * Entry/exit point in another polygon | ||
| * @type {Boolean} | ||
| */ | ||
| this._isEntry = true; | ||
| /** | ||
| * Intersection vertex flag | ||
| * @type {Boolean} | ||
| */ | ||
| this._isIntersection = false; | ||
| /** | ||
| * Loop check | ||
| * @type {Boolean} | ||
| */ | ||
| this._visited = false; | ||
| clip: clip | ||
| }; | ||
| },{"./clip":1}],3:[function(_dereq_,module,exports){ | ||
| /** | ||
| * Creates intersection vertex | ||
| * @param {Number} x | ||
| * @param {Number} y | ||
| * @param {Number} distance | ||
| * @return {Vertex} | ||
| */ | ||
| Vertex.createIntersection = function(x, y, distance) { | ||
| var vertex = new Vertex(x, y); | ||
| vertex._distance = distance; | ||
| vertex._isIntersection = true; | ||
| vertex._isEntry = false; | ||
| return vertex; | ||
| }; | ||
| /** | ||
| * Mark as visited | ||
| */ | ||
| Vertex.prototype.visit = function() { | ||
| this._visited = true; | ||
| if (this._corresponding !== null && !this._corresponding._visited) { | ||
| this._corresponding.visit(); | ||
| } | ||
| }; | ||
| /** | ||
| * Convenience | ||
| * @param {Vertex} v | ||
| * @return {Boolean} | ||
| */ | ||
| Vertex.prototype.equals = function(v) { | ||
| return this.x === v.x && this.y === v.y; | ||
| }; | ||
| /** | ||
| * Check if vertex is inside a polygon by odd-even rule: | ||
| * If the number of intersections of a ray out of the point and polygon | ||
| * segments is odd - the point is inside. | ||
| */ | ||
| Vertex.prototype.isInside = function(poly) { | ||
| var oddNodes = false, | ||
| vertex = poly.first, | ||
| next = vertex.next, | ||
| x = this.x, | ||
| y = this.y; | ||
| do { | ||
| if ((vertex.y < y && next.y >= y || | ||
| next.y < y && vertex.y >= y) && | ||
| (vertex.x <= x || next.x <= x)) { | ||
| oddNodes ^= (vertex.x + (y - vertex.y) / | ||
| (next.y - vertex.y) * (next.x - vertex.x) < x); | ||
| } | ||
| vertex = vertex.next; | ||
| next = vertex.next || poly.first; | ||
| } while (!vertex.equals(poly.first)); | ||
| return oddNodes; | ||
| }; | ||
| /** | ||
| * Intersection | ||
@@ -216,2 +117,9 @@ * @param {Vertex} s1 | ||
| }; | ||
| module.exports = Intersection; | ||
| },{}],4:[function(_dereq_,module,exports){ | ||
| var Vertex = _dereq_('./vertex'); | ||
| var Intersection = _dereq_('./intersection'); | ||
| /** | ||
@@ -500,57 +408,147 @@ * Polygon representation | ||
| }; | ||
| // Router | ||
| module.exports = Polygon; | ||
| },{"./intersection":3,"./vertex":5}],5:[function(_dereq_,module,exports){ | ||
| /** | ||
| * Clip driver | ||
| * @api | ||
| * @param {Array.<Array.<Number>>} polygonA | ||
| * @param {Array.<Array.<Number>>} polygonB | ||
| * @param {Boolean} sourceForwards | ||
| * @param {Boolean} clipForwards | ||
| * @return {Array.<Array.<Number>>} | ||
| * Vertex representation | ||
| * | ||
| * @param {Number|Array.<Number>} x | ||
| * @param {Number=} y | ||
| * | ||
| * @constructor | ||
| */ | ||
| function clip(polygonA, polygonB, eA, eB) { | ||
| var result, source = new Polygon(polygonA), | ||
| clip = new Polygon(polygonB), | ||
| result = source.clip(clip, eA, eB); | ||
| var Vertex = function(x, y) { | ||
| return result; | ||
| } | ||
| return { | ||
| if (arguments.length === 1) { | ||
| // Coords | ||
| if (Array.isArray(x)) { | ||
| y = x[1]; | ||
| x = x[0]; | ||
| } else { | ||
| y = x.y; | ||
| x = x.x; | ||
| } | ||
| } | ||
| /** | ||
| * @api | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonA | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonB | ||
| * @return {Array.<Array.<Number>>|Array.<Array.<Object>|Null} | ||
| * X coordinate | ||
| * @type {Number} | ||
| */ | ||
| union: function(polygonA, polygonB) { | ||
| return clip(polygonA, polygonB, false, false); | ||
| }, | ||
| this.x = x; | ||
| /** | ||
| * @api | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonA | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonB | ||
| * @return {Array.<Array.<Number>>|Array.<Array.<Object>>|Null} | ||
| * Y coordinate | ||
| * @type {Number} | ||
| */ | ||
| intersection: function(polygonA, polygonB) { | ||
| return clip(polygonA, polygonB, true, true); | ||
| }, | ||
| this.y = y; | ||
| /** | ||
| * @api | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonA | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonB | ||
| * @return {Array.<Array.<Number>>|Array.<Array.<Object>>|Null} | ||
| * Next node | ||
| * @type {Vertex} | ||
| */ | ||
| diff: function(polygonA, polygonB) { | ||
| return clip(polygonA, polygonB, false, true); | ||
| }, | ||
| this.next = null; | ||
| clip: clip | ||
| /** | ||
| * Previous vertex | ||
| * @type {Vertex} | ||
| */ | ||
| this.prev = null; | ||
| /** | ||
| * Corresponding intersection in other polygon | ||
| */ | ||
| this._corresponding = null; | ||
| /** | ||
| * Distance from previous | ||
| */ | ||
| this._distance = 0.0; | ||
| /** | ||
| * Entry/exit point in another polygon | ||
| * @type {Boolean} | ||
| */ | ||
| this._isEntry = true; | ||
| /** | ||
| * Intersection vertex flag | ||
| * @type {Boolean} | ||
| */ | ||
| this._isIntersection = false; | ||
| /** | ||
| * Loop check | ||
| * @type {Boolean} | ||
| */ | ||
| this._visited = false; | ||
| }; | ||
| })); | ||
| /** | ||
| * Creates intersection vertex | ||
| * @param {Number} x | ||
| * @param {Number} y | ||
| * @param {Number} distance | ||
| * @return {Vertex} | ||
| */ | ||
| Vertex.createIntersection = function(x, y, distance) { | ||
| var vertex = new Vertex(x, y); | ||
| vertex._distance = distance; | ||
| vertex._isIntersection = true; | ||
| vertex._isEntry = false; | ||
| return vertex; | ||
| }; | ||
| },{}],2:[function(require,module,exports){ | ||
| /** | ||
| * Mark as visited | ||
| */ | ||
| Vertex.prototype.visit = function() { | ||
| this._visited = true; | ||
| if (this._corresponding !== null && !this._corresponding._visited) { | ||
| this._corresponding.visit(); | ||
| } | ||
| }; | ||
| /** | ||
| * Convenience | ||
| * @param {Vertex} v | ||
| * @return {Boolean} | ||
| */ | ||
| Vertex.prototype.equals = function(v) { | ||
| return this.x === v.x && this.y === v.y; | ||
| }; | ||
| /** | ||
| * Check if vertex is inside a polygon by odd-even rule: | ||
| * If the number of intersections of a ray out of the point and polygon | ||
| * segments is odd - the point is inside. | ||
| * @param {Polygon} poly | ||
| * @return {Boolean} | ||
| */ | ||
| Vertex.prototype.isInside = function(poly) { | ||
| var oddNodes = false, | ||
| vertex = poly.first, | ||
| next = vertex.next, | ||
| x = this.x, | ||
| y = this.y; | ||
| do { | ||
| if ((vertex.y < y && next.y >= y || | ||
| next.y < y && vertex.y >= y) && | ||
| (vertex.x <= x || next.x <= x)) { | ||
| oddNodes ^= (vertex.x + (y - vertex.y) / | ||
| (next.y - vertex.y) * (next.x - vertex.x) < x); | ||
| } | ||
| vertex = vertex.next; | ||
| next = vertex.next || poly.first; | ||
| } while (!vertex.equals(poly.first)); | ||
| return oddNodes; | ||
| }; | ||
| module.exports = Vertex; | ||
| },{}],6:[function(_dereq_,module,exports){ | ||
| "use strict"; | ||
@@ -594,6 +592,6 @@ | ||
| var inwards = this.inwardsNormal(); | ||
| return { | ||
| x: -inwards.x, | ||
| y: -inwards.y | ||
| }; | ||
| return [ | ||
| -inwards[0], | ||
| -inwards[1] | ||
| ]; | ||
| }; | ||
@@ -606,10 +604,10 @@ | ||
| Edge.prototype.inwardsNormal = function() { | ||
| var dx = this.next.x - this.current.x, | ||
| dy = this.next.y - this.current.y, | ||
| var dx = this.next[0] - this.current[0], | ||
| dy = this.next[1] - this.current[1], | ||
| edgeLength = Math.sqrt(dx * dx + dy * dy); | ||
| return { | ||
| x: -dy / edgeLength, | ||
| y: dx / edgeLength | ||
| }; | ||
| return [ | ||
| -dy / edgeLength, | ||
| dx / edgeLength | ||
| ]; | ||
| }; | ||
@@ -627,9 +625,9 @@ | ||
| return new Edge({ | ||
| x: current.x + dx, | ||
| y: current.y + dy | ||
| }, { | ||
| x: next.x + dx, | ||
| y: next.y + dy | ||
| }); | ||
| return new Edge([ | ||
| current[0] + dx, | ||
| current[1] + dy | ||
| ], [ | ||
| next[0] + dx, | ||
| next[1] + dy | ||
| ]); | ||
| }; | ||
@@ -639,3 +637,3 @@ | ||
| },{}],3:[function(require,module,exports){ | ||
| },{}],7:[function(_dereq_,module,exports){ | ||
| "use strict"; | ||
@@ -654,4 +652,4 @@ | ||
| module.exports = function intersection(A0, A1, B0, B1) { | ||
| var den = (B1.y - B0.y) * (A1.x - A0.x) - | ||
| (B1.x - B0.x) * (A1.y - A0.y); | ||
| var den = (B1[1] - B0[1]) * (A1[0] - A0[0]) - | ||
| (B1[0] - B0[0]) * (A1[1] - A0[1]); | ||
@@ -663,7 +661,7 @@ // lines are parallel or conincident | ||
| var ua = ((B1.x - B0.x) * (A0.y - B0.y) - | ||
| (B1.y - B0.y) * (A0.x - B0.x)) / den; | ||
| var ua = ((B1[0] - B0[0]) * (A0[1] - B0[1]) - | ||
| (B1[1] - B0[1]) * (A0[0] - B0[0])) / den; | ||
| var ub = ((A1.x - A0.x) * (A0.y - B0.y) - | ||
| (A1.y - A0.y) * (A0.x - B0.x)) / den; | ||
| var ub = ((A1[0] - A0[0]) * (A0[1] - B0[1]) - | ||
| (A1[1] - A0[1]) * (A0[0] - B0[0])) / den; | ||
@@ -674,12 +672,12 @@ if (ua < 0 || ub < 0 || ua > 1 || ub > 1) { | ||
| return { | ||
| x: A0.x + ua * (A1.x - A0.x), | ||
| y: A0.y + ua * (A1.y - A0.y) | ||
| }; | ||
| return [ | ||
| A0[0] + ua * (A1[0] - A0[0]), | ||
| A0[1] + ua * (A1[1] - A0[1]) | ||
| ]; | ||
| }; | ||
| },{}],4:[function(require,module,exports){ | ||
| var GreinerHormann = require('greiner-hormann'); | ||
| var Edge = require('./edge'); | ||
| var intersection = require('./intersection'); | ||
| },{}],8:[function(_dereq_,module,exports){ | ||
| var GreinerHormann = _dereq_('greiner-hormann'); | ||
| var Edge = _dereq_('./edge'); | ||
| var intersection = _dereq_('./intersection'); | ||
@@ -762,4 +760,4 @@ "use strict"; | ||
| var len = vertices.length; | ||
| if (vertices[0].x === vertices[len - 1].x && | ||
| vertices[0].y === vertices[len - 1].y) { | ||
| if (vertices[0][0] === vertices[len - 1][0] && | ||
| vertices[0][1] === vertices[len - 1][1]) { | ||
| vertices = vertices.slice(0, len - 1); | ||
@@ -786,4 +784,4 @@ this._closed = true; | ||
| var PI2 = Math.PI * 2, | ||
| startAngle = atan2(startVertex.y - center.y, startVertex.x - center.x), | ||
| endAngle = atan2(endVertex.y - center.y, endVertex.x - center.x); | ||
| startAngle = atan2(startVertex[1] - center[1], startVertex[0] - center[0]), | ||
| endAngle = atan2(endVertex[1] - center[1], endVertex[0] - center[0]); | ||
@@ -811,6 +809,6 @@ // odd number please | ||
| angle = startAngle + segmentAngle * i; | ||
| vertices.push({ | ||
| x: center.x + Math.cos(angle) * radius, | ||
| y: center.y + Math.sin(angle) * radius | ||
| }); | ||
| vertices.push([ | ||
| center[0] + Math.cos(angle) * radius, | ||
| center[1] + Math.sin(angle) * radius | ||
| ]); | ||
| } | ||
@@ -833,4 +831,4 @@ vertices.push(endVertex); | ||
| var edge = this.edges[i], | ||
| dx = edge._outNormal.x * dist, | ||
| dy = edge._outNormal.y * dist; | ||
| dx = edge._outNormal[0] * dist, | ||
| dy = edge._outNormal[1] * dist; | ||
| offsetEdges.push(edge.offset(dx, dy)); | ||
@@ -879,4 +877,4 @@ } | ||
| var edge = this.edges[i], | ||
| dx = edge._inNormal.x * dist, | ||
| dy = edge._inNormal.y * dist; | ||
| dx = edge._inNormal[0] * dist, | ||
| dy = edge._inNormal[1] * dist; | ||
@@ -928,6 +926,6 @@ offsetEdges.push(edge.offset(dx, dy)); | ||
| if (this._closed) { | ||
| vertices.push({ | ||
| x: vertices[0].x, | ||
| y: vertices[0].y | ||
| }); | ||
| vertices.push([ | ||
| vertices[0][0], | ||
| vertices[0][1] | ||
| ]); | ||
| } | ||
@@ -951,3 +949,4 @@ return vertices; | ||
| },{"./edge":2,"./intersection":3,"greiner-hormann":1}]},{},[4])(4) | ||
| },{"./edge":6,"./intersection":7,"greiner-hormann":2}]},{},[8]) | ||
| (8) | ||
| }); |
+13
-16
@@ -1,16 +0,13 @@ | ||
| /* | ||
| Licensed under MIT License | ||
| */ | ||
| function s(){return function q(k,d,h){function f(a,c){if(!d[a]){if(!k[a]){var b="function"==typeof require&&require;if(!c&&b)return b(a,!0);if(g)return g(a,!0);b=Error("Cannot find module '"+a+"'");throw b.code="MODULE_NOT_FOUND",b;}b=d[a]={exports:{}};k[a][0].call(b.exports,function(b){var c=k[a][1][b];return f(c?c:b)},b,b.exports,q,k,d,h)}return d[a].exports}for(var g="function"==typeof require&&require,m=0;m<h.length;m++)f(h[m]);return f}({1:[function(q,k,d){(function(h,f){"object"===typeof d? | ||
| k.exports=f():window.greinerHormann=f()})(this,function(){function h(a,c){this.first=null;this.g=0;this.n=null;this.p="undefined"===typeof c?Array.isArray(a[0]):c;for(var b=0,e=a.length;b<e;b++)this.i(new g(a[b]))}function d(a,c,b,e){this.k=this.toSource=this.y=this.x=0;var l=(e.y-b.y)*(c.x-a.x)-(e.x-b.x)*(c.y-a.y);0!==l&&(this.toSource=((e.x-b.x)*(a.y-b.y)-(e.y-b.y)*(a.x-b.x))/l,this.k=((c.x-a.x)*(a.y-b.y)-(c.y-a.y)*(a.x-b.x))/l,this.valid()&&(this.x=a.x+this.toSource*(c.x-a.x),this.y=a.y+this.toSource* | ||
| (c.y-a.y)))}function g(a,c){1===arguments.length&&(Array.isArray(a)?(c=a[1],a=a[0]):(c=a.y,a=a.x));this.x=a;this.y=c;this.e=this.c=this.next=null;this.m=0;this.h=!0;this.f=this.a=!1}function m(a,c,b,e){a=new h(a);c=new h(c);return a.clip(c,b,e)}Array.isArray=Array.isArray||function(a){return Boolean(a&&"[object Array]"===Object.prototype.toString.call(Object(a)))};g.u=function(a,c,b){a=new g(a,c);a.m=b;a.a=!0;a.h=!1;return a};g.prototype.C=function(){this.f=!0;null===this.e||this.e.f||this.e.C()}; | ||
| g.prototype.b=function(a){return this.x===a.x&&this.y===a.y};g.prototype.B=function(a){var c=!1,b=a.first,e=b.next,l=this.x,d=this.y;do(b.y<d&&e.y>=d||e.y<d&&b.y>=d)&&(b.x<=l||e.x<=l)&&(c^=b.x+(d-b.y)/(e.y-b.y)*(e.x-b.x)<l),b=b.next,e=b.next||a.first;while(!b.b(a.first));return c};d.prototype.valid=function(){return 0<this.toSource&&1>this.toSource&&0<this.k&&1>this.k};h.prototype.i=function(a){if(null==this.first)this.first=a,this.first.next=a,this.first.c=a;else{var c=this.first,b=c.c;c.c=a;a.next= | ||
| c;a.c=b;b.next=a}this.g++};h.prototype.w=function(a,c,b){for(;!c.b(b)&&c.m<a.m;)c=c.next;a.next=c;b=c.c;a.c=b;b.next=a;c.c=a;this.g++};h.prototype.j=function(a){for(;a.a;)a=a.next;return a};h.prototype.F=function(){var a=this.D||this.first;do{if(a.a&&!a.f)break;a=a.next}while(!a.b(this.first));return this.D=a};h.prototype.G=function(){var a=this.n||this.first;do{if(a.a&&!a.f)return this.n=a,!0;a=a.next}while(!a.b(this.first));this.n=null;return!1};h.prototype.o=function(){var a=[],c=this.first;if(this.p){do a.push([c.x, | ||
| c.y]),c=c.next;while(c!==this.first)}else{do a.push({x:c.x,y:c.y}),c=c.next;while(c!==this.first)}return a};h.prototype.clip=function(a,c,b){var e=this.first,l=a.first,r,n;do{if(!e.a){do l.a||(n=new d(e,this.j(e.next),l,a.j(l.next)),n.valid()&&(r=g.u(n.x,n.y,n.toSource),n=g.u(n.x,n.y,n.k),r.e=n,n.e=r,this.w(r,e,this.j(e.next)),a.w(n,l,a.j(l.next)))),l=l.next;while(!l.b(a.first))}e=e.next}while(!e.b(this.first));e=this.first;l=a.first;r=e.B(a);n=l.B(this);c^=r;b^=n;do e.a&&(e.h=c,c=!c),e=e.next;while(!e.b(this.first)); | ||
| do l.a&&(l.h=b,b=!b),l=l.next;while(!l.b(a.first));for(c=[];this.G();){b=this.F();e=new h([],this.p);e.i(new g(b.x,b.y));do{b.C();if(b.h){do b=b.next,e.i(new g(b.x,b.y));while(!b.a)}else{do b=b.c,e.i(new g(b.x,b.y));while(!b.a)}b=b.e}while(!b.f);c.push(e.o())}0===c.length&&(r&&c.push(this.o()),n&&c.push(a.o()),0===c.length&&(c=null));return c};return{union:function(a,c){return m(a,c,!1,!1)},intersection:function(a,c){return m(a,c,!0,!0)},diff:function(a,c){return m(a,c,!1,!0)},clip:m}})},{}],2:[function(q, | ||
| k){function d(d,f){this.current=d;this.next=f;this.r=this.A();this.s=this.H()}d.prototype.H=function(){var d=this.A();return{x:-d.x,y:-d.y}};d.prototype.A=function(){var d=this.next.x-this.current.x,f=this.next.y-this.current.y,g=Math.sqrt(d*d+f*f);return{x:-f/g,y:d/g}};d.prototype.offset=function(h,f){var g=this.current,m=this.next;return new d({x:g.x+h,y:g.y+f},{x:m.x+h,y:m.y+f})};k.exports=d},{}],3:[function(q,k){k.exports=function(d,h,f,g){var m=(g.y-f.y)*(h.x-d.x)-(g.x-f.x)*(h.y-d.y);if(0==m)return null; | ||
| g=((g.x-f.x)*(d.y-f.y)-(g.y-f.y)*(d.x-f.x))/m;f=((h.x-d.x)*(d.y-f.y)-(h.y-d.y)*(d.x-f.x))/m;return 0>g||0>f||1<g||1<f?null:{x:d.x+g*(h.x-d.x),y:d.y+g*(h.y-d.y)}}},{}],4:[function(q,k){function d(a,c){this.d=this.g=null;this.q=!1;a&&this.data(a);this.l=c||5}var h=q("greiner-hormann"),f=q("./edge"),g=q("./intersection");"use strict";var m=Math.atan2;d.prototype.data=function(a){a=this.I(a);for(var c=[],b=0,e=a.length;b<e;b++)c.push(new f(a[b],a[(b+1)%e]));this.g=a;this.d=c;return this};d.prototype.arcSegments= | ||
| function(a){this.l=a;return this};d.prototype.I=function(a){var c=a.length;a[0].x===a[c-1].x&&a[0].y===a[c-1].y&&(a=a.slice(0,c-1),this.q=!0);return a};d.prototype.t=function(a,c,b,e,d,g,f){var h=2*Math.PI,k=m(e.y-c.y,e.x-c.x),p=m(d.y-c.y,d.x-c.x);0===g%2&&--g;0>k&&(k+=h);0>p&&(p+=h);p=k>p?k-p:k+h-p;f=(f?-p:h-p)/g;a.push(e);for(e=1;e<g;++e)p=k+f*e,a.push({x:c.x+Math.cos(p)*b,y:c.y+Math.sin(p)*b});a.push(d)};d.prototype.padding=function(a){var c=[],b=[],e,d;e=0;for(d=this.d.length;e<d;e++){var f=this.d[e]; | ||
| c.push(f.offset(f.s.x*a,f.s.y*a))}e=0;for(d=c.length;e<d;e++){var f=c[e],n=c[(e+d-1)%d],k=g(n.current,n.next,f.current,f.next);k?b.push(k):this.t(b,this.d[e].current,a,n.next,f.current,this.l,!1)}b=(a=h.union(b,b))?a[0]:b;return b=this.v(b)};d.prototype.margin=function(a){var c=[],b=[],e,d;e=0;for(d=this.d.length;e<d;e++){var f=this.d[e];c.push(f.offset(f.r.x*a,f.r.y*a))}e=0;for(d=c.length;e<d;e++){var f=c[e],k=c[(e+d-1)%d],m=g(k.current,k.next,f.current,f.next);m?b.push(m):this.t(b,this.d[e].current, | ||
| a,k.next,f.current,this.l,!0)}if(a=h.union(b,b))a=a[0],b=a.slice(0,a.length/2);return b=this.v(b)};d.prototype.v=function(a){this.q&&a.push({x:a[0].x,y:a[0].y});return a};d.prototype.offset=function(a){return 0===a?this.g:0<a?this.margin(a):this.padding(-a)};k.exports=d},{"./edge":2,"./intersection":3,"greiner-hormann":1}]},{},[4])(4)} | ||
| if("object"==typeof exports&&"undefined"!=typeof module)module.exports=s();else if("function"==typeof define&&define.J)define([],s);else{var t;"undefined"!=typeof window?t=window:"undefined"!=typeof global?t=global:"undefined"!=typeof self&&(t=self);t.Offset=s()}!0; | ||
| function t(){return function h(g,c,a){function e(f,d){if(!c[f]){if(!g[f]){var k="function"==typeof require&&require;if(!d&&k)return k(f,!0);if(b)return b(f,!0);throw Error("Cannot find module '"+f+"'");}k=c[f]={exports:{}};g[f][0].call(k.exports,function(b){var a=g[f][1][b];return e(a?a:b)},k,k.exports,h,g,c,a)}return c[f].exports}for(var b="function"==typeof require&&require,d=0;d<a.length;d++)e(a[d]);return e}({1:[function(h,g){var c=h("./polygon");g.exports=function(a,e,b,d){a=new c(a);e=new c(e); | ||
| return a.clip(e,b,d)}},{"./polygon":4}],2:[function(h,g){var c=h("./clip");g.exports={union:function(a,e){return c(a,e,!1,!1)},intersection:function(a,e){return c(a,e,!0,!0)},diff:function(a,e){return c(a,e,!1,!0)},clip:c}},{"./clip":1}],3:[function(h,g){function c(a,c,b,d){this.o=this.toSource=this.y=this.x=0;var f=(d.y-b.y)*(c.x-a.x)-(d.x-b.x)*(c.y-a.y);0!==f&&(this.toSource=((d.x-b.x)*(a.y-b.y)-(d.y-b.y)*(a.x-b.x))/f,this.o=((c.x-a.x)*(a.y-b.y)-(c.y-a.y)*(a.x-b.x))/f,this.valid()&&(this.x=a.x+ | ||
| this.toSource*(c.x-a.x),this.y=a.y+this.toSource*(c.y-a.y)))}c.prototype.valid=function(){return 0<this.toSource&&1>this.toSource&&0<this.o&&1>this.o};g.exports=c},{}],4:[function(h,g){function c(b,d){this.first=null;this.i=0;this.v=null;this.A="undefined"===typeof d?Array.isArray(b[0]):d;for(var f=0,c=b.length;f<c;f++)this.l(new a(b[f]))}var a=h("./vertex"),e=h("./intersection");c.prototype.l=function(b){if(null==this.first)this.first=b,this.first.next=b,this.first.c=b;else{var a=this.first,f=a.c; | ||
| a.c=b;b.next=a;b.c=f;f.next=b}this.i++};c.prototype.I=function(b,a,f){for(;!a.b(f)&&a.u<b.u;)a=a.next;b.next=a;f=a.c;b.c=f;f.next=b;a.c=b;this.i++};c.prototype.m=function(b){for(;b.a;)b=b.next;return b};c.prototype.N=function(){var b=this.M||this.first;do{if(b.a&&!b.h)break;b=b.next}while(!b.b(this.first));return this.M=b};c.prototype.O=function(){var b=this.v||this.first;do{if(b.a&&!b.h)return this.v=b,!0;b=b.next}while(!b.b(this.first));this.v=null;return!1};c.prototype.w=function(){var b=[],a= | ||
| this.first;if(this.A){do b.push([a.x,a.y]),a=a.next;while(a!==this.first)}else{do b.push({x:a.x,y:a.y}),a=a.next;while(a!==this.first)}return b};c.prototype.clip=function(b,d,f){var m=this.first,k=b.first,n,l;do{if(!m.a){do k.a||(l=new e(m,this.m(m.next),k,b.m(k.next)),l.valid()&&(n=a.G(l.x,l.y,l.toSource),l=a.G(l.x,l.y,l.o),n.g=l,l.g=n,this.I(n,m,this.m(m.next)),b.I(l,k,b.m(k.next)))),k=k.next;while(!k.b(b.first))}m=m.next}while(!m.b(this.first));m=this.first;k=b.first;n=m.K(b);l=k.K(this);d^=n; | ||
| f^=l;do m.a&&(m.j=d,d=!d),m=m.next;while(!m.b(this.first));do k.a&&(k.j=f,f=!f),k=k.next;while(!k.b(b.first));for(d=[];this.O();){f=this.N();m=new c([],this.A);m.l(new a(f.x,f.y));do{f.L();if(f.j){do f=f.next,m.l(new a(f.x,f.y));while(!f.a)}else{do f=f.c,m.l(new a(f.x,f.y));while(!f.a)}f=f.g}while(!f.h);d.push(m.w())}0===d.length&&(n&&d.push(this.w()),l&&d.push(b.w()),0===d.length&&(d=null));return d};g.exports=c},{"./intersection":3,"./vertex":5}],5:[function(h,g){function c(a,c){1===arguments.length&& | ||
| (Array.isArray(a)?(c=a[1],a=a[0]):(c=a.y,a=a.x));this.x=a;this.y=c;this.g=this.c=this.next=null;this.u=0;this.j=!0;this.h=this.a=!1}c.G=function(a,e,b){a=new c(a,e);a.u=b;a.a=!0;a.j=!1;return a};c.prototype.L=function(){this.h=!0;null===this.g||this.g.h||this.g.L()};c.prototype.b=function(a){return this.x===a.x&&this.y===a.y};c.prototype.K=function(a){var c=!1,b=a.first,d=b.next,f=this.x,m=this.y;do(b.y<m&&d.y>=m||d.y<m&&b.y>=m)&&(b.x<=f||d.x<=f)&&(c^=b.x+(m-b.y)/(d.y-b.y)*(d.x-b.x)<f),b=b.next,d= | ||
| b.next||a.first;while(!b.b(a.first));return c};g.exports=c},{}],6:[function(h,g){function c(a,c){this.current=a;this.next=c;this.C=this.J();this.D=this.P()}c.prototype.P=function(){var a=this.J();return[-a[0],-a[1]]};c.prototype.J=function(){var a=this.next[0]-this.current[0],c=this.next[1]-this.current[1],b=Math.sqrt(a*a+c*c);return[-c/b,a/b]};c.prototype.offset=function(a,e){var b=this.current,d=this.next;return new c([b[0]+a,b[1]+e],[d[0]+a,d[1]+e])};g.exports=c},{}],7:[function(h,g){g.exports= | ||
| function(c,a,e,b){var d=(b[1]-e[1])*(a[0]-c[0])-(b[0]-e[0])*(a[1]-c[1]);if(0==d)return null;b=((b[0]-e[0])*(c[1]-e[1])-(b[1]-e[1])*(c[0]-e[0]))/d;e=((a[0]-c[0])*(c[1]-e[1])-(a[1]-c[1])*(c[0]-e[0]))/d;return 0>b||0>e||1<b||1<e?null:[c[0]+b*(a[0]-c[0]),c[1]+b*(a[1]-c[1])]}},{}],8:[function(h,g){function c(a,b){this.f=this.i=null;this.B=!1;a&&this.data(a);this.s=b||5}var a=h("greiner-hormann"),e=h("./edge"),b=h("./intersection");"use strict";var d=Math.atan2;c.prototype.data=function(a){a=this.R(a); | ||
| for(var b=[],c=0,d=a.length;c<d;c++)b.push(new e(a[c],a[(c+1)%d]));this.i=a;this.f=b;return this};c.prototype.arcSegments=function(a){this.s=a;return this};c.prototype.R=function(a){var b=a.length;a[0][0]===a[b-1][0]&&a[0][1]===a[b-1][1]&&(a=a.slice(0,b-1),this.B=!0);return a};c.prototype.F=function(a,b,c,n,e,g,h){var q=2*Math.PI,r=d(n[1]-b[1],n[0]-b[0]),p=d(e[1]-b[1],e[0]-b[0]);0===g%2&&--g;0>r&&(r+=q);0>p&&(p+=q);p=r>p?r-p:r+q-p;h=(h?-p:q-p)/g;a.push(n);for(n=1;n<g;++n)p=r+h*n,a.push([b[0]+Math.cos(p)* | ||
| c,b[1]+Math.sin(p)*c]);a.push(e)};c.prototype.padding=function(c){var d=[],k=[],e,l;e=0;for(l=this.f.length;e<l;e++){var g=this.f[e];d.push(g.offset(g.D[0]*c,g.D[1]*c))}e=0;for(l=d.length;e<l;e++){var g=d[e],h=d[(e+l-1)%l],q=b(h.current,h.next,g.current,g.next);q?k.push(q):this.F(k,this.f[e].current,c,h.next,g.current,this.s,!1)}k=(c=a.union(k,k))?c[0]:k;return k=this.H(k)};c.prototype.margin=function(c){var d=[],e=[],g,l;g=0;for(l=this.f.length;g<l;g++){var h=this.f[g];d.push(h.offset(h.C[0]*c,h.C[1]* | ||
| c))}g=0;for(l=d.length;g<l;g++){var h=d[g],v=d[(g+l-1)%l],q=b(v.current,v.next,h.current,h.next);q?e.push(q):this.F(e,this.f[g].current,c,v.next,h.current,this.s,!0)}if(c=a.union(e,e))c=c[0],e=c.slice(0,c.length/2);return e=this.H(e)};c.prototype.H=function(a){this.B&&a.push([a[0][0],a[0][1]]);return a};c.prototype.offset=function(a){return 0===a?this.i:0<a?this.margin(a):this.padding(-a)};g.exports=c},{"./edge":6,"./intersection":7,"greiner-hormann":2}]},{},[8])(8)} | ||
| if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.S)define([],t);else{var u;"undefined"!=typeof window?u=window:"undefined"!=typeof global?u=global:"undefined"!=typeof self&&(u=self);u.Offset=t()}!0; |
+601
-50
@@ -1,2 +0,552 @@ | ||
| !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Offset=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){ | ||
| !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Offset=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ | ||
| var Polygon = _dereq_('./polygon'); | ||
| /** | ||
| * Clip driver | ||
| * @api | ||
| * @param {Array.<Array.<Number>>} polygonA | ||
| * @param {Array.<Array.<Number>>} polygonB | ||
| * @param {Boolean} sourceForwards | ||
| * @param {Boolean} clipForwards | ||
| * @return {Array.<Array.<Number>>} | ||
| */ | ||
| module.exports = function(polygonA, polygonB, eA, eB) { | ||
| var result, source = new Polygon(polygonA), | ||
| clip = new Polygon(polygonB), | ||
| result = source.clip(clip, eA, eB); | ||
| return result; | ||
| }; | ||
| },{"./polygon":4}],2:[function(_dereq_,module,exports){ | ||
| var clip = _dereq_('./clip'); | ||
| module.exports = { | ||
| /** | ||
| * @api | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonA | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonB | ||
| * @return {Array.<Array.<Number>>|Array.<Array.<Object>|Null} | ||
| */ | ||
| union: function(polygonA, polygonB) { | ||
| return clip(polygonA, polygonB, false, false); | ||
| }, | ||
| /** | ||
| * @api | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonA | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonB | ||
| * @return {Array.<Array.<Number>>|Array.<Array.<Object>>|Null} | ||
| */ | ||
| intersection: function(polygonA, polygonB) { | ||
| return clip(polygonA, polygonB, true, true); | ||
| }, | ||
| /** | ||
| * @api | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonA | ||
| * @param {Array.<Array.<Number>|Array.<Object>} polygonB | ||
| * @return {Array.<Array.<Number>>|Array.<Array.<Object>>|Null} | ||
| */ | ||
| diff: function(polygonA, polygonB) { | ||
| return clip(polygonA, polygonB, false, true); | ||
| }, | ||
| clip: clip | ||
| }; | ||
| },{"./clip":1}],3:[function(_dereq_,module,exports){ | ||
| /** | ||
| * Intersection | ||
| * @param {Vertex} s1 | ||
| * @param {Vertex} s2 | ||
| * @param {Vertex} c1 | ||
| * @param {Vertex} c2 | ||
| * @constructor | ||
| */ | ||
| var Intersection = function(s1, s2, c1, c2) { | ||
| /** | ||
| * @type {Number} | ||
| */ | ||
| this.x = 0.0; | ||
| /** | ||
| * @type {Number} | ||
| */ | ||
| this.y = 0.0; | ||
| /** | ||
| * @type {Number} | ||
| */ | ||
| this.toSource = 0.0; | ||
| /** | ||
| * @type {Number} | ||
| */ | ||
| this.toClip = 0.0; | ||
| var d = (c2.y - c1.y) * (s2.x - s1.x) - (c2.x - c1.x) * (s2.y - s1.y); | ||
| if (d === 0) { | ||
| return; | ||
| } | ||
| /** | ||
| * @type {Number} | ||
| */ | ||
| this.toSource = ((c2.x - c1.x) * (s1.y - c1.y) - (c2.y - c1.y) * (s1.x - c1.x)) / d; | ||
| /** | ||
| * @type {Number} | ||
| */ | ||
| this.toClip = ((s2.x - s1.x) * (s1.y - c1.y) - (s2.y - s1.y) * (s1.x - c1.x)) / d; | ||
| if (this.valid()) { | ||
| this.x = s1.x + this.toSource * (s2.x - s1.x); | ||
| this.y = s1.y + this.toSource * (s2.y - s1.y); | ||
| } | ||
| }; | ||
| /** | ||
| * @return {Boolean} | ||
| */ | ||
| Intersection.prototype.valid = function() { | ||
| return (0 < this.toSource && this.toSource < 1) && (0 < this.toClip && this.toClip < 1); | ||
| }; | ||
| module.exports = Intersection; | ||
| },{}],4:[function(_dereq_,module,exports){ | ||
| var Vertex = _dereq_('./vertex'); | ||
| var Intersection = _dereq_('./intersection'); | ||
| /** | ||
| * Polygon representation | ||
| * @param {Array.<Array.<Number>>} p | ||
| * @param {Boolean=} arrayVertices | ||
| * | ||
| * @constructor | ||
| */ | ||
| var Polygon = function(p, arrayVertices) { | ||
| /** | ||
| * @type {Vertex} | ||
| */ | ||
| this.first = null; | ||
| /** | ||
| * @type {Number} | ||
| */ | ||
| this.vertices = 0; | ||
| /** | ||
| * @type {Vertex} | ||
| */ | ||
| this._lastUnprocessed = null; | ||
| /** | ||
| * Whether to handle input and output as [x,y] or {x:x,y:y} | ||
| * @type {Boolean} | ||
| */ | ||
| this._arrayVertices = (typeof arrayVertices === "undefined") ? | ||
| Array.isArray(p[0]) : | ||
| arrayVertices; | ||
| for (var i = 0, len = p.length; i < len; i++) { | ||
| this.addVertex(new Vertex(p[i])); | ||
| } | ||
| }; | ||
| /** | ||
| * Add a vertex object to the polygon | ||
| * (vertex is added at the 'end' of the list') | ||
| * | ||
| * @param vertex | ||
| */ | ||
| Polygon.prototype.addVertex = function(vertex) { | ||
| if (this.first == null) { | ||
| this.first = vertex; | ||
| this.first.next = vertex; | ||
| this.first.prev = vertex; | ||
| } else { | ||
| var next = this.first, | ||
| prev = next.prev; | ||
| next.prev = vertex; | ||
| vertex.next = next; | ||
| vertex.prev = prev; | ||
| prev.next = vertex; | ||
| } | ||
| this.vertices++; | ||
| }; | ||
| /** | ||
| * Inserts a vertex inbetween start and end | ||
| * | ||
| * @param {Vertex} vertex | ||
| * @param {Vertex} start | ||
| * @param {Vertex} end | ||
| */ | ||
| Polygon.prototype.insertVertex = function(vertex, start, end) { | ||
| var prev, curr = start; | ||
| while (!curr.equals(end) && curr._distance < vertex._distance) { | ||
| curr = curr.next; | ||
| } | ||
| vertex.next = curr; | ||
| prev = curr.prev; | ||
| vertex.prev = prev; | ||
| prev.next = vertex; | ||
| curr.prev = vertex; | ||
| this.vertices++; | ||
| }; | ||
| /** | ||
| * Get next non-intersection point | ||
| * @param {Vertex} v | ||
| * @return {Vertex} | ||
| */ | ||
| Polygon.prototype.getNext = function(v) { | ||
| var c = v; | ||
| while (c._isIntersection) { | ||
| c = c.next; | ||
| } | ||
| return c; | ||
| }; | ||
| /** | ||
| * Unvisited intersection | ||
| * @return {Vertex} | ||
| */ | ||
| Polygon.prototype.getFirstIntersect = function() { | ||
| var v = this._firstIntersect || this.first; | ||
| do { | ||
| if (v._isIntersection && !v._visited) { | ||
| break; | ||
| } | ||
| v = v.next; | ||
| } while (!v.equals(this.first)); | ||
| this._firstIntersect = v; | ||
| return v; | ||
| }; | ||
| /** | ||
| * Does the polygon have unvisited vertices | ||
| * @return {Boolean} [description] | ||
| */ | ||
| Polygon.prototype.hasUnprocessed = function() { | ||
| var v = this._lastUnprocessed || this.first; | ||
| do { | ||
| if (v._isIntersection && !v._visited) { | ||
| this._lastUnprocessed = v; | ||
| return true; | ||
| } | ||
| v = v.next; | ||
| } while (!v.equals(this.first)); | ||
| this._lastUnprocessed = null; | ||
| return false; | ||
| }; | ||
| /** | ||
| * The output depends on what you put in, arrays or objects | ||
| * @return {Array.<Array<Number>|Array.<Object>} | ||
| */ | ||
| Polygon.prototype.getPoints = function() { | ||
| var points = [], | ||
| v = this.first; | ||
| if (this._arrayVertices) { | ||
| do { | ||
| points.push([v.x, v.y]); | ||
| v = v.next; | ||
| } while (v !== this.first); | ||
| } else { | ||
| do { | ||
| points.push({ | ||
| x: v.x, | ||
| y: v.y | ||
| }); | ||
| v = v.next; | ||
| } while (v !== this.first); | ||
| } | ||
| return points; | ||
| }; | ||
| /** | ||
| * Clip polygon against another one. | ||
| * Result depends on algorithm direction: | ||
| * | ||
| * Intersection: forwards forwards | ||
| * Union: backwars backwards | ||
| * Diff: backwards forwards | ||
| * | ||
| * @param {Polygon} clip | ||
| * @param {Boolean} sourceForwards | ||
| * @param {Boolean} clipForwards | ||
| */ | ||
| Polygon.prototype.clip = function(clip, sourceForwards, clipForwards) { | ||
| var sourceVertex = this.first, | ||
| clipVertex = clip.first, | ||
| sourceInClip, clipInSource; | ||
| // calculate and mark intersections | ||
| do { | ||
| if (!sourceVertex._isIntersection) { | ||
| do { | ||
| if (!clipVertex._isIntersection) { | ||
| var i = new Intersection( | ||
| sourceVertex, | ||
| this.getNext(sourceVertex.next), | ||
| clipVertex, clip.getNext(clipVertex.next)); | ||
| if (i.valid()) { | ||
| var sourceIntersection = | ||
| Vertex.createIntersection(i.x, i.y, i.toSource), | ||
| clipIntersection = | ||
| Vertex.createIntersection(i.x, i.y, i.toClip); | ||
| sourceIntersection._corresponding = clipIntersection; | ||
| clipIntersection._corresponding = sourceIntersection; | ||
| this.insertVertex( | ||
| sourceIntersection, | ||
| sourceVertex, | ||
| this.getNext(sourceVertex.next)); | ||
| clip.insertVertex( | ||
| clipIntersection, | ||
| clipVertex, | ||
| clip.getNext(clipVertex.next)); | ||
| } | ||
| } | ||
| clipVertex = clipVertex.next; | ||
| } while (!clipVertex.equals(clip.first)); | ||
| } | ||
| sourceVertex = sourceVertex.next; | ||
| } while (!sourceVertex.equals(this.first)); | ||
| // phase two - identify entry/exit points | ||
| sourceVertex = this.first; | ||
| clipVertex = clip.first; | ||
| sourceInClip = sourceVertex.isInside(clip); | ||
| clipInSource = clipVertex.isInside(this); | ||
| sourceForwards ^= sourceInClip; | ||
| clipForwards ^= clipInSource; | ||
| do { | ||
| if (sourceVertex._isIntersection) { | ||
| sourceVertex._isEntry = sourceForwards; | ||
| sourceForwards = !sourceForwards; | ||
| } | ||
| sourceVertex = sourceVertex.next; | ||
| } while (!sourceVertex.equals(this.first)); | ||
| do { | ||
| if (clipVertex._isIntersection) { | ||
| clipVertex._isEntry = clipForwards; | ||
| clipForwards = !clipForwards; | ||
| } | ||
| clipVertex = clipVertex.next; | ||
| } while (!clipVertex.equals(clip.first)); | ||
| // phase three - construct a list of clipped polygons | ||
| var list = []; | ||
| while (this.hasUnprocessed()) { | ||
| var current = this.getFirstIntersect(), | ||
| // keep format | ||
| clipped = new Polygon([], this._arrayVertices); | ||
| clipped.addVertex(new Vertex(current.x, current.y)); | ||
| do { | ||
| current.visit(); | ||
| if (current._isEntry) { | ||
| do { | ||
| current = current.next; | ||
| clipped.addVertex(new Vertex(current.x, current.y)); | ||
| } while (!current._isIntersection); | ||
| } else { | ||
| do { | ||
| current = current.prev; | ||
| clipped.addVertex(new Vertex(current.x, current.y)); | ||
| } while (!current._isIntersection); | ||
| } | ||
| current = current._corresponding; | ||
| } while (!current._visited); | ||
| list.push(clipped.getPoints()); | ||
| } | ||
| if (list.length === 0) { | ||
| if (sourceInClip) { | ||
| list.push(this.getPoints()); | ||
| } | ||
| if (clipInSource) { | ||
| list.push(clip.getPoints()); | ||
| } | ||
| if (list.length === 0) { | ||
| list = null; | ||
| } | ||
| } | ||
| return list; | ||
| }; | ||
| module.exports = Polygon; | ||
| },{"./intersection":3,"./vertex":5}],5:[function(_dereq_,module,exports){ | ||
| /** | ||
| * Vertex representation | ||
| * | ||
| * @param {Number|Array.<Number>} x | ||
| * @param {Number=} y | ||
| * | ||
| * @constructor | ||
| */ | ||
| var Vertex = function(x, y) { | ||
| if (arguments.length === 1) { | ||
| // Coords | ||
| if (Array.isArray(x)) { | ||
| y = x[1]; | ||
| x = x[0]; | ||
| } else { | ||
| y = x.y; | ||
| x = x.x; | ||
| } | ||
| } | ||
| /** | ||
| * X coordinate | ||
| * @type {Number} | ||
| */ | ||
| this.x = x; | ||
| /** | ||
| * Y coordinate | ||
| * @type {Number} | ||
| */ | ||
| this.y = y; | ||
| /** | ||
| * Next node | ||
| * @type {Vertex} | ||
| */ | ||
| this.next = null; | ||
| /** | ||
| * Previous vertex | ||
| * @type {Vertex} | ||
| */ | ||
| this.prev = null; | ||
| /** | ||
| * Corresponding intersection in other polygon | ||
| */ | ||
| this._corresponding = null; | ||
| /** | ||
| * Distance from previous | ||
| */ | ||
| this._distance = 0.0; | ||
| /** | ||
| * Entry/exit point in another polygon | ||
| * @type {Boolean} | ||
| */ | ||
| this._isEntry = true; | ||
| /** | ||
| * Intersection vertex flag | ||
| * @type {Boolean} | ||
| */ | ||
| this._isIntersection = false; | ||
| /** | ||
| * Loop check | ||
| * @type {Boolean} | ||
| */ | ||
| this._visited = false; | ||
| }; | ||
| /** | ||
| * Creates intersection vertex | ||
| * @param {Number} x | ||
| * @param {Number} y | ||
| * @param {Number} distance | ||
| * @return {Vertex} | ||
| */ | ||
| Vertex.createIntersection = function(x, y, distance) { | ||
| var vertex = new Vertex(x, y); | ||
| vertex._distance = distance; | ||
| vertex._isIntersection = true; | ||
| vertex._isEntry = false; | ||
| return vertex; | ||
| }; | ||
| /** | ||
| * Mark as visited | ||
| */ | ||
| Vertex.prototype.visit = function() { | ||
| this._visited = true; | ||
| if (this._corresponding !== null && !this._corresponding._visited) { | ||
| this._corresponding.visit(); | ||
| } | ||
| }; | ||
| /** | ||
| * Convenience | ||
| * @param {Vertex} v | ||
| * @return {Boolean} | ||
| */ | ||
| Vertex.prototype.equals = function(v) { | ||
| return this.x === v.x && this.y === v.y; | ||
| }; | ||
| /** | ||
| * Check if vertex is inside a polygon by odd-even rule: | ||
| * If the number of intersections of a ray out of the point and polygon | ||
| * segments is odd - the point is inside. | ||
| * @param {Polygon} poly | ||
| * @return {Boolean} | ||
| */ | ||
| Vertex.prototype.isInside = function(poly) { | ||
| var oddNodes = false, | ||
| vertex = poly.first, | ||
| next = vertex.next, | ||
| x = this.x, | ||
| y = this.y; | ||
| do { | ||
| if ((vertex.y < y && next.y >= y || | ||
| next.y < y && vertex.y >= y) && | ||
| (vertex.x <= x || next.x <= x)) { | ||
| oddNodes ^= (vertex.x + (y - vertex.y) / | ||
| (next.y - vertex.y) * (next.x - vertex.x) < x); | ||
| } | ||
| vertex = vertex.next; | ||
| next = vertex.next || poly.first; | ||
| } while (!vertex.equals(poly.first)); | ||
| return oddNodes; | ||
| }; | ||
| module.exports = Vertex; | ||
| },{}],6:[function(_dereq_,module,exports){ | ||
| "use strict"; | ||
@@ -40,6 +590,6 @@ | ||
| var inwards = this.inwardsNormal(); | ||
| return { | ||
| x: -inwards.x, | ||
| y: -inwards.y | ||
| }; | ||
| return [ | ||
| -inwards[0], | ||
| -inwards[1] | ||
| ]; | ||
| }; | ||
@@ -52,10 +602,10 @@ | ||
| Edge.prototype.inwardsNormal = function() { | ||
| var dx = this.next.x - this.current.x, | ||
| dy = this.next.y - this.current.y, | ||
| var dx = this.next[0] - this.current[0], | ||
| dy = this.next[1] - this.current[1], | ||
| edgeLength = Math.sqrt(dx * dx + dy * dy); | ||
| return { | ||
| x: -dy / edgeLength, | ||
| y: dx / edgeLength | ||
| }; | ||
| return [ | ||
| -dy / edgeLength, | ||
| dx / edgeLength | ||
| ]; | ||
| }; | ||
@@ -73,9 +623,9 @@ | ||
| return new Edge({ | ||
| x: current.x + dx, | ||
| y: current.y + dy | ||
| }, { | ||
| x: next.x + dx, | ||
| y: next.y + dy | ||
| }); | ||
| return new Edge([ | ||
| current[0] + dx, | ||
| current[1] + dy | ||
| ], [ | ||
| next[0] + dx, | ||
| next[1] + dy | ||
| ]); | ||
| }; | ||
@@ -85,3 +635,3 @@ | ||
| },{}],2:[function(require,module,exports){ | ||
| },{}],7:[function(_dereq_,module,exports){ | ||
| "use strict"; | ||
@@ -100,4 +650,4 @@ | ||
| module.exports = function intersection(A0, A1, B0, B1) { | ||
| var den = (B1.y - B0.y) * (A1.x - A0.x) - | ||
| (B1.x - B0.x) * (A1.y - A0.y); | ||
| var den = (B1[1] - B0[1]) * (A1[0] - A0[0]) - | ||
| (B1[0] - B0[0]) * (A1[1] - A0[1]); | ||
@@ -109,7 +659,7 @@ // lines are parallel or conincident | ||
| var ua = ((B1.x - B0.x) * (A0.y - B0.y) - | ||
| (B1.y - B0.y) * (A0.x - B0.x)) / den; | ||
| var ua = ((B1[0] - B0[0]) * (A0[1] - B0[1]) - | ||
| (B1[1] - B0[1]) * (A0[0] - B0[0])) / den; | ||
| var ub = ((A1.x - A0.x) * (A0.y - B0.y) - | ||
| (A1.y - A0.y) * (A0.x - B0.x)) / den; | ||
| var ub = ((A1[0] - A0[0]) * (A0[1] - B0[1]) - | ||
| (A1[1] - A0[1]) * (A0[0] - B0[0])) / den; | ||
@@ -120,12 +670,12 @@ if (ua < 0 || ub < 0 || ua > 1 || ub > 1) { | ||
| return { | ||
| x: A0.x + ua * (A1.x - A0.x), | ||
| y: A0.y + ua * (A1.y - A0.y) | ||
| }; | ||
| return [ | ||
| A0[0] + ua * (A1[0] - A0[0]), | ||
| A0[1] + ua * (A1[1] - A0[1]) | ||
| ]; | ||
| }; | ||
| },{}],3:[function(require,module,exports){ | ||
| var GreinerHormann = require('greiner-hormann'); | ||
| var Edge = require('./edge'); | ||
| var intersection = require('./intersection'); | ||
| },{}],8:[function(_dereq_,module,exports){ | ||
| var GreinerHormann = _dereq_('greiner-hormann'); | ||
| var Edge = _dereq_('./edge'); | ||
| var intersection = _dereq_('./intersection'); | ||
@@ -208,4 +758,4 @@ "use strict"; | ||
| var len = vertices.length; | ||
| if (vertices[0].x === vertices[len - 1].x && | ||
| vertices[0].y === vertices[len - 1].y) { | ||
| if (vertices[0][0] === vertices[len - 1][0] && | ||
| vertices[0][1] === vertices[len - 1][1]) { | ||
| vertices = vertices.slice(0, len - 1); | ||
@@ -232,4 +782,4 @@ this._closed = true; | ||
| var PI2 = Math.PI * 2, | ||
| startAngle = atan2(startVertex.y - center.y, startVertex.x - center.x), | ||
| endAngle = atan2(endVertex.y - center.y, endVertex.x - center.x); | ||
| startAngle = atan2(startVertex[1] - center[1], startVertex[0] - center[0]), | ||
| endAngle = atan2(endVertex[1] - center[1], endVertex[0] - center[0]); | ||
@@ -257,6 +807,6 @@ // odd number please | ||
| angle = startAngle + segmentAngle * i; | ||
| vertices.push({ | ||
| x: center.x + Math.cos(angle) * radius, | ||
| y: center.y + Math.sin(angle) * radius | ||
| }); | ||
| vertices.push([ | ||
| center[0] + Math.cos(angle) * radius, | ||
| center[1] + Math.sin(angle) * radius | ||
| ]); | ||
| } | ||
@@ -279,4 +829,4 @@ vertices.push(endVertex); | ||
| var edge = this.edges[i], | ||
| dx = edge._outNormal.x * dist, | ||
| dy = edge._outNormal.y * dist; | ||
| dx = edge._outNormal[0] * dist, | ||
| dy = edge._outNormal[1] * dist; | ||
| offsetEdges.push(edge.offset(dx, dy)); | ||
@@ -325,4 +875,4 @@ } | ||
| var edge = this.edges[i], | ||
| dx = edge._inNormal.x * dist, | ||
| dy = edge._inNormal.y * dist; | ||
| dx = edge._inNormal[0] * dist, | ||
| dy = edge._inNormal[1] * dist; | ||
@@ -374,6 +924,6 @@ offsetEdges.push(edge.offset(dx, dy)); | ||
| if (this._closed) { | ||
| vertices.push({ | ||
| x: vertices[0].x, | ||
| y: vertices[0].y | ||
| }); | ||
| vertices.push([ | ||
| vertices[0][0], | ||
| vertices[0][1] | ||
| ]); | ||
| } | ||
@@ -397,3 +947,4 @@ return vertices; | ||
| },{"./edge":1,"./intersection":2,"greiner-hormann":undefined}]},{},[3])(3) | ||
| },{"./edge":6,"./intersection":7,"greiner-hormann":2}]},{},[8]) | ||
| (8) | ||
| }); |
+5
-4
| var L = require('leaflet'); | ||
| //var Offset = require('../src/offset'); | ||
| var Offset = require('../src/offset'); | ||
@@ -58,3 +58,4 @@ var points = [ | ||
| vertices = points.map(function(p) { | ||
| return map.options.crs.latLngToPoint(L.latLng(p), map.getZoom()); | ||
| var pt = map.options.crs.latLngToPoint(L.latLng(p), map.getZoom()); | ||
| return [pt.x, pt.y]; | ||
| }); | ||
@@ -66,3 +67,3 @@ | ||
| result = result.map(function(p) { | ||
| return map.options.crs.pointToLatLng(p, map.getZoom()); | ||
| return map.options.crs.pointToLatLng(L.point(p), map.getZoom()); | ||
| }); | ||
@@ -75,5 +76,5 @@ | ||
| result = result.map(function(p) { | ||
| return map.options.crs.pointToLatLng(p, map.getZoom()); | ||
| return map.options.crs.pointToLatLng(L.point(p), map.getZoom()); | ||
| }); | ||
| L.polygon(result, paddingStyle).addTo(map); |
@@ -24,2 +24,3 @@ body,html{margin:0;padding:0;width:100%;height:100%}/* required styles */ | ||
| -ms-touch-action: none; | ||
| touch-action: none; | ||
| } | ||
@@ -26,0 +27,0 @@ .leaflet-tile, |
+1
-1
@@ -6,3 +6,3 @@ <!DOCTYPE html> | ||
| <link type="text/css" href="example/style.css" rel="stylesheet"> | ||
| <script src="dist/offset.min.js"></script> | ||
| <!--<script src="dist/offset.min.js"></script>--> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> | ||
@@ -9,0 +9,0 @@ </head> |
+38
-38
| { | ||
| "name": "polygon-offset", | ||
| "version": "0.0.5", | ||
| "description": "Polygon offsetting algorithm, aimed for use with leaflet", | ||
| "main": "src/offset.js", | ||
| "keywords": [ | ||
| "polygon", | ||
| "offset", | ||
| "algorithm", | ||
| "scale", | ||
| "margin", | ||
| "padding" | ||
| ], | ||
| "author": "Alexander Milevski <info@w8r.name>", | ||
| "license": "MIT", | ||
| "devDependencies": { | ||
| "catw": "^0.2.0", | ||
| "leaflet": "^0.7.3", | ||
| "less": "^2.0.0", | ||
| "serve": "^1.4.0", | ||
| "watchify": "^2.1.1" | ||
| }, | ||
| "scripts": { | ||
| "watch-css": "catw -c 'lessc -' 'example/*.less' -o example/style.css -v", | ||
| "watch-js": "watchify example/app.js -o example/bundle.js -dv", | ||
| "watch": "npm run watch-css & npm run watch-js", | ||
| "build-css": "catw -c 'lessc -' 'example/*.less' > example/style.css", | ||
| "build-js": "browserify -s Offset src/offset.js > dist/offset.js", | ||
| "build": "npm run build-css && npm run build-js", | ||
| "start": "npm run watch & serve", | ||
| "test": "node test/test.js" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/w8r/polygon-offset.git" | ||
| }, | ||
| "dependencies": { | ||
| "greiner-hormann": "^1.2.0" | ||
| } | ||
| "name": "polygon-offset", | ||
| "version": "0.1.0", | ||
| "description": "Polygon offsetting algorithm, aimed for use with leaflet", | ||
| "main": "src/offset.js", | ||
| "keywords": [ | ||
| "polygon", | ||
| "offset", | ||
| "algorithm", | ||
| "scale", | ||
| "margin", | ||
| "padding" | ||
| ], | ||
| "author": "Alexander Milevski <info@w8r.name>", | ||
| "license": "MIT", | ||
| "devDependencies": { | ||
| "catw": "^0.2.0", | ||
| "leaflet": "^0.7.3", | ||
| "less": "^2.0.0", | ||
| "serve": "^1.4.0", | ||
| "watchify": "^2.1.1" | ||
| }, | ||
| "scripts": { | ||
| "watch-css": "catw -c 'lessc -' 'example/*.less' -o example/style.css -v", | ||
| "watch-js": "watchify example/app.js -o example/bundle.js -dv", | ||
| "watch": "npm run watch-css & npm run watch-js", | ||
| "build-css": "catw -c 'lessc -' 'example/*.less' > example/style.css", | ||
| "build-js": "browserify -s Offset src/offset.js > dist/offset.js", | ||
| "build": "npm run build-css && npm run build-js", | ||
| "start": "npm run watch & serve", | ||
| "test": "node test/test.js" | ||
| }, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "https://github.com/w8r/polygon-offset.git" | ||
| }, | ||
| "dependencies": { | ||
| "greiner-hormann": "^1.2.0" | ||
| } | ||
| } |
+5
-4
@@ -34,5 +34,6 @@ # Offset | ||
| var points = [ | ||
| {x:0, y: 0}, {x: 100, y:0}, | ||
| {x: 100, y:100}, {x: 0, y: 100}, | ||
| {x:0, y:0}], x = -10; | ||
| [0,0], [0,100], | ||
| [100,100], [100,0], [0,0] | ||
| ]; | ||
| var x = -10; | ||
@@ -78,3 +79,3 @@ var offset = new Offset(); | ||
| Copyright (c) 2014 Alexander Milevski | ||
| Copyright (c) 2015 Alexander Milevski | ||
@@ -81,0 +82,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of |
+17
-17
@@ -39,6 +39,6 @@ "use strict"; | ||
| var inwards = this.inwardsNormal(); | ||
| return { | ||
| x: -inwards.x, | ||
| y: -inwards.y | ||
| }; | ||
| return [ | ||
| -inwards[0], | ||
| -inwards[1] | ||
| ]; | ||
| }; | ||
@@ -51,10 +51,10 @@ | ||
| Edge.prototype.inwardsNormal = function() { | ||
| var dx = this.next.x - this.current.x, | ||
| dy = this.next.y - this.current.y, | ||
| var dx = this.next[0] - this.current[0], | ||
| dy = this.next[1] - this.current[1], | ||
| edgeLength = Math.sqrt(dx * dx + dy * dy); | ||
| return { | ||
| x: -dy / edgeLength, | ||
| y: dx / edgeLength | ||
| }; | ||
| return [ | ||
| -dy / edgeLength, | ||
| dx / edgeLength | ||
| ]; | ||
| }; | ||
@@ -72,11 +72,11 @@ | ||
| return new Edge({ | ||
| x: current.x + dx, | ||
| y: current.y + dy | ||
| }, { | ||
| x: next.x + dx, | ||
| y: next.y + dy | ||
| }); | ||
| return new Edge([ | ||
| current[0] + dx, | ||
| current[1] + dy | ||
| ], [ | ||
| next[0] + dx, | ||
| next[1] + dy | ||
| ]); | ||
| }; | ||
| module.exports = Edge; |
+10
-10
@@ -14,4 +14,4 @@ "use strict"; | ||
| module.exports = function intersection(A0, A1, B0, B1) { | ||
| var den = (B1.y - B0.y) * (A1.x - A0.x) - | ||
| (B1.x - B0.x) * (A1.y - A0.y); | ||
| var den = (B1[1] - B0[1]) * (A1[0] - A0[0]) - | ||
| (B1[0] - B0[0]) * (A1[1] - A0[1]); | ||
@@ -23,7 +23,7 @@ // lines are parallel or conincident | ||
| var ua = ((B1.x - B0.x) * (A0.y - B0.y) - | ||
| (B1.y - B0.y) * (A0.x - B0.x)) / den; | ||
| var ua = ((B1[0] - B0[0]) * (A0[1] - B0[1]) - | ||
| (B1[1] - B0[1]) * (A0[0] - B0[0])) / den; | ||
| var ub = ((A1.x - A0.x) * (A0.y - B0.y) - | ||
| (A1.y - A0.y) * (A0.x - B0.x)) / den; | ||
| var ub = ((A1[0] - A0[0]) * (A0[1] - B0[1]) - | ||
| (A1[1] - A0[1]) * (A0[0] - B0[0])) / den; | ||
@@ -34,6 +34,6 @@ if (ua < 0 || ub < 0 || ua > 1 || ub > 1) { | ||
| return { | ||
| x: A0.x + ua * (A1.x - A0.x), | ||
| y: A0.y + ua * (A1.y - A0.y) | ||
| }; | ||
| return [ | ||
| A0[0] + ua * (A1[0] - A0[0]), | ||
| A0[1] + ua * (A1[1] - A0[1]) | ||
| ]; | ||
| }; |
+16
-16
@@ -81,4 +81,4 @@ var GreinerHormann = require('greiner-hormann'); | ||
| var len = vertices.length; | ||
| if (vertices[0].x === vertices[len - 1].x && | ||
| vertices[0].y === vertices[len - 1].y) { | ||
| if (vertices[0][0] === vertices[len - 1][0] && | ||
| vertices[0][1] === vertices[len - 1][1]) { | ||
| vertices = vertices.slice(0, len - 1); | ||
@@ -105,4 +105,4 @@ this._closed = true; | ||
| var PI2 = Math.PI * 2, | ||
| startAngle = atan2(startVertex.y - center.y, startVertex.x - center.x), | ||
| endAngle = atan2(endVertex.y - center.y, endVertex.x - center.x); | ||
| startAngle = atan2(startVertex[1] - center[1], startVertex[0] - center[0]), | ||
| endAngle = atan2(endVertex[1] - center[1], endVertex[0] - center[0]); | ||
@@ -130,6 +130,6 @@ // odd number please | ||
| angle = startAngle + segmentAngle * i; | ||
| vertices.push({ | ||
| x: center.x + Math.cos(angle) * radius, | ||
| y: center.y + Math.sin(angle) * radius | ||
| }); | ||
| vertices.push([ | ||
| center[0] + Math.cos(angle) * radius, | ||
| center[1] + Math.sin(angle) * radius | ||
| ]); | ||
| } | ||
@@ -152,4 +152,4 @@ vertices.push(endVertex); | ||
| var edge = this.edges[i], | ||
| dx = edge._outNormal.x * dist, | ||
| dy = edge._outNormal.y * dist; | ||
| dx = edge._outNormal[0] * dist, | ||
| dy = edge._outNormal[1] * dist; | ||
| offsetEdges.push(edge.offset(dx, dy)); | ||
@@ -198,4 +198,4 @@ } | ||
| var edge = this.edges[i], | ||
| dx = edge._inNormal.x * dist, | ||
| dy = edge._inNormal.y * dist; | ||
| dx = edge._inNormal[0] * dist, | ||
| dy = edge._inNormal[1] * dist; | ||
@@ -247,6 +247,6 @@ offsetEdges.push(edge.offset(dx, dy)); | ||
| if (this._closed) { | ||
| vertices.push({ | ||
| x: vertices[0].x, | ||
| y: vertices[0].y | ||
| }); | ||
| vertices.push([ | ||
| vertices[0][0], | ||
| vertices[0][1] | ||
| ]); | ||
| } | ||
@@ -253,0 +253,0 @@ return vertices; |
+5
-17
| var Offset = require('../src/offset'); | ||
| // CCW | ||
| var points = [{ | ||
| x: 0, | ||
| y: 0 | ||
| }, { | ||
| x: 0, | ||
| y: 100 | ||
| }, { | ||
| x: 100, | ||
| y: 100 | ||
| }, { | ||
| x: 100, | ||
| y: 0 | ||
| }, { | ||
| x: 0, | ||
| y: 0 | ||
| }], | ||
| x = -10; | ||
| var points = [ | ||
| [0,0], [0,100], | ||
| [100,100], [100,0], [0,0] | ||
| ]; | ||
| var x = -10; | ||
@@ -22,0 +10,0 @@ var offset = new Offset(); |
Sorry, the diff of this file is too big to display
777036
11.32%12166
13.13%99
1.02%