R语言学习(三)3D制图——rayshader包(一)

个人感觉R语言最有趣的就是各种各样的制图包,今天就来学习一个!
下面附上原作者Github链接https://github.com/tylermorganwall/rayshader

小贴士

关于各种包的函数文档可以https://cran.r-project.org/web/packages/available_packages_by_name.html这里找到。

管道操作

这里先说一些其他的东西,之前一直看到“->”但不知道和“=”有啥区别,后来学习了一下,两者大多数环境下没有区别,但这里举个例子,func(x=1)与func(x<-1,前者调用完后变量x不会被保留,而后者会在工作区里保留变量x=1。
管道(%>%)调用函数,其作用是将前一步的结果直接传参给下一步的函数,从而省略了中间的赋值步骤,可以大量减少内存中的对象,节省内存。x %>% f(y) 等同于 f(x, y),y %>% f(x, ., z) 等同于 f(x, y, z )。

Rayshader

在这里插入图片描述

安装相关包

install.packages("rgdal")
install.packages("devtools")
devtools::install_github("tylermorganwall/rayshader")

之前安装过rgdal包和devtools包就不用安装了。

绘制3D地形图

loadzip = tempfile() 
download.file("https://tylermw.com/data/dem_01.tif.zip", loadzip)
localtif = raster::raster(unzip(loadzip, "dem_01.tif"))
unlink(loadzip)

#And convert it to a matrix:
elmat = matrix(raster::extract(localtif, raster::extent(localtif), buffer = 1000),
               nrow = ncol(localtif), ncol = nrow(localtif))
#We use another one of rayshader's built-in textures:               
elmat %>%
  sphere_shade(texture = "desert") %>%
  plot_map()

此代码是先下载示例的30m分辨率的dem数据(可以改成自己的数据),之后将dem转成matrix矩阵,这里用到raster包里的extrac取值函数,中间用到缓冲buffer参数,但是这个参数一般用于点的缓冲,在这里可能是用于面的缓冲,有没有似乎对结果没有什么影响。sphere_shade为纹理映射函数,其中参数texture为映射的纹理特征,有“imhof1”, “imhof2”, “imhof3”, imhof4“,”desert“,”bw“,”unicorn"这几个选项。下图为不同texture的效果。
在这里插入图片描述

设置光线方向

elmat %>%
  sphere_shade(sunangle = 45, texture = "desert") %>%
  plot_map()

sunangle参数为高光的角度。
在这里插入图片描述

添加水体

elmat %>%
  sphere_shade(texture = "desert") %>%
  add_water(detect_water(elmat), color = "desert") %>%
  plot_map()

detect_water函数是利用泛洪填充算法来侦测水体, add_water是获取前者得到的水体并添加到地形图上。color函数设置水体的颜色,可以为“imhof1”, “imhof2”, “imhof3”, imhof4“,”desert“,”bw“,”unicorn",前五个是各种明暗的蓝色,bw是白色,unicorn是彩虹色。
在这里插入图片描述

添加光线追踪层

raymat = ray_shade(elmat)

#And we can add a raytraced layer from that sun direction as well:
elmat %>%
  sphere_shade(texture = "desert") %>%
  add_water(detect_water(elmat), color = "desert") %>%
  add_shadow(raymat) %>%
  plot_map()

注:sphere_shade只能调整山体的明暗效果,ray_shade可以根据方向生成阴影,当方向参数未设置时,会依据平均光线方向和曲面法向的点来缩放每个像元的灯光强度。控制方向参数的默认值为anglebreaks=seq(40,50,1), sunangle=315,具体两者有何联系和不同,我还真不知道555555,add_shadow是添加之前得到的阴影。
在这里插入图片描述

ambient occlusion shadow layer 环境光遮挡阴影层

具体的我也不懂,大致就是前者计算了全局光照ambient_shade函数是计算间接光照,即物体之间因为反射、折射而导致的光线、阴影变化。使其看起来更真实。

ambmat = ambient_shade(elmat)

elmat %>%
  sphere_shade(texture = "desert") %>%
  add_water(detect_water(elmat), color = "desert") %>%
  add_shadow(raymat) %>%
  add_shadow(ambmat) %>%
  plot_map()

在这里插入图片描述

3D映射制图

这一块是我最喜欢的了,感觉非常的炫酷!ray_shade函数中zscale函数为X和Y间距(假定相等)与Z轴之间的比率(个人感觉dem分辨率30m,zscale应该是30,但是或许设置小一点的值让山变得陡峭可以获得很好的视觉效果,所以plot_3d和ray_shade中的值稍微小一点),其中maxsearch为射线检查的最大距离。add_shadow中max_darken参数为0.5表示图像变暗的限度为50%。

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

在这里插入图片描述

景深渲染

elmat %>%
  sphere_shade(texture = "desert") %>%
  add_water(detect_water(elmat), color = "desert") %>%
  add_shadow(raymat, 0.5) %>%
  add_shadow(ambmat, 0.5) %>%
  plot_3d(elmat, zscale = 10, fov = 30, theta = -225, phi = 25, windowsize = c(1000, 800), zoom = 0.3)
render_depth(focus = 0.6, focallength = 200, clear = TRUE)

在这里插入图片描述

绘制3D水深/地形图

montshadow = ray_shade(montereybay, zscale = 50, lambert = FALSE)
montamb = ambient_shade(montereybay, zscale = 50)
montereybay %>% 
    sphere_shade(zscale = 10, texture = "imhof1") %>% 
    add_shadow(montshadow, 0.5) %>%
    add_shadow(montamb) %>%
    plot_3d(montereybay, zscale = 50, fov = 0, theta = -45, phi = 45, windowsize = c(1000, 800), zoom = 0.75,
            water = TRUE, waterdepth = 0, wateralpha = 0.5, watercolor = "lightblue",
            waterlinecolor = "white", waterlinealpha = 0.5)
render_snapshot(clear = TRUE)

这里的montereybay加利福尼亚州蒙特雷湾水深数据是它自带的。fov视角角度。 theta绕Z轴旋转角度。wateralpha水的透明度,waterdepth 海平面高度。
在这里插入图片描述

不同形状底座

par(mfrow = c(1, 2))
montereybay %>% 
    sphere_shade(zscale = 10, texture = "imhof1") %>% 
    add_shadow(montshadow, 0.5) %>%
    add_shadow(montamb) %>%
    plot_3d(montereybay, zscale = 50, fov = 0, theta = -45, phi = 45, windowsize = c(1000, 800), zoom = 0.6,
            water = TRUE, waterdepth = 0, wateralpha = 0.5, watercolor = "lightblue",
            waterlinecolor = "white", waterlinealpha = 0.5, baseshape = "circle")
render_snapshot(clear = TRUE)

montereybay %>% 
    sphere_shade(zscale = 10, texture = "imhof1") %>% 
    add_shadow(montshadow, 0.5) %>%
    add_shadow(montamb) %>%
    plot_3d(montereybay, zscale = 50, fov = 0, theta = -45, phi = 45, windowsize = c(1000, 800), zoom = 0.6,
            water = TRUE, waterdepth = 0, wateralpha = 0.5, watercolor = "lightblue",
            waterlinecolor = "white", waterlinealpha = 0.5, baseshape = "hex")
render_snapshot(clear = TRUE)

plot_3d函数中waterlinecolor为水图层的边界颜色,waterlinealpha为相应的透明度,baseshape为底座的形状,有"rectangle",“circle”,"hex"三种。
在这里插入图片描述

添加标注

montereybay %>% 
    sphere_shade(zscale = 10, texture = "imhof1") %>% 
    add_shadow(montshadow, 0.5) %>%
    add_shadow(montamb) %>%
    plot_3d(montereybay, zscale = 50, fov = 0, theta = -100, phi = 30, windowsize = c(1000, 800), zoom = 0.6,
            water = TRUE, waterdepth = 0, waterlinecolor = "white", waterlinealpha = 0.5,
            wateralpha = 0.5, watercolor = "lightblue")
render_label(montereybay, x = 350, y = 240, z = 4000, zscale = 50,
             text = "Moss Landing", textsize = 2, linewidth = 5)
render_label(montereybay, x = 220, y = 330, z = 6000, zscale = 50,
             text = "Santa Cruz", color = "darkred", textcolor = "darkred", textsize = 2, linewidth = 5)
render_label(montereybay, x = 300, y = 130, z = 4000, zscale = 50,
             text = "Monterey", dashed = TRUE, textsize = 2, linewidth = 5)
render_label(montereybay, x = 50, y = 130, z = 1000, zscale = 50,
             text = "Monterey Canyon", relativez = FALSE, textsize = 2, linewidth = 5)
render_snapshot(clear = TRUE)

在这里插入图片描述
render_label用法一看便知,不必介绍。但是作者原代码我直接运行会报错:
在这里插入图片描述
这里报错原因是我没安装freetype矢量字体,一种解决方法是每个render_label加上 freetype = "false”,且textsize 改为1,这种方法是改用栅格字体,但是字体大小只能为1,看起来会比较小。
在这里插入图片描述
另一只解决方法是下载安装freetype字体,字体网站的链接是[http://freetype.sourceforge.net/index2.html]

(http://freetype.sourceforge.net/index2.html),具体安装方法自己百度,似乎挺麻烦的。。。我就先搁置了

参考资料:

1.http://www.imooc.com/wenda/detail/451927

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值