{"version":3,"file":"PolygonUtils.mjs","sources":["../../src/utils/PolygonUtils.ts"],"sourcesContent":["/**\n * Utilities for polygon\n * @class\n * @private\n */\nexport class PolygonUtils\n{\n    /**\n     * Calculate points of an offset polygon\n     * @see {@link http://csharphelper.com/blog/2016/01/enlarge-a-polygon-in-c/}\n     * @private\n     * @param {number[]} points - polygon coordinates\n     * @param {number} offset\n     * @returns {number[]} - offset points\n     */\n    static offsetPolygon(points: number[], offset: number): number[]\n    {\n        const offsetPoints: number[] = [];\n        const length: number = points.length;\n\n        offset = PolygonUtils.isPolygonClockwise(points) ? offset : -1 * offset;\n\n        for (let j = 0; j < length; j += 2)\n        {\n            // Find location for the points before and after j\n            let i = (j - 2);\n\n            if (i < 0)\n            {\n                i += length;\n            }\n\n            const k = (j + 2) % length;\n\n            // Move the points by the offset\n            let v1x = points[j] - points[i];\n            let v1y = points[j + 1] - points[i + 1];\n            let len = Math.sqrt((v1x * v1x) + (v1y * v1y));\n\n            v1x /= len;\n            v1y /= len;\n            v1x *= offset;\n            v1y *= offset;\n\n            const norm1x = -v1y;\n            const norm1y = v1x;\n\n            const pij1 = [points[i] + norm1x, points[i + 1] + norm1y];\n            const pij2 = [points[j] + norm1x, points[j + 1] + norm1y];\n\n            let v2x = points[k] - points[j];\n            let v2y = points[k + 1] - points[j + 1];\n\n            len = Math.sqrt((v2x * v2x) + (v2y * v2y));\n\n            v2x /= len;\n            v2y /= len;\n            v2x *= offset;\n            v2y *= offset;\n\n            const norm2x = -v2y;\n            const norm2y = v2x;\n\n            const pjk1 = [points[j] + norm2x, points[j + 1] + norm2y];\n            const pjk2 = [points[k] + norm2x, points[k + 1] + norm2y];\n\n            // Find where the shifted lines ij and jk intersect.\n            const intersectPoint = PolygonUtils\n                .findIntersection(pij1[0], pij1[1], pij2[0], pij2[1], pjk1[0], pjk1[1], pjk2[0], pjk2[1]);\n\n            if (intersectPoint)\n            {\n                offsetPoints.push(...intersectPoint);\n            }\n        }\n\n        return offsetPoints;\n    }\n\n    /**\n     * Determine the intersection point of two line segments\n     * @see {@link here http://paulbourke.net/geometry/pointlineplane/}\n     * @private\n     * @param {number} x1 - x-coordinate of start point at first line\n     * @param {number} y1 - y-coordinate of start point at first line\n     * @param {number} x2 - x-coordinate of end point at first line\n     * @param {number} y2 - y-coordinate of end point at first line\n     * @param {number} x3 - x-coordinate of start point at second line\n     * @param {number} y3 - y-coordinate of start point at second line\n     * @param {number} x4 - x-coordinate of end point at second line\n     * @param {number} y4 - y-coordinate of end point at second line\n     * @returns [x, y] coordinates of intersection\n     */\n    static findIntersection(\n        x1: number, y1: number, x2: number, y2: number,\n        x3: number, y3: number, x4: number, y4: number\n    ): [number, number] | null\n    {\n        const denominator = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));\n        const numeratorA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));\n        const numeratorB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));\n\n        // lines are parallel\n        if (denominator === 0)\n        {\n            // lines are coincident\n            if (numeratorA === 0 && numeratorB === 0)\n            {\n                return [(x1 + x2) / 2, (y1 + y2) / 2];\n            }\n\n            return null;\n        }\n\n        const uA = numeratorA / denominator;\n\n        return [x1 + (uA * (x2 - x1)), y1 + (uA * (y2 - y1))];\n    }\n\n    /**\n     * Determine polygon are clockwise or counterclockwise\n     * @see {@link https://stackoverflow.com/questions/1165647}\n     * @private\n     * @param {number[]} polygon - polygon coordinates\n     * @returns {boolean} - true if polygon is clockwise\n     */\n    static isPolygonClockwise(polygon: number[]): boolean\n    {\n        let sum = 0;\n\n        for (let i = 0, j = polygon.length - 2; i < polygon.length; j = i, i += 2)\n        {\n            sum += (polygon[i] - polygon[j]) * (polygon[i + 1] + polygon[j + 1]);\n        }\n\n        return sum > 0;\n    }\n}\n"],"names":[],"mappings":"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"}