I have these methods in angular to draw cross section of riverbed and analysis areas high(red) & low(yellow) using three.js. with current implementation analysis areas are of boxgeometry shape now need to follow shape of riverbed. Please help

private draw_analysis_area(): void {
let hi_lo_crossover = parseFloat(this.analysisSettingsModel?.levelAnalysisAreaThreshold?.toString() || ‘0’);
// high level analysis area settings
let ll_camera_left_boundary = parseFloat(this.analysisSettingsModel?.lowLevelPositiveOffset?.toString() || ‘0’);
let ll_camera_right_boundary = parseFloat(this.analysisSettingsModel?.lowLevelNegativeOffset?.toString() || ‘0’);
let ll_area_visibility = this.analysisSettingsModel.lowLevelAreaVisible;
// high level analysis area settings
let hl_camera_left_boundary = parseFloat(this.analysisSettingsModel?.highLevelPositiveOffset?.toString() || ‘0’);
let hl_camera_right_boundary = parseFloat(this.analysisSettingsModel?.highLevelNegativeOffset?.toString() || ‘0’);
let hl_area_visibility = this.analysisSettingsModel.highLevelAreaVisible;
let boundary_length = Math.abs(this.bank_1?.x - this.bank_2?.x)
let hi_lo = new Array();
hi_lo.push(new THREE.Vector3(this.bank_1?.x, hi_lo_crossover))
hi_lo.push(new THREE.Vector3(this.bank_2?.x, hi_lo_crossover))

// Hi lo analysis cross over mesh
let geometry = this.extrudePath(hi_lo, 10);
let material = new THREE.MeshPhongMaterial({ color: "green", wireframe: false, side: THREE.DoubleSide, transparent: true, opacity: 0.5 });
let hi_lo_crossover_mesh = new THREE.Mesh(geometry, material);
//scene.add(hi_lo_crossover_mesh);

//low level analysis area
let ll_area_mesh;
const ll_area_mesh_name = "ll_area_mesh";
if (ll_area_visibility) {
  let ll_boundary_width = ll_camera_left_boundary + ll_camera_right_boundary;
  geometry = new THREE.BoxGeometry(boundary_length, this.bottom.y - hi_lo_crossover, ll_boundary_width);
  material = new THREE.MeshPhongMaterial({ color: 'yellow', side: THREE.DoubleSide, transparent: true, opacity: 0.5 });
  ll_area_mesh = new THREE.Mesh(geometry, material);
  ll_area_mesh.name = ll_area_mesh_name;
  // set position, rotation, and add to scene
  ll_area_mesh.position.set(this.bank_1?.x + (boundary_length / 2), hi_lo_crossover / 2 + this.bottom.y / 2, ll_boundary_width / 2 - ll_camera_left_boundary + this.riverCam_object.position.z);
}
this.addOrReplaceToSceneByName(ll_area_visibility, ll_area_mesh_name, ll_area_mesh);

//high level analysis area
let hl_area_mesh;
const hl_area_mesh_name = "hl_area_mesh";
if (hl_area_visibility) {
  let hl_boundary_width = hl_camera_left_boundary + hl_camera_right_boundary
  geometry = new THREE.BoxGeometry(boundary_length, this.top.y - hi_lo_crossover, hl_boundary_width);
  material = new THREE.MeshPhongMaterial({ color: 'red', side: THREE.DoubleSide, transparent: true, opacity: 0.5 });
  hl_area_mesh = new THREE.Mesh(geometry, material);
  // set position, rotation, and add to scene
  hl_area_mesh.position.set(this.bank_1?.x + (boundary_length / 2), hi_lo_crossover / 2 + this.top.y / 2, hl_boundary_width / 2 - hl_camera_left_boundary + this.riverCam_object.position.z);
  hl_area_mesh.name = hl_area_mesh_name;
}
this.addOrReplaceToSceneByName(hl_area_visibility, hl_area_mesh_name, hl_area_mesh);

}

private extrudePath(points: any, depth: number): void {
let geometry = new THREE.PlaneGeometry(0, 0, points.length - 1, 1);
let pos = geometry.attributes.position;

for (let i = 0, l = points.length, p; i < l; i++) {
  let p = points[i];
  pos.setXYZ(i, p.x, p.y, p.z + depth / 2);
  pos.setXYZ(i + points.length, p.x, p.y, p.z - depth / 2)
}

geometry.computeVertexNormals();
return geometry;

}

private draw_cross_section(): void {
let cross_section_visible = this.analysisSettingsModel?.crossSectionVisible;
let crossSection_mesh;
const crossSection_mesh_name = “crossSection_mesh”;
if (cross_section_visible) {
let crossSection = new Array();
this.crossSectionData.data.forEach(line => {
crossSection.push(new THREE.Vector3(parseFloat(line?.y?.toString() || ‘0’), parseFloat(line?.z?.toString() || ‘0’)));
});
this.bank_1 = crossSection[0] || new THREE.Vector3(0, 0, 0); // the first cross section point
this.bank_2 = new THREE.Vector3(0, 0, 0); // the last cross section point
this.bottom = new THREE.Vector3(0, 0, 0); // the lowest crosse section point
this.top = new THREE.Vector3(0, 0, 0); // the highest cross section point

  crossSection.forEach(point => {
    if (point.y <= this.bottom.y) { //get lowest cross section point
      this.bottom = point;
    }
    if (point.y >= this.top.y) { //get highest cross section point
      this.top = point;
    }
    this.bank_2 = point; //get last cross section point
  });

  // river bed mesh
  let geometry = this.extrudePath(crossSection, 10);
  let material = new THREE.MeshBasicMaterial({ map: this.dirt_texture, wireframe: false, side: THREE.DoubleSide });
  crossSection_mesh = new THREE.Mesh(geometry, material);
  crossSection_mesh.name = crossSection_mesh_name;
}
this.addOrReplaceToSceneByName(cross_section_visible, crossSection_mesh_name, crossSection_mesh);

}

Not really enough information here to help you with this. You should create a jsfiddle or codepen showing the issue, and/or some screenshots or drawing showing the result you want to achieve.

Very few people enjoy piecing together your code from a forum post, for such an ill-defined problem, sorry. :slight_smile:

2 Likes

Sorry I couldn’t create a codepen but I have existing screenshot


Expected is red & yellow area to follow riverbed shape

Lots of ways to approach this, but the simplest might be to use a horizontally subdivided plane and then adjust the vertices to match your profile. something like this:
(pseudocode)

let redPlaneGeometry = new THREE.PlaneGeometry(gridWidth,gridHeight, gridXCells, 1)

let vertices = redPlaneGeometry.attributes.position.array;

for(let i=0;i<vertices.length;i+=3){
let x = vertices[i];
let y = vertices[i+1];
if(y < .5) // This is one of the bottom vertices...
    y = HEIGHT AT X   // Set it to the depth/height of riverbed
vertices[i+1] = y;
}

let redPlaneMesh = new THREE.Mesh(redPlaneGeometry, redPlaneMaterial)
scene.add(redPlaneMesh);