CanvasMap
Getting Started Tutorials 3D Reference

3D Extruded Geometries

3D Extruded Geometries are geometries that are created by extruding cross sections along a path. This is a powerfull approach to create a wide variety of geometries. These are used for:

The desired features for extruding geometries include:

The following approaches work:

ExtrudeBufferGeometry with a Path

Typically the path is created with a CatmullRomCurve3 and then passed in as the "ExtrusionPath".

This approach appears to work well for everything except being able to specify the cross-sections rotation angles. Also, it appears this approach does not allow us to define exactly where the cross sectoins are placed along the extrusion. The "steps" parameter specifies the number of sections for extrusion and they appear to be equally placed.

This approach is used to rendering graticules on a sphere in the CM3LayerGraticule class.

 var ExtrusionPath =  new THREE.CatmullRomCurve3( ThePoints );
 ExtrusionPath.curveType = 'catmullrom';
 ExtrusionPath.closed = false;
 
 var extrudeSettings = {
 steps: 100,
 bevelEnabled: false,
 extrudePath: ExtrusionPath
 };
 // create the geometry
 var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings );
 
 // create the mesh with the geometry and TheMaterial
 var TheLine = new THREE.Mesh( geometry, TheMaterial );
 
 edges = new THREE.VertexNormalsHelper( TheLine, 200, 0x00ff00, 1 );
 //			edges = new THREE.FaceNormalsHelper( mesh, 2, 0x00ff00, 1 );
 this.LineMesh.add(edges);
 
 this.LineMesh.add(TheLine);
 

Custom Indexed Extrusion

In this approach we have created a new class, CM3PathExtrusion which allows for extrusions with a great deal of flexiblity. The primary function is:

CM3PathExtrusion.GetTHREEGeometry(PathArray,Index,CrossSectionArray,Closed)

This function works by creating individual tubes between each pair of points in the PathArray. This allows the geometry to extracly match the segments of a polyline or outline of a polygon. The cross section can is used as the shape of the tube.

One of the key issues with extrusions is how to handle the connections between the "tubes". With this approach the vertices in one tube are joined with the vertices in the next tube with segements and then the segments are used to create faces. Note that this doubles the number of vertices, segments, and faces compared to the previous approahch.

Future extensions:

Analysis

The main problem in extruding along a path is how to make the end connections look good. By default, we could just create "tubes" along each line segment based on a cross-section. The problem is that whenever the segments do not meet at 180 degrees (i.e. almost all the time), there would be a crack on one side of the connection and overlap on the other. OpenGL can have flicking with overlaps and craks do not look good. There are a number of solutions to this problem. Typically the user can specify different types of connections, flat, pointy, and curved. The pointy connections result in ever increasing extensions to the line segment intersections. The flat option is really just a curved connection with one segment. As the number of segments in the curve increase, the curve appears smoother.

The key problem with extruding for GIS applications is that we want to control the rotation of the cross sections for the extrusion. As an example, if we have a road, we want the roads cross section to be flat by default regarless of the turns and ups and downs of the road. Then, we would apply rotation to the cross section to match how the road was constructed on the terrain.

There are a number of keys to soling this problem:

  1. Finding the point of rotation that allows a curve to turn smoothly from one line segment to the next at a specified radius.
  2. Creating additional cross sections at desired angles to connect the two ends of the line segments.

Because we are creating a curved end, the curve will not pass through the point of intersection.

Approach

The approach as follows:

  1. Given three points P0, P1, P2 and a RadiusOfRotation
  2. Find the angle between the two line segments in 3d space. See https://www.nabla.hr/PC-LinePlaneIn3DSp2.htm#Angle%20between%20lines
  3. Find the distance from P1 to the new end points on the line segments:
    1. DistanceToNewPoints=RadiusOfRotation/Math.tan(AngleIn3D/2);
  4. The distance from P1 to the rotation point:
    1. DistanceToRotationPoint=RadiusOfRotation/Math.sin(AngleIn3D/2);
  5. Use the DistanceToNewPoints to find the new line segment end points, P10 and P12. Note that if the DistanceToNewPoints is less than the length of either line segment, then the segments are too short for the radius of curvature. In this case, P2 is ignored and we move on the to the next point.
  6. Find the new rotation point:
    1. The rotation point is on a line that goes through P1 and a point mid-way between P10 and P12.
    2. Find the point, P11, between P10 and P12
    3. The rotation point can then be found by putting a line between P11 and P1 and then finding the point that is DistanceToRotationPoint from P1 on the line.
  7. Find the Number of Segments in the curve. This is specified by the "crack angle" and the DegreesPerSegment desired by the user.
  8. If the Number of Curve Segments is 1, then the steps belowmay be skipped
    1. Find the angles between the line segments (BissectingAngles) projected into the XY plane and the Z plane. These are required to sweep our curve simultaneously in the XY plane and the Z plane while keeping the cross sections oriented correctly.
    2. Find the initial angles to the points at the center of the new cross sections and the angles between these points.
    3. Setup the initial angles of the cross sections to match the end of the first line segment (P0, P1)
    4. For each curve segment:
      1. Add the
  9. T

Tech Notes

Note that for all of the above, the normals are key and can be displayed with:

 edges = new THREE.VertexNormalsHelper( TheLine, 200, 0x00ff00, 1 );
   //			edges = new THREE.FaceNormalsHelper( mesh, 2, 0x00ff00, 1 );
 this.LineMesh.add(edges);