3D Model Using the rgl Package
[This article was first published on Stats and things, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
A while back, I had a unique opportunity to work with some very talented interns for the summer while I was working at Allstate insurance. Without giving away details of the project that Allstate may prefer to keep secret, let’s just say that we had access to a laser range finder, and were testing it on a cardboard cutout. The laser range finder would give angle and distance in a fan shape directly in front of it. It’s used in robotics to detect obstacles and whatnot. We mounted the scanner on a platform and moved it vertically. That way, we could take a fan shape of measurements incrementally moving up and down giving a 3D view of the target.Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.
The data file was great, but we needed a way to visually inspect the data to check that the trig the interns had to do to get x,y,z data from the angle, angle, distance raw data was correct. So, I fired up R, found the rgl package, and got to work.
There’s really not much to the code, first I read in the data. They gave me a 2D matrix of z values. I created some dummy x and y data, fitted it to some colors, smoothed out some errant laser readings and ran the viewer…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(rgl) | |
file <- "data.txt" | |
smooth <- TRUE | |
# this data file is a list of heights... z | |
# x and y are not given, I just create matrices for them | |
z <- read.delim(file, header=F, sep="|") | |
z[,1] <- NULL # first column is all nulls... junk | |
z <- as.matrix(z) | |
z1 <- dim(z)[1] | |
z2 <- dim(z)[2] | |
# x and y are just indices, fabricated x,y data | |
x1 <- seq(1, z2*2, 2) | |
x <- t(matrix(rep(x1, z1), nrow=z2, ncol=z1)) | |
y <- matrix(rep(seq(1,z1*2,2), z2), z1, z2) | |
zlim <- range(z) | |
zlen <- zlim[2] - zlim[1] + 1 | |
colorlut <- terrain.colors(zlen) # height color lookup table | |
col <- colorlut[ z-zlim[1]+1 ] # assign colors to heights for each point | |
# laser scanner was too bumpy... smooth out some crazy readings. | |
if(smooth){ | |
z[z<800] <- 1000 | |
z[z>1300] <- 1000 | |
z <- z/10 | |
} | |
rgl.open() | |
rgl.surface(x, y, max(z)-z, color=col, back="lines") |
It opens a viewer that you can zoom, tilt, and pan.
There are options to adjust the artificial lighting, the colors, and a bunch of other things, but as you can see, it came out fairly well. This was a 3d cardboard “car” taped to a wall. You can even see evidence of the tape coming out of the roof and windshield.
The code and data are on github here… https://github.com/corynissen/3D_model_demo
follow me on twitter… https://twitter.com/corynissen
To leave a comment for the author, please follow the link and comment on their blog: Stats and things.
R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.