tylermorganwall / rayshader

R Package for 2D and 3D mapping and data visualization
https://www.rayshader.com/
2.06k stars 214 forks source link

`plot_3d()` fails for heightmap with named dimensions #200

Closed tsamsonov closed 2 years ago

tsamsonov commented 2 years ago

Hi @tylermorganwall !

plot_3d() fails to execute if the heightmap matrix has named dimensions:

library(rayshader)
library(stars)
#> Загрузка требуемого пакета: abind
#> Загрузка требуемого пакета: sf
#> Linking to GEOS 3.8.1, GDAL 3.2.1, PROJ 7.2.1

dem = read_stars('https://raw.githubusercontent.com/tsamsonov/r-geo-course/master/data/dem_fergana.tif')

elev = dem[[1]]

dim(elev)
#>   x   y 
#> 690 594

elev %>%
  sphere_shade(texture = "desert") %>%
  add_water(detect_water(elev), color = "desert") %>%
  add_shadow(ray_shade(elev, zscale = 3), 0.5) %>%
  add_shadow(ambient_shade(elev), 0) %>%
  plot_3d(elev, zscale = 10, fov = 0, theta = 135, zoom = 0.75, phi = 45, windowsize = c(1000, 800))
#> Error in rgl.surface(x = 1:nrow(heightmap) - nrow(heightmap)/2, z = (1:ncol(heightmap) - : Bad dimension for normals

Created on 2021-11-28 by the reprex package (v2.0.1)

It seems that rgl.surface() performs strict comparison of dimensions including their names (lines 34-37):

if (!identical(dim(y), dim(normal_x)) || !identical(dim(y), 
      dim(normal_y)) || !identical(dim(y), dim(normal_z))) 
      stop(gettextf("Bad dimension for %s", "normals"), 
        domain = NA)

Hence, everything works fine if I unname the dimensions:

library(rayshader)
library(stars)
#> Загрузка требуемого пакета: abind
#> Загрузка требуемого пакета: sf
#> Linking to GEOS 3.8.1, GDAL 3.2.1, PROJ 7.2.1

dem = read_stars('https://raw.githubusercontent.com/tsamsonov/r-geo-course/master/data/dem_fergana.tif')

elev = dem[[1]]

dim(elev) <- unname(dim(elev))
dim(elev)
#> [1] 690 594

elev %>%
  sphere_shade(texture = "desert") %>%
  add_water(detect_water(elev), color = "desert") %>%
  add_shadow(ray_shade(elev, zscale = 3), 0.5) %>%
  add_shadow(ambient_shade(elev), 0) %>%
  plot_3d(elev, zscale = 10, fov = 0, theta = 135, zoom = 0.75, phi = 45, windowsize = c(1000, 800))

Sys.sleep(0.2)
render_snapshot()

image

Created on 2021-11-28 by the reprex package (v2.0.1)

Should plot_3d() do unnaming itself?

tylermorganwall commented 2 years ago

Huh, weird bug! Thanks for the report. I fixed it in the latest version (dc1bb008d378d397fe7f57ac1732b999af70e5e1).