Skip to content

Commit

Permalink
fix(modeling): added orientation option to polygon
Browse files Browse the repository at this point in the history
  • Loading branch information
z3dev authored Jan 14, 2024
1 parent ce1b679 commit 6c7be85
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
1 change: 1 addition & 0 deletions packages/modeling/src/primitives/polygon.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default polygon
export interface PolygonOptions {
points: Array<Vec2> | Array<Array<Vec2>>
paths?: Array<number> | Array<Array<number>>
orientation?: 'counterclockwise' | 'clockwise'
}

declare function polygon(options: PolygonOptions): Geom2
19 changes: 15 additions & 4 deletions packages/modeling/src/primitives/polygon.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand All @@ -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')

Expand Down Expand Up @@ -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
10 changes: 10 additions & 0 deletions packages/modeling/src/primitives/polygon.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const test = require('ava')

const geom2 = require('../geometries/geom2')
const measureArea = require('../measurements/measureArea')

const { polygon } = require('./index')

Expand Down Expand Up @@ -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)
})

0 comments on commit 6c7be85

Please sign in to comment.