From 6c7be85d7e208a2b100c3bce10380ada8f9d7e32 Mon Sep 17 00:00:00 2001 From: Z3 Development Date: Sun, 14 Jan 2024 13:59:26 +0900 Subject: [PATCH] fix(modeling): added orientation option to polygon --- packages/modeling/src/primitives/polygon.d.ts | 1 + packages/modeling/src/primitives/polygon.js | 19 +++++++++++++++---- .../modeling/src/primitives/polygon.test.js | 10 ++++++++++ 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/packages/modeling/src/primitives/polygon.d.ts b/packages/modeling/src/primitives/polygon.d.ts index a35c4ee75..bc3806505 100644 --- a/packages/modeling/src/primitives/polygon.d.ts +++ b/packages/modeling/src/primitives/polygon.d.ts @@ -6,6 +6,7 @@ export default polygon export interface PolygonOptions { points: Array | Array> paths?: Array | Array> + orientation?: 'counterclockwise' | 'clockwise' } declare function polygon(options: PolygonOptions): Geom2 diff --git a/packages/modeling/src/primitives/polygon.js b/packages/modeling/src/primitives/polygon.js index dbd5b0f08..fb752ae8e 100644 --- a/packages/modeling/src/primitives/polygon.js +++ b/packages/modeling/src/primitives/polygon.js @@ -2,10 +2,13 @@ const geom2 = require('../geometries/geom2') /** * Construct a polygon in two dimensional space from a list of points, or a list of points and paths. - * NOTE: The ordering of points is VERY IMPORTANT. + * + * NOTE: The ordering of points is important, and must define a counter clockwise rotation of points. + * * @param {Object} options - options for construction * @param {Array} options.points - points of the polygon : either flat or nested array of 2D points * @param {Array} [options.paths] - paths of the polygon : either flat or nested array of point indexes + * @param {String} [options.orientation='counterclockwise'] - orientation of points * @returns {geom2} new 2D geometry * @alias module:modeling/primitives.polygon * @@ -24,9 +27,10 @@ const geom2 = require('../geometries/geom2') const polygon = (options) => { const defaults = { points: [], - paths: [] + paths: [], + orientation: 'counterclockwise' } - const { points, paths } = Object.assign({}, defaults, options) + const { points, paths, orientation } = Object.assign({}, defaults, options) if (!(Array.isArray(points) && Array.isArray(paths))) throw new Error('points and paths must be arrays') @@ -58,13 +62,20 @@ const polygon = (options) => { const allpoints = [] listofpolys.forEach((list) => list.forEach((point) => allpoints.push(point))) + // convert the list of paths into a list of sides, and accumulate let sides = [] listofpaths.forEach((path) => { const setofpoints = path.map((index) => allpoints[index]) const geometry = geom2.fromPoints(setofpoints) sides = sides.concat(geom2.toSides(geometry)) }) - return geom2.create(sides) + + // convert the list of sides into a geometry + let geometry = geom2.create(sides) + if (orientation == "clockwise") { + geometry = geom2.reverse(geometry) + } + return geometry } module.exports = polygon diff --git a/packages/modeling/src/primitives/polygon.test.js b/packages/modeling/src/primitives/polygon.test.js index 28168ae4d..a1c45fa58 100644 --- a/packages/modeling/src/primitives/polygon.test.js +++ b/packages/modeling/src/primitives/polygon.test.js @@ -1,6 +1,7 @@ const test = require('ava') const geom2 = require('../geometries/geom2') +const measureArea = require('../measurements/measureArea') const { polygon } = require('./index') @@ -51,3 +52,12 @@ test('polygon: providing object.points (array) and object.path (array) creates e t.notThrows(() => geom2.validate(geometry)) t.true(comparePoints(obs, exp)) }) + +test('polygon: clockwise points', (t) => { + const poly = polygon({ + points: [[-10, -0], [-10, -10], [-15, -5]], + orientation: "clockwise", + }) + t.is(poly.sides.length, 3) + t.is(measureArea(poly), 25) +})