Cartesian coordinates of a regular tetrahedron

Post your questions, suggestions and experiences regarding to Image manipulation, 3d modeling and level editing for the Irrlicht engine here.
Post Reply
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Cartesian coordinates of a regular tetrahedron

Post by randomMesh »

I am trying to render a regular tetrahedron via drawVertexPrimitiveList().

The wikipedia article says the coordinates are
  • (1, 1, 1)
    (−1, −1, 1)
    (−1, 1, −1)
    (1, −1, −1)

Code: Select all

vertices[0].Pos = core::vector3df(halfSize, halfSize, halfSize);
vertices[1].Pos = core::vector3df(-halfSize, -halfSize, halfSize);
vertices[2].Pos = core::vector3df(-halfSize, halfSize, -halfSize);
vertices[3].Pos = core::vector3df(halfSize, -halfSize, -halfSize);
const u16 indices[12] = {  0, 1, 3,  0, 3, 2,  0, 2, 1,  3, 1, 2 };
works well, the above code looks like this
Image

Now i want to have the tetrahedron rotated, so that one corner points up the Y-axis. The centroid should be at (0.0f, 0.0f, 0.0f).
Image
So i tried

Code: Select all

vertices[0].Pos = core::vector3df(0.0f, halfSize, 0.0f);
vertices[1].Pos = core::vector3df(-halfSize, -halfSize, -halfSize);
vertices[2].Pos = core::vector3df(halfSize, -halfSize, -halfSize);
vertices[3].Pos = core::vector3df(0.0f, -halfSize, halfSize);
This unfortunately results in a non-regular tetrahedron.
I know i could just rotate the node, but i really want to know the position of the vertices.

The formulas for regular tetrahedron in the article don't help, since my math skills are... uhm.. poor.

Can anyone help?
"Whoops..."
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

I can't vouch for these numbers because I just worked them out back-of-the-envelope style, but they should be correct;

Code: Select all

vertices[0].Pos = core::vector3df(0.0f, r, 0.0f);
vertices[1].Pos = core::vector3df(r*sqrt(2.0)*2.0/3.0, -r/3.0, 0.0);
vertices[2].Pos = core::vector3df(-r*sqrt(2.0)/3.0, -r/3.0, r*sqrt(2)/sqrt(3));
vertices[3].Pos = core::vector3df(-r*sqrt(2.0)/3.0, -r/3.0, -r*sqrt(2)/sqrt(3));
I've left it in terms of sqrt(2) and sqrt(3) because there's probably some constants somewhere set to these values.
r = radius (distance from centre of mass to each vertex). It's equal to 4/3 of the total height, and the base of the pyramid is at y = -r/3.
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

For anybody interested, the maths is quite simple - uses nothing more than trig and a little intuition.

Assume we're building a tetrahedron around a point, with a radius of 1 (to simplify the math a little).
Intuition: The centre of mass is the centre of mass in all directions. Therefore if we have a point at -1 y, and know that the other 3 points form a plane perpendicular to y (i.e. all have the same y value), they must all be at +1/3 y, else the centre of mass would be elsewhere.
Now build a triangle with height = 1/3, hypotenuse = 1. By Pythagoras the remaining dimension (width) is sqrt( 1^2 - (1/3)^2 ) = sqrt( 8/9 ) = sqrt(2) * 2 / 3
Here define the second angle of rotation by setting z to 0, and this has given us the second point. Now it's just an equilateral triangle base with radius sqrt(2) * 2 / 3. Using the centre of mass argument a second time, or using the cos(60)=1/2 identity, we find that the x of the remaining 2 points is -sqrt(2) / 3
Finally the sin(60)=sqrt(3)/2 identity tells us that the z values of the last 2 points are +/- sqrt(2) * sqrt(3) / 3, which simplifies to +/- sqrt(2/3)
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

Thank you very much, works like a charm.

One last little question:
Say the length of each edge should be 1000.0f. What's the math to compute radius r?

I tried f32 r = 1000.0f*sqrt(3)/sqrt(2)/2; which results in edge length = 1000.000008, but
i don't know if there's a more elegant and faster solution.

Again, thank you for your help, your post cleared some things up.
"Whoops..."
DavidJE13
Posts: 165
Joined: Tue Jan 09, 2007 7:17 pm

Post by DavidJE13 »

Your formula is perfectly correct and elegant. Nothing will be more accurate short of using 64-bit precision or replacing all r's with that formula and simplifying them (and that may not be any better)

for a little more programming elegance you can use M_SQRT2 (=sqrt(2)) and M_SQRT1_2 (=1/sqrt(2)) in the place of some sqrt calls for speed. I'd also recommend making your own SQRT3 constant (and maybe a SQRT1_3 constant too) to save some calculations.
Post Reply