3D Mesh from cloud of points

Hello all. I´m quite new to Three.js in particular and 3D rendering in general. I´m trying to solve the following problem:
I need to represent a volume from a set of points determined by polar coordinates (phi and theta) a magnitude.
The final result it should be something similar to a bumped sphere

So far I´ve been able to render the mesh using THREE.ConvexGeometry providing the coordinates and radius = 1
but when I try to represent the mesh applying the magnitude the resulting volume makes no sense at all.
Could you guide me here please?


        var points = [];
        var data = newRaw.Positions;
        var weight = newRaw.Power;
        var normalizationFactor = 20;

        for (var i = 0; i < data.length / 3; i++) {
            var x = data[3 * i];
            var y = data[3 * i + 1];
            var z = data[3 * i + 2];
            var radius = weight[i];
            
            var point = new THREE.Vector3(
                x * normalizationFactor * radius,
                y * normalizationFactor * radius,
                z * normalizationFactor * radius,
            );

            points.push(point);
        }

        const geometry = new THREE.ConvexGeometry(points);

        geometry.computeBoundingSphere();
                
        let meshmaterial = new THREE.MeshBasicMaterial({ color: 0xd3d3d3 });
        var mesh = new THREE.Mesh(geometry, meshmaterial);
        scene.add(mesh)

        const wireframe = new THREE.WireframeGeometry(geometry);
        const material = new THREE.LineBasicMaterial({
            color: 0xffffff,
            linewidth: 1,
            linejoin: 'miter'
        });

        line = new THREE.LineSegments(wireframe, material);
        scene.add(line);

I´d say that in theory the thing I´m trying to get is in the example https://threejs.org/examples/#webgl_geometry_convex but with a sphere.
But maybe I´m totally wrong.

Thank you in advance.

ConvexGeometry always computes the convex hull for a set of points and then represents this bounding volume as a geometry. If you say you need a sphere, use Sphere.setFromPoints(). You can then use the radius and center property in order to create a mesh based on SphereGeometry.

1 Like

Thank you, I´d give it a try, but maybe I did not explain myself correctly.
The points does not have the same radius so the mesh is not sphere. this only happens when the points have the same radius.

I´m trying to get sometihng like this http://images.elektroda.net/57_1343958566.png

thanks again

that is not convex.

I think what you could do is 1 project this in 2d, something like mercator projection, 2 create 2d mesh from that using some https://github.com/r3mi/poly2tri.js/, 3 map it back to 3D and 4 extrude vertices to their original distances

edit: actually, you could do with three.js only,

1 project all the vertices onto 3D sphere of some radius, 2 do the convex hull, 3 extrude vertices to their original distances

Thank you
But in that case when extruding the convex idexes would not make the inner points to be lost? Please have a look

The inner points are the key here

Thanks again any help is welcomed!

I cant seem to find jsfiddle link in the thread, can you post it again

You need something similar to Triangulation from the Collection of examples from discourse.threejs.org ( from 2018 discourse.threejs.hofk.de )

  • but in 3D with polar coordinates. Instead of the plane you have the surface of the unit sphere. The points are projected onto this sphere.
    After triangulation the original values of the radius are restored.

The original post @prisoner849

In delaunator.js the algorithm is commented quite well. You can try to transfer it.

// pick a seed point close to the center
// find the point closest to the seed
// find the third point which forms the smallest circumcircle with the first two
// swap the order of the seed points for counter-clockwise orientation

and so on


Some reading Delaunay triangulation - Wikipedia

1 Like

Hi , thanks I think this is what I´m looking for.

Maybe makes sense to set points at the same distance (radius) from center and then try to triangulate just a spherical surface somehow. Then use the index you get from triangulation with the original set of points for a geometry.

An interesting article: https://www.redblobgames.com/x/1842-delaunay-voronoi-sphere/

Probably I was unclear again. :confused:

With

Instead of the plane you have the surface of the unit sphere. The points are projected onto this sphere. …

I mean that you should work on the sphere with a radius of one.

I took a little look at the procedure. It seems as complex as the triangulation of the implicit surfaces or forms with holes. ( GitHub - hofk/THREEi.js: three.js addon for triangulation of implicit surfaces and for forms with holes. The addon generates indexed BufferGeometries. and
Addon for triangulation of implicit surfaces/ forms with holes)
I’m not quite done with that yet, otherwise it would entice me.

Looking at this example: https://threejs.org/examples/#webgl_geometry_convex

I thought why not give it a try: https://jsfiddle.net/prisoner849/c9ewjnox/

3 Likes

Reading the article in the comments someone says

“Delaunay triangulation of a set of points on a sphere is the same as convex hull of the point set. I agree that it’s not easily intuitive, but it saves you all this trouble.”

If that´s true then THREE.ConvexGeometry is the triagulation you are mentioning in fact I get this:

Thanks! I will

Thank you so much it worked like a charm!!!

1 Like

Glad it helped :slight_smile: :beers:

I thought why not give it a try:

I didn’t think three.js already included that. But I also lack the overview to recognize it immediately. So I would have done a lot of work for nothing if I had tried to implement the algorithm.

Once again an efficient solution! :+1: :+1: :+1:

I played around a little.
With THREE.LineSegments you see the sphere very beautiful.

2020-01-27_20.19.53

// ****************** + *********************
const lsGeo = new THREE.BufferGeometry( );
const lsPos = new Float32Array( 200 * 3 );
lsGeo.setAttribute( 'position', new THREE.BufferAttribute( lsPos, 3 ) );
for ( i = 0; i < pts.length; i ++ ) {		 
	lsPos[ i * 6     ] = pts[ i ].x;
	lsPos[ i * 6 + 1 ] = pts[ i ].y;
	lsPos[ i * 6 + 2 ] = pts[ i ].z;	
	lsPos[ i * 6 + 3 ] = unitPts[ i ].x;
	lsPos[ i * 6 + 4 ] = unitPts[ i ].y;
	lsPos[ i * 6 + 5 ] = unitPts[ i ].z;	
}
const  lsMaterial = new THREE.LineBasicMaterial({ color: "white"});
const  ls = new THREE.LineSegments( lsGeo, lsMaterial );
scene.add( ls );
// *******************************************

One would still have to display the colors according to the distance from the origin.

2 Likes

@pardogojo
Looking at your last pics of examples, I’ve got a strong impression that it looks like a usual THREE.SphereGeometry() (just rotated around x or z axis at 90 degrees) with defined width and height segmentations.
Maybe we made an overcomplicated solution and somehow it’s possible to use a built-in primitive of sphere for your case :slight_smile:
Maybe we just need to change length of vertices’ vectors in a sphere geometry.

1 Like

Maybe you are right, In fact I was trying that at the time you sent your post.
Would you mind to explain the reason of this code in the HTML part of the jsfiddle?

<script>
THREE.Vector3.prototype.equals = function( v, epsilon = Number.EPSILON ) {

    return ( ( Math.abs( v.x - this.x ) < epsilon ) && ( Math.abs( v.y - this.y ) < epsilon ) && ( Math.abs( v.z - this.z ) < epsilon ) );

}
</script>

Without this part the code does not work at all…

It’s better to compare vectors with some tolerance, as you can’t get the same exact result with calculation by the reason of precision.
I took it from here:

And used something very similar in this SO answer before:

1 Like