Created
September 20, 2019 10:57
-
-
Save scriptify/80bcb8f4f3e878c5f064cc48dc905017 to your computer and use it in GitHub Desktop.
Calculates the area of a polygon in 3D space
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//determinant of matrix a | |
function det(a) { | |
return ( | |
a[0][0] * a[1][1] * a[2][2] + | |
a[0][1] * a[1][2] * a[2][0] + | |
a[0][2] * a[1][0] * a[2][1] - | |
a[0][2] * a[1][1] * a[2][0] - | |
a[0][1] * a[1][0] * a[2][2] - | |
a[0][0] * a[1][2] * a[2][1] | |
); | |
} | |
//unit normal vector of plane defined by points a, b, and c | |
function unit_normal(a, b, c) { | |
let x = det([[1, a[1], a[2]], [1, b[1], b[2]], [1, c[1], c[2]]]); | |
let y = det([[a[0], 1, a[2]], [b[0], 1, b[2]], [c[0], 1, c[2]]]); | |
let z = det([[a[0], a[1], 1], [b[0], b[1], 1], [c[0], c[1], 1]]); | |
let magnitude = Math.pow( | |
Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2), | |
0.5 | |
); | |
return [x / magnitude, y / magnitude, z / magnitude]; | |
} | |
// dot product of vectors a and b | |
function dot(a, b) { | |
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; | |
} | |
// cross product of vectors a and b | |
function cross(a, b) { | |
let x = a[1] * b[2] - a[2] * b[1]; | |
let y = a[2] * b[0] - a[0] * b[2]; | |
let z = a[0] * b[1] - a[1] * b[0]; | |
return [x, y, z]; | |
} | |
// area of polygon poly | |
export default function calculatePolygonArea(poly) { | |
if (poly.length < 3) { | |
console.log("not a plane - no area"); | |
return 0; | |
} else { | |
let total = [0, 0, 0]; | |
for (let i = 0; i < poly.length; i++) { | |
var vi1 = poly[i]; | |
if (i === poly.length - 1) { | |
var vi2 = poly[0]; | |
} else { | |
var vi2 = poly[i + 1]; | |
} | |
let prod = cross(vi1, vi2); | |
total[0] = total[0] + prod[0]; | |
total[1] = total[1] + prod[1]; | |
total[2] = total[2] + prod[2]; | |
} | |
let result = dot(total, unit_normal(poly[0], poly[1], poly[2])); | |
return Math.abs(result / 2); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This seems to work pretty well, too. https://math.stackexchange.com/questions/3207981/caculate-area-of-polygon-in-3d
Calculated polygons in excel with this formula. If the points aren't to far away from the plane this should work pretty well.