How move all points to sphere

geometry

#1

Hi all. Can u help me? Got a 50000 points:

    var geometry = new THREE.Geometry();
    for (var i = 0; i < 50000; i ++ ) {
        var vertex = new THREE.Vector3();
        vertex.x = 2000 * Math.random() - 1000;
        vertex.y = 2000 * Math.random() - 1000;
        vertex.z = 2000 * Math.random() - 1000;

        geometry.vertices.push( vertex );
    }

    material = new THREE.PointsMaterial({color: 0xffffff});
    particles = new THREE.Points(geometry, material);
    scene.add( particles );

But i whant move it all to sphere how i can do that?


#2

You want the vertices to form a sphere? Something like:

const v = new Vector3();

function randomPointInSphere( radius ) {

  const x = _Math.randFloat( -1, 1 );
  const y = _Math.randFloat( -1, 1 );
  const z = _Math.randFloat( -1, 1 );
  const normalizationFactor = 1 / Math.sqrt( x * x + y * y + z * z );

  v.x = x * normalizationFactor * radius;
  v.y = y * normalizationFactor * radius;
  v.z = z * normalizationFactor * radius;

  return v;
}

#3

very nice! TY! But i mean sphere like carcas and point should placed in sphere


#4

like carcas

What does that mean?

It’s helpful with questions if you explain fully and completely what you mean to start with btw, don’t make people who want to help you play guessing games.


#5

forgive me but English is not my native language. I’m grateful for your help. I just incorrectly expressed the thought. I hope this does not cause your resentment


#6

No resentment here. But you still haven’t attempted to explain what you actually want :stuck_out_tongue:
What’s a carcas?


#7

If you use THREE.Geometry(), then for each vertex you can set coordinates of start, coordinates of end and then interpolate start to end with .lerpVectors() method of THREE.Vector3() object.

var geometry = new THREE.SphereGeometry(10, 320, 240);
geometry.vertices.forEach(v => {
  v.endPos = v.clone();
  v.set(
    THREE.Math.randFloat(-50, 50),
    THREE.Math.randFloat(-50, 50),
    THREE.Math.randFloat(-50, 50)
  );
  v.startPos = v.clone();
});

and then in you animation loop

geometry.vertices.forEach(v=>{
    v.lerpVectors(v.startPos, v.endPos, Math.sin(time * Math.PI) * 0.5 + 0.5);
});

https://jsfiddle.net/prisoner849/kh9rzLyc/

But I’d prefer to use THREE.BufferGeometry() with THREE.ShaderMaterial(), when a geometry has thousands of vertices.


#8

i whanna do somthing like that https://threejs.org/examples/?q=points#webgl_buffergeometry_points but for carcas use sphere form not box.


#9

You can do it with THREE.Spherical()

var geometry = new THREE.Geometry();
var spherical = new THREE.Spherical();
for(let i = 0; i < 50000; i++){
  spherical.phi = Math.random() * Math.PI;
  spherical.theta = Math.random() * Math.PI * 2;
  spherical.radius = Math.random() * 10; // 10 is the desired radius
  geometry.vertices.push(new THREE.Vector3().setFromSpherical(spherical));
}

But it populates the sphere non-uniformly.
https://jsfiddle.net/prisoner849/L62wfc7t/


#10

So it’s better to use another approach:

var geometry = new THREE.Geometry();
var spherical = new THREE.Spherical();
for(let i = 0; i < 50000; i++){
  geometry.vertices.push(setRandomPointInSphere(10)); // 10 is the desired radius
}

function setRandomPointInSphere(radius){
  var v = new THREE.Vector3(
    THREE.Math.randFloatSpread(radius * 2),
    THREE.Math.randFloatSpread(radius * 2),
    THREE.Math.randFloatSpread(radius * 2)
  );
  if (v.length() > radius){
    return setRandomPointInSphere(radius);
  }
  return v;
}

That approach populates the sphere uniformly.
https://jsfiddle.net/prisoner849/z58m18as/


#11

thank you so much! you are my breath.