Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merging line geometries in three.js

Tags:

three.js

I'm having a problem merging multiple lines into one geometry. Line geometry was built using the CubicBezierCurve3:

const curve = new CubicBezierCurve3(
            point1,
            point2,
            point3,
            point4
        );
        const geometry = new BufferGeometry();
        const points = curve.getPoints(16);
        geometry.setFromPoints(points);

Then these two geometries were merged using BufferGeometryUtils:

const line = new Line(BufferGeometryUtils.mergeBufferGeometries([line1Geometry, line2Geometry], false), new LineBasicMaterial())

As a result, the desired figure turned out, but an extra line came from somewhere that connects them.

line

If I change the order when merging, then I get a different line. I don't understand how to solve this problem.

line2

like image 822
Artur Avatar asked Oct 17 '25 03:10

Artur


1 Answers

You can't use THREE.Line for this use case since it represents a continuous line. So if you merge two separate lines into one, there will be no gap that separates both.

You have to use THREE.LineSegments however that means you have to pre-process your curve geometries. Try it like in the following live example:

let camera, scene, renderer;

init();
render();

function init() {

  camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
  camera.position.set(0, 0.5, 2);

  scene = new THREE.Scene();

  const curve1 = new THREE.CubicBezierCurve3(
    new THREE.Vector3(1, 0, 0),
    new THREE.Vector3(2, 0, 0),
    new THREE.Vector3(1, 1, 0),
    new THREE.Vector3(2, 1, 0)
  );

  const geometry1 = createGeometry(curve1.getPoints(32));

  const curve2 = new THREE.CubicBezierCurve3(
    new THREE.Vector3(-1, 0, 0),
    new THREE.Vector3(-2, 0, 0),
    new THREE.Vector3(-1, 1, 0),
    new THREE.Vector3(-2, 1, 0)
  );

  const geometry2 = createGeometry(curve2.getPoints(32));

  const geometry = THREE.BufferGeometryUtils.mergeBufferGeometries([geometry1, geometry2]);

  const material = new THREE.LineBasicMaterial();

  mesh = new THREE.LineSegments(geometry, material);
  scene.add(mesh);

  renderer = new THREE.WebGLRenderer({
    antialias: true
  });
  renderer.setPixelRatio(window.devicePixelRatio);
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

}

function render() {

  renderer.render(scene, camera);

}

function createGeometry(points) {

  const vertices = [];
  const segments = points.length - 1;

  for (let i = 0; i < segments; i++) {

    const point1 = points[i];
    const point2 = points[i + 1];

    vertices.push(point1.x, point1.y, point1.z);
    vertices.push(point2.x, point2.y, point2.z);

  }

  const geometry = new THREE.BufferGeometry();
  geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));

  return geometry;

}
body {
  margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/examples/js/utils/BufferGeometryUtils.js"></script>
like image 85
Mugen87 Avatar answered Oct 20 '25 07:10

Mugen87