Makarov
Makarov

Reputation: 187

Three.js Calculate the Area of Geometry Face (Face3)

I am exporting a 3D model with the ColladaLoader, every Mesh create a Geometry object with multiple Faces.

I manage to select faces to change colors and textures of a single face that is an array of Triangles (Face3). Change color of single face of a Mesh

Change texture of single face of a Mesh

Know I need to get the area of each "Face" I know the faces are a sum of Triangles instances of Face3. I try looping through each related face and summing the a, b and c values like this, but with no luck.

var sAB = Math.abs(face.a - face.b);
var sBC = Math.abs(face.b - face.c);
var sCA = Math.abs(face.c - face.a);
var s = sAB + sBC + sCA;
var a = Math.sqrt(s*(s-sAB)*(s-sBC)*(s-sCA));

How can a calculate the Area of a Face3 triangle object?

Upvotes: 4

Views: 5044

Answers (4)

Wilt
Wilt

Reputation: 44346

THREE.ShapeUtils comes with a convenience method getArea where you pass an array of points/vertices of a 2D polygon:

.area ( contour ) : Number

contour -- 2D polygon.

Calculate area of a ( 2D ) contour polygon.

This method more or less the same as in @pailhead his answer but works for a polygon with several points instead of only three points (a triangle).

To be able to use this for vertices that are not in the X-Y plane (from a 3D mesh) you would need to rotate/project your mesh first so it ends up in the X-Y plane. You can easily do that with a rotation matrix.


Note: Be aware that this method uses a method that comes with limitations for self-intersecting polygons. Check also the Limitations chapter on this "Math Open Reference" page for reference.

Upvotes: 2

pailhead
pailhead

Reputation: 5431

To add to the other two answers, mathematically, if you do a cross product of two vectors, the length of the resulting vector will be twice the area you are looking for. In three.js speak:

new THREE.Vector3().crossVectors(
 new THREE.Vector3().subVectors( vertexB, vertexA ),
 new THREE.Vector3().subVectors( vertexC, vertexA ),
).length() / 2 

Upvotes: 3

Martin Schuhfuß
Martin Schuhfuß

Reputation: 6986

The values a, b and c of the Face3 do not store the actual vertices. Instead, the indices of the vertices in geometry.vertices are stored there. So to retrieve the three vertices you need something like this:

var va = geometry.vertices[face.a];
var vb = geometry.vertices[face.b];
var vc = geometry.vertices[face.c];

The calculations you are using do not work that way when dealing with vectors. You need to use the functions from THREE.Vector3 (for instance var v = new THREE.Vector3(); v.subVectors(va, vb);) to do these calculations.

Alternatively, there is a class THREE.Triangle that you can use for that:

var t = new THREE.Triangle(va,vb,vc);
var area = t.getArea();

Upvotes: 5

prisoner849
prisoner849

Reputation: 17586

You can use THREE.Triangle() and its .getArea() method:

var geom = new THREE.PlaneGeometry(1, 1);

var face0 = geom.faces[0]; // you know what face, you want to get its area

var verts = geom.vertices;

var tri = new THREE.Triangle(verts[face0.a], verts[face0.b], verts[face0.c]);

var area = tri.getArea();
console.log(area);
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/93/three.min.js"></script>

Upvotes: 3

Related Questions