简体   繁体   中英

Three.js: Drawing points

For a web project, I would like to draw random points with Three.js.

This is my code so far:

 <script type="module"> import * as THREE from 'https://threejs.org/build/three.module.js'; import { TrackballControls } from 'https://threejs.org/examples/jsm/controls/TrackballControls.js'; let camera, scene, renderer, controls; init(); animate(); function init() { renderer = new THREE.WebGLRenderer(); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); scene = new THREE.Scene(); scene.background = new THREE.Color( 0xffffff ); camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 ); camera.position.set( 0, 0, 500 ); controls = new TrackballControls( camera, renderer.domElement ); controls.minDistance = 200; controls.maxDistance = 500; scene.add( new THREE.AmbientLight( 0x222222 ) ); const light = new THREE.PointLight( 0xffffff ); light.position.copy( camera.position ); scene.add( light ); // // const randomPoints = []; for ( let i = 0; i < 10; i ++ ) { randomPoints.push( new THREE.Vector3( ( i - 4.5 ) * 50, THREE.MathUtils.randFloat( - 50, 50 ), THREE.MathUtils.randFloat( - 50, 50 ) ) ); } const randomSpline = new THREE.CatmullRomCurve3( randomPoints ); // const extrudeSettings2 = { steps: 120, bevelEnabled: false, extrudePath: randomSpline }; const pts2 = [], numPts = 5; for ( let i = 0; i < numPts * 2; i ++ ) { const l = i % 2 == 1? 10: 10; const a = i / numPts * Math.PI; pts2.push( new THREE.Vector2( Math.cos( a ) * l, Math.sin( a ) * l ) ); } const shape2 = new THREE.Shape( pts2 ); const geometry2 = new THREE.ExtrudeGeometry( shape2, extrudeSettings2 ); const material2 = new THREE.MeshLambertMaterial( { color: 0xff8000, wireframe: false } ); const mesh2 = new THREE.Mesh( geometry2, material2 ); scene.add( mesh2 ); // const materials = [ material2 ]; const extrudeSettings3 = { depth: 40, steps: 1, bevelEnabled: true, bevelThickness: 2, bevelSize: 4, bevelSegments: 1 }; const geometry3 = new THREE.ExtrudeGeometry( shape2, extrudeSettings3 ); const mesh3 = new THREE.Mesh( geometry3 ); mesh3.position.set( 150, 100, 0 ); } function animate() { requestAnimationFrame( animate ); controls.update(); renderer.render( scene, camera ); } </script>

Currently, everything is based on splines. The result should not be based on extrusion, but on random points. I don't really know how to get random points. Is there a special function for it? Or can another function be used for it?

I would be veeeery thankful for help: :)

I think a good place to start with is usingConvexGeometry . You give it an array of points / Vector3 ( which I see you have created under the variable randomPoints ) as a parameter and it will create a shape for you.

I see you used CatmullRomCurve3, this may be a good tool to create the curves between the points as you mentioned. We can combine both of these ideas to create a somewhat curvier model.

const divisions = 25; // The amount of divisions between points
const catmullPoints = new THREE.CatmullRomCurve3( randomPoints, true, "catmullrom", 0.5 ).getPoints(divisions);
const geometryConvex = new ConvexGeometry( randomPoints );

So now you have a geometry with a somewhat randomized shape. The thing about it is that it will look a bit more "geometrical" than the example shapes you provided. So what you can try to do is divide your randomPoints to chunks, ie multiple sub-arrays, and do a similar approach as above, basically saving the created geometries to a separate array, let's call it geometries , and then you can use mergeBufferGeometries to create a single geometry out of these geometries, this will give a more abstract looking shape. The code:

  const size = THREE.MathUtils.randInt(2,10); // the number of sub arrays can be another parameter to randomize
  const pointsChunk = chunk([...randomPoints], size); // you can use lodash or other chunk algorithms found online
  
  const geometries = [];
  for ( let i = 0 ; i < pointsChunk.length ; i++) {
     const divisions = 25;
     const catmullPoints = new THREE.CatmullRomCurve3( pointsChunk[i], true, "catmullrom", 0.5 ).getPoints( divisions );
     geometries.push(new ConvexGeometry( catmullPoints ));
  }
  
  const mergedGeometry = BufferGeometryUtils.mergeBufferGeometries( geometries );

There may be more ways to go about it, but I believe ConvexGeometry is definitely a good place to start. Here is a fiddle of my attempt: https://jsfiddle.net/9rc503tn/2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM