Best way to flatten the top and bottom of a torus geometry

I’m wondering how one would go about making a “flattener” type modifying technique to:

Take a torus geometry and flatten “to taste” the top and bottom of the poles of it…
(Considering its the usual horizontal orientation)

Imagine a torus sliced into horizontal sections.
How would I go about generating those one by one using a “flattening” of the points in the up/down axis?
(Not slicing a whole torus up)


Since it starts with a super-flat torus, and then just expands it according to your needs and the displacement map - this solution could likely be also used here.

Seems it’s not a torus geometry at all, but several lathe geometries.

Wow both your guys suggestions on that thread are great. I’ll check them out.

Actually I wonder if I made a circle with a displacement map of horizontal stripes on it, then lathed THAT… To have the non displaced stripes be the only ones extruded along the lathe…hmmm what do you guys think?

Hmm but although the displacement will flatten, it would never completely “cut” or disallow extrusion huh.

If I use the flattening, via either method, and wanted just say, a torus in just 6 slices total, is just have to make 3 at different settings, then group and clone the group…then flip the cloned group on its vertical axis…

A very rough, thus imperfect :upside_down_face:, solution with LatheGeometry:




Don’t know if I understood the task correctly, but how about this?


Hey thanks for that example.
That’s what I needed for the non-sliced version.

Very cool. I’ll be trying this thanks!

is this where you did the flattening…?

let v = new THREE.Vector3(); 

for( let i = 0; i < pos.count; i++ ){

	v.fromBufferAttribute( pos, i );
	pos.setZ( i, Math.abs( v.z ) > 0.3 ? Math.sign( v.z ) * 0.3 : v.z );

Of course, that’s all there is to the program. :slightly_smiling_face:

You can also do it asymmetrically.

const a = 0.4;
const b = -0.1;

for( let i = 0; i < pos.count; i++ ){

	v.fromBufferAttribute( pos, i );
	//pos.setZ( i, Math.abs( v.z ) > 0.3 ? Math.sign( v.z ) * 0.3 : v.z );
	if ( v.z > a ) v.z = a;
	if ( v.z < b ) v.z = b;
	pos.setZ( i, v.z );

But the signs of a and b should be different. Otherwise you get a boundary with the radius of the whole torus.

const a = 0.42;
const b = 0.25;

2021-02-20 17.23.30

In this case, another solution is needed. Like the one from @prisoner849.

1 Like