How to add Road following spline in Terrain?

Good Day !
I want to draw a road with a width=3m such that the red line is the middle of the Road.
I hope somebody to fix This.

here is my code

function createcurve(event){
window.cos = Math.cos;
window.sin = Math.sin;
window.tan = Math.tan;
window.sqrt = Math.sqrt;
window.pow = Math.pow;
window.log = Math.log;
window.exp = Math.exp;
const formulaStr=document.getElementById('customvalue').value;
const formula = new Function('x', 'y', 'return ' + formulaStr);
const vertices = [];
const array1 = [];
for ( let i = 0; i < 50; i ++ ) {
for ( let j = 0; j < 50; j ++ ) {
	const y =formula(i,j);
	vertices.push( new THREE.Vector3(i, y, j) );
}}
for ( let x = 0; x < 49; x ++ ) {
for ( let y = 0; y < 49; y ++ ) {
var area1=new THREE.Triangle(vertices[y+50*x],vertices[y+50*x+51],vertices[y+50*x+50]).getArea();
array1[y+49*x]=area1;
document.getElementById('Areacustom').value=(array1.reduce((total, next) => total + next, 0.0).toFixed(2))*2;
}}

const customgeometry=new THREE.BufferGeometry().setFromPoints(vertices);
const cutomMaterial=new THREE.PointsMaterial( { color:'yellow',size:0.2 } );
const points = new THREE.Points( customgeometry, cutomMaterial );
scene.add( points );
// triangulate x, z
var indexDelaunay = Delaunator.from(
  vertices.map(v => {
    return [v.x, v.z];
  })
);

var meshIndex = []; // delaunay index => three.js index
for (let i = 0; i < indexDelaunay.triangles.length; i++){
  meshIndex.push(indexDelaunay.triangles[i]);
}

customgeometry.setIndex(meshIndex); // add three.js index to the existing geometry
customgeometry.computeVertexNormals();


var mesh = new THREE.Mesh(
  customgeometry, // re-use the existing geometry
  new THREE.MeshNormalMaterial({wireframe:true})
);
scene.add(mesh)
for(let x=2;x<scene.children.length-2;x++){
scene.children[x].material.visible=false;
}
function createlines(event){
var vertice=[];
  const customGeometry = new THREE.BufferGeometry().setFromPoints(vertice);
      const customMaterial = new THREE.PointsMaterial({ color: 0x888888, size: 0.3 });
      const points = new THREE.Points(customGeometry, customMaterial);
      const curveObject = new THREE.Line(new THREE.BufferGeometry(), new THREE.LineBasicMaterial({ color: 0xff0000 }));
      function handleClick(event) {
        const x = (event.clientX / window.innerWidth) * 2 - 1;
        const y = -(event.clientY / window.innerHeight) * 2 + 1;
        const vector = new THREE.Vector3(x, y, y);
        vector.unproject(camera);
        const dir = vector.sub(camera.position).normalize();
        const distance = -camera.position.y / dir.y;
        const pos = camera.position.clone().add(dir.multiplyScalar(distance));
        vertice.push(pos);
        const customGeometry = new THREE.BufferGeometry().setFromPoints(vertice);
        points.geometry.dispose(), points.geometry = customGeometry;
        if (vertice.length >= 3) {
          const curve = new THREE.CatmullRomCurve3(vertice);
          const po = curve.getPoints(150);
          const geometry = new THREE.BufferGeometry().setFromPoints(po);
          const material = new THREE.LineBasicMaterial({ color: 0xff0000,size:5 });
          curveObject.geometry.dispose(), curveObject.geometry = geometry, curveObject.material = material;

        }
      }

      function init() {
        scene.add(points);
        scene.add(curveObject);
        window.addEventListener('click', handleClick);
      }
  init();

}

I Created The curve Using this function f(x,y)=sin(x)*cos(y) I need drawing similar to picture bellow
Capture1
Thank you

  1. Do not the cat like this:
window.cos = Math.cos;
window.sin = Math.sin;
window.tan = Math.tan;
window.sqrt = Math.sqrt;
window.pow = Math.pow;
window.log = Math.log;
window.exp = Math.exp;

Consider absolutely never assigning anything to window manually, you’ll save yourself plenty of js-related pain.

  1. Before you start creating the road geometry - start with preparing the environment for it. Can’t build a road on mountains and curvy ditches - you need to flatten the environment first.

First, divide your spline into more / denser segments - the denser the spline, the nicer the final road will look.
Second, go through all points in the spline and for each point find all vertices of the ground mesh that are “locally” close to that point (ie. distance from point to the vertex < some arbitrary radius, you can use half-distance between points on the spline for as the radius.)
Third, here you’d do the subdivision / tessellation of the ground mesh (ie. the reason why on your green screenshot there are more triangles closer to the road) - but skip it for now.
Four, having nearby vertices for each point - equalise their y-position. Calculate average y-position and just assign it to other nearby vertices (to make it more pretty you can do that adjustment stronger / weaker depending on the vertex distance from the spline point - using lerp for example.)
Done, you should now have the terrain flattened in a way that you can actually place a non-zero-width road on it. On that kind of geometry you can either use a decal or place a plane / fan geometry along the spline to create a road.

1 Like