Skip to content

Instantly share code, notes, and snippets.

@kapraran
Created February 17, 2021 14:33
Show Gist options
  • Save kapraran/d2b80a80bd11077352c75f671c3ca057 to your computer and use it in GitHub Desktop.
Save kapraran/d2b80a80bd11077352c75f671c3ca057 to your computer and use it in GitHub Desktop.
// https://observablehq.com/@scarysize/finding-random-points-in-a-polygon
const pointsOutput =
`
{ Vec2(191.36773681641, -896.60498046875), Vec2(455.9482421875, -696.60577392578), Vec2(584.68591308594, -1235.2385253906), Vec2(-316.11657714844, -1357.7646484375), Vec2(-316.51806640625, -815.22882080078), Vec2(-179.95001220703, -968.591796875), }
`
const earcut = require('earcut')
/* https://en.wikipedia.org/wiki/Shoelace_formula */
function getTriangleArea(triangle) {
const [a, b, c] = triangle;
return 0.5 * (
(b[0] - a[0]) * (c[1] - a[1]) -
(c[0] - a[0]) * (b[1] - a[1])
);
}
function generateDistribution(triangles) {
const totalArea = triangles.reduce((sum, triangle) => sum + getTriangleArea(triangle), 0);
const cumulativeDistribution = [];
for (let i = 0; i < triangles.length; i++) {
const lastValue = cumulativeDistribution[i - 1] || 0;
const nextValue = lastValue + getTriangleArea(triangles[i]) / totalArea;
cumulativeDistribution.push(nextValue);
}
// [area1, area1 + aera2, area1 + area2 + area3, ...]
return cumulativeDistribution;
}
function extractPoints(output) {
const params = [...output.matchAll(/Vec2\((([^\,]*)\,([^\,]*))\)/g)]
return params.reduce((points, param) => {
points.push([parseFloat(param[2]), parseFloat(param[3])])
return points
}, [])
}
function extractTriangles(points) {
const triangleIndexes = earcut(points.flat())
return new Array(triangleIndexes.length / 3).fill(0).map((v, i) => ([
points[triangleIndexes[i * 3]],
points[triangleIndexes[i * 3 + 1]],
points[triangleIndexes[i * 3 + 2]]
])
)
}
function generateLuaConfigCode(triangles, cumulativeDistribution) {
const trianglesStr = triangles.map(triangle => {
return `{ ${triangle.map(point => `Vec2(${point[0]} , ${point[1]})`).join(', ')} }`
})
console.log(`Triangles = { ${trianglesStr.join(', ')} }`)
console.log(`CumulativeDistribution = { ${cumulativeDistribution.join(', ')} }`)
}
function main() {
const points = extractPoints(pointsOutput)
const triangles = extractTriangles(points)
const cumulativeDistribution = generateDistribution(triangles)
generateLuaConfigCode(triangles, cumulativeDistribution)
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment