# Can't understand why result is a triangle instead of rectangle when creating 3d polygon

I am relatively new to Three.JS and tried to implement something to build polygons in 3D space. I tried using earcut library to triangulate points - did not help that much, tried to use Hull.js, which did work, but only with convex shapes.
After a while I found solution that was provided by @prisoner849 and for some sets of points it worked perfectly, but for some not.
Live code example
As far as I understand this solution, there should be a rectangle here, not a triangle.
For this set of points it build rectangle as expected:

``````[
{
"x": 2.6443464756011963,
"y": 1.637024998664856,
"z": -3.753018856048584
},
{
"x": -2.3420379161834717,
"y": 1.637024998664856,
"z": -3.2846970558166504
},
{
"x": -3.70695424079895,
"y": 1.637024998664856,
"z": -6.309837818145752
},
{
"x": 0.8760173916816711,
"y": 1.637024998664856,
"z": -8.244649887084961
}
]
``````

How to change the code so example in the fiddle would build a rectangle?

``````  const vertices = new Float32Array([
-3.70695424079895, -1.5, -6.309837818145752,  // A
-3.70695424079895,  1.637024998664856, -6.309837818145752,  // B
0.8760173916816711, -1.5, -8.244649887084961,  // C
0.8760173916816711,  1.637024998664856, -8.244649887084961   // D
]);

const indices = new Uint16Array([
0, 1, 2,  // Triangle 1: A -> B -> C
2, 1, 3   // Triangle 2: C -> B -> D
]);

// UV-Coordinates
const uvs = new Float32Array([
0, 0,  // UV A
0, 1,  // UV B
1, 0,  // UV C
1, 1   // UV D
]);

//BufferGeometry
const geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));
geometry.setIndex(new THREE.BufferAttribute(indices, 1));

const material = new THREE.MeshBasicMaterial({ map: texture, side: THREE.DoubleSide });

const mesh = new THREE.Mesh(geometry, material);
``````

I kept the example as short as possible, so no normal ones.
A polygon consists of 2 triangles. Therefore you have to set the indices for your geometry. `geometry.setIndex(new THREE.BufferAttribute(indices, 1));`

With 0, 1, 2, 2, 1, 3 the two triangles are set in a clockwise direction. You can set the order counterclockwise. This decides which side is outside and inside.

Thatâ€™s how I started back then too
I hope it helps. Iâ€™ll leave it up to you to add the normal ones

2 Likes

Or maybe just try changing the raw points in that live example to this:

``````var rawPoints = [
{
"x": -3.70695424079895,
"y": -1.5,
"z": -6.309837818145752
},
{
"x": -3.70695424079895,
"y": 1.637024998664856,
"z": -6.309837818145752
},
{
"x": 0.8760173916816711,
"y": 1.637024998664856,
"z": -6.309837818145752
},
{
"x": 0.8760173916816711,
"y": -1.5,
"z": -6.309837818145752
}
]
``````
2 Likes

GitHubDragonFlys way is the better option if the original code is preferred.

More generallyâ€¦ in threejs there arenâ€™t quads. There are only triangles. To make a quad, you make 2 triangles, but share 2 of the verts between the triangles via the .index as in @Attila_Schroeder s example.

Or instead output 6 vertices if you donâ€™t want to use an index.

So order do matter in that case. I was looking at the Shape class, and read somewhere about automatic triangulation it performs when created. But how to sort it then? I have a camera position at (0,0,0), I assume it is clockwise order, so I sort like this:

``````const copy = points.map(p => p.clone());
return copy.sort((a, b) => Math.atan2(a.y, a.x) - Math.atan2(b.y, b.x));
``````

But itâ€™s incorrect anyway, because there is no such thing as clockwise order in 3d space.
And I think you unintentially set all z-indexes to the same value, I tried to simply reorder points at index 2 and 3, and it worked:

``````var rawPoints = [
{
"x": -3.70695424079895,
"y": -1.5,
"z": -6.309837818145752
},
{
"x": -3.70695424079895,
"y": 1.637024998664856,
"z": -6.309837818145752
},
{
"x": 0.8760173916816711,
"y": 1.637024998664856,
"z": -8.244649887084961
},
{
"x": 0.8760173916816711,
"y": -1.5,
"z": -8.244649887084961
}
]
``````

So I guess I just need to came up with some sophisticated method to sort points?

`````` 0---1---2---3
| \ | \ | \ |
4---5---6---7
| \ | \ | \ |
8---9--10--11
| \ | \ | \ |
12--13--14--15

5, 4, 0, 0, 1, 5, 6, 5, 1, 1, 2, 6, 7, 6, 2, 2, 3, 7 ... is clockwise
0, 4, 5, 5, 1, 0, 1, 5, 6, 6, 2, 1, 2, 6, 7, 7, 3, 2 ... is counter clockwise
``````

The clockwise and counterclockwise topic refers to the order of your vertices in your vertex array. Since you want to create an area with your vertices, you automatically define a local orientation within the area. And now how you define the triangles in it with the index order cw or ccw defines inside and outside. It doesnâ€™t matter where you start a triangle 0, 5, 4 or 5, 4, 0 or 4, 0, 5 for the first triangle cw makes the same triangle

1 Like

Here you can see the arrangement of the vertices and triangles for the three.js base geometries.

NumberingHelperExamples

1 Like

Clockwise exists in 3d. If youâ€™re facing the triangle from itâ€™s front side, the vertices are declared clockwise. If they arenâ€™t clockwise, youâ€™re facing the back side.

2 Likes