Ever since the introduction of electronic devices with touch controls, interactive 3D graphics objects have become increasingly popular in multimedia electronic books (ebooks). The Lidar Toolbox and the Computer Vision Toolbox from MathWorks provide the necessary tools for creating and exporting 3D graphics objects for inclusion in documents such as multimedia ebooks, interactive websites, and presentations (MathWorks 2025a, b).
I have been working on this for a while, after important features for macOS were no longer available, which were previously provided in Simulink 3D Animation and which I presented in earlier editions of my books. The problem was that the 3D model had to be equipped not only with vertices and edges, but also with faces that were colored in the DEMCMAP color map. Thanks to the excellent MathWorks support from Oliver Jährig and Sebastian Gross, we finally managed to do it.
The Polygon File Format (PLY) files are text or binary files with the file extension .ply. Suche a file contains vertices, edges, and faces for 3D polygons. The PLY files can be viewed using a browser plugin (many different types of which are available online) or using 3D software, such as the open-source MeshLab software
or the free Blender software available at
These tools (as well as others) can be used to convert the PLY format into other 3D graphics object file formats, such as the Universal 3D (U3D), the Virtual Reality Modeling Language (VRML), the Collada digital asset exchange (DAE) or Filmbox (FBX) formats. As an example, the U3D format is the format required to place a 3D graphics object onto a PDF page with Adobe Acrobat.
The digital terrain models such as the one in file s01_e036_1arc_v3.tif are great examples of such interactive 3D objects. We use the script readgeoraster to read the GeoTIFF file using
[SRTM,R] = readgeoraster('s01_e036_1arc_v3.tif',... 'OutputType','double');
which is a generic tool for reading geospatial raster data files. The output arguments are the digital elevation data SRTM and the spatial reference object R. The SRTM dataset actually has a resolution of 1/3600 degrees, but we first reduce it to 1/360 degrees so that our computers can handle a smooth 3D display. We define a coordinate grid LON and LAT to match SRTM using
SRTM = SRTM(1:10:end,1:10:end)/5000; [LON,LAT] = meshgrid(36:1/360:37,-1:1/360:0);
3D graphics can be generated from the elevation data using the function
vertices = [LON(:),LAT(:),SRTM(:)]; faces = delaunay(LON,LAT); mesh = surfaceMesh(vertices,faces);
We now set the demcmap as the colormap for our digital terrain model, that is, we replace the standard color map parula with a colormap that is commonly used for displaying digital terrain models. To ensure that our colormap matches the data, we scale it to the range between the extreme values of SRTM using
zLimits = [min(SRTM(:)),max(SRTM(:))]; demcmap(zLimits)
Then we determine the number of faces and colors using
numFaces = size(faces,1); cmap = colormap; numColors = size(cmap,1);
We then assign colors to the faces of the 3D model using
faceColors = zeros(numFaces,3); for i = 1:numFaces vertexIndices = faces(i,:); avgZ = mean(SRTM(vertexIndices)); colorIndex = round((avgZ-zLimits(1))/ ... (zLimits(2)-zLimits(1))*(numColors-1))+1; colorIndex = min(max(colorIndex,1),numColors); faceColors(i,:) = cmap(colorIndex,:); end
We then convert the faceColors to vertexColors using
numVertices = size(vertices,1); vertexColors = zeros(numVertices,3); vertexCounts = zeros(numVertices,1);
We then assign colors to the vertices of the 3D model using
for i = 1:numFaces face = faces(i,:); color = faceColors(i,:); for j = 1:3 vIdx = face(j); vertexColors(vIdx,:) = vertexColors(vIdx,:)+... color; vertexCounts(vIdx) = vertexCounts(vIdx)+1; end end
We replace zeros by ones in order to avoid division by zero before we devide vertexColors by vertexCounts using
vertexCounts(vertexCounts==0) = 1; vertexColors = vertexColors./vertexCounts;
Then we assign vertexColors and facesColors to the attributes of the mesh object using
mesh.VertexColors = vertexColors; mesh.FaceColors = faceColors;
and display the result using surfaceMeshShow:
surfaceMeshShow(mesh)
We can the use writeSurfaceMesh to save the 3D model to a file in a range of formats, for example as a PLY or FBX file using
writeSurfaceMesh(mesh,'srtm_1.ply') writeSurfaceMesh(mesh,'srtm_2.fbx')
Instead of a mesh of vertices, edges, and faces with colors, we can also display the vertices as a point cloud. Before we do that, we remove the vertices with no data using
xyzPoints = xyzPoints(~isnan(xyzPoints(:,3)),:);
Again, we defined the colors of the vertices using
colorIndices = round(rescale(SRTM(:),1,... size(cmap,1))); colors = cmap(colorIndices,:);
With the function pointCloud, we can create a point cloud ptCloud from xyzPoints with the colors colors:
ptCloud = pointCloud(xyzPoints,... 'color',colors);
We can display the resulting point cloud with colors using
pcshow(ptCloud)
We can the use pcwrite to save the 3D model to a PLY file using
pcwrite(ptCloud,'srtm_3.ply',... 'Encoding','binary')
Importing the resulting PLY file into a PLY client such as MeshLab or Blender reveals that the terrain model does indeed has colors, as defined by demcmap. We can use the file in the PLY format to create an interactive document.
Downloads
Download all files to perform the experiment.
References
MathWorks (2025a) Computer Vision Toolbox – User’s Guide. The MathWorks, Natick, MA
MathWorks (2025b) Lidar Toolbox – User’s Guide. The MathWorks, Natick, MA
Trauth, M.H. (2025) MATLAB Recipes for Earth Sciences – Sixth Edition. Springer International Publishing, 567 p, https://doi.org/10.1007/978-3-031-57949-3