rdk750
rdk750

Reputation: 13

Adding Width to a Curved Path in Three.js

I created a racetrack shaped curve in three.js with the following code:

var path = new THREE.Path();

    path.moveTo(150,50);
    path.lineTo(150,150);
    path.quadraticCurveTo(150,175,100,175);
    path.quadraticCurveTo(50,175,50,150);
    path.lineTo(50,50);
    path.quadraticCurveTo(50,25,100,25);
    path.quadraticCurveTo(150,25,150,50);

    var pathPoints = path.getPoints();

    var pathGeometry = new THREE.BufferGeometry().setFromPoints(pathPoints);
    var pathMaterial = new THREE.LineBasicMaterial({color:0xFF1493});

    var raceTrack = new THREE.Line(pathGeometry,pathMaterial);
    scene.add(raceTrack);

}

Right now, the track is just a single line, and I wanted to know if it was possible to make the track into a geometry with a width (still 2D) so that I can add a texture to it.

Currently, the path looks something like this:

1px wide path

What I'd like is to be able to draw the same shape, but just increase the width of the line:

5px wide path

Upvotes: 1

Views: 2428

Answers (2)

Martin Schuhfuß
Martin Schuhfuß

Reputation: 6986

With regular Line-objects, there is no way to achieve this.

Here are a few options you can try:

  • create your complete "race-track" as a geometry, including both the inner and the outer line. I have no idea what you need this for, but this is probably the most "correct" way to do something like this (using this approach, the race-track can have different width at different points, you have control over how bends and turns behave and so on). A quick example:

    const shape = new THREE.Shape();
    
    shape.moveTo(150, 50);
    shape.lineTo(150, 150);
    shape.quadraticCurveTo(150, 175, 100, 175);
    shape.quadraticCurveTo(50, 175, 50, 150);
    shape.lineTo(50, 50);
    shape.quadraticCurveTo(50, 25, 100, 25);
    shape.quadraticCurveTo(150, 25, 150, 50);
    
    const innerShape = new THREE.Path();
    
    innerShape.moveTo(140, 40);
    innerShape.lineTo(140, 140);
    innerShape.quadraticCurveTo(140, 165, 90, 165);
    innerShape.quadraticCurveTo(60, 165, 60, 140);
    innerShape.lineTo(60, 50);
    innerShape.quadraticCurveTo(60, 35, 110, 35);
    innerShape.quadraticCurveTo(140, 35, 140, 60);
    
    shape.holes.push(innerShape);
    
    var raceTrack = new THREE.Mesh(
      new THREE.ShapeGeometry(shape),
      new THREE.MeshBasicMaterial({ color: 0xff1493 })
    );
    

    full code here: https://codepen.io/usefulthink/pen/eMBgmE

  • alternatively, you can use the new fat-lines implementation shown here: https://threejs.org/examples/?q=line#webgl_lines_fat or the MeshLine implementation from here: https://github.com/spite/THREE.MeshLine, but I have the feeling those do not what you are looking for...

Upvotes: 2

Mugen87
Mugen87

Reputation: 31036

With R91, three.js added support for triangulated lines. This approach enables line width greater than 1px in a reliable way.

Demo: https://threejs.org/examples/webgl_lines_fat.html

There are no textures applied on the example but uv-coordinates are generated for the underlying geometry.

Upvotes: 3

Related Questions