suppressPackageStartupMessages({
  library(ggplot2)
  library(magrittr)

  library(threed)
})


knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
library(ggplot2)

library(threed)

Introduction

Prepare an object for plotting

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# The `threed` package has some builtin objects in `threed::mesh3dobj`
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
obj <- threed::mesh3dobj$cube

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Define camera 'lookat' matrix i.e. camera-to-world transform
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
camera_to_world <- threed::look_at_matrix(eye = c(1.5, 1.75, 4), at = c(0, 0, 0))

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Transform the object into camera space and do perspective projection
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
obj <- obj %>%
  transform_by(invert_matrix(camera_to_world)) %>%
  perspective_projection()
as.data.frame(obj) %>% knitr::kable()

Plot the points for the vertices of the object

ggplot(obj, aes(x, y)) +
  geom_point() +
  theme_void() +
  theme(legend.position = 'none') +
  coord_equal()

Plot the outline of each polygon

ggplot(obj, aes(x, y, group = element_id)) +
  geom_polygon(fill = NA, colour = 'black', size = 0.2) +
  theme_void() +
  theme(legend.position = 'none') +
  coord_equal()

Dotted rendering of hidden lines

ggplot(obj, aes(x, y, group = element_id)) +
  geom_polygon(fill = NA, colour='black', aes(linetype = hidden,  size = hidden)) +
  scale_linetype_manual(values = c('TRUE' = "dotted", 'FALSE' = 'solid')) +
  scale_size_manual(values = c('TRUE' = 0.2, 'FALSE' = 0.5)) +
  theme_void() +
  theme(legend.position = 'none') +
  coord_equal()

Hidden line removal

ggplot(obj, aes(x, y, group = element_id)) +
  geom_polygon(fill = NA, colour = 'black', aes(size = hidden)) +
  scale_size_manual(values = c('TRUE' = 0, 'FALSE' = 0.5)) +
  theme_void() +
  theme(legend.position = 'none') +
  coord_equal()

Naive Filled Polygons

ggplot(obj, aes(x, y, group = element_id)) +
  geom_polygon(fill = 'lightblue', colour = 'black', size = 0.2) +
  theme_void() +
  theme(legend.position = 'none') +
  coord_equal()

Filled Polygons - (1) Drop hidden elements so they never get drawn

obj_df <- as.data.frame(obj) 
obj_df <- subset(obj_df, !obj_df$hidden)

ggplot(obj_df, aes(x, y, group = element_id)) +
  geom_polygon(fill = 'lightblue', colour = 'black', size = 0.2) +
  theme_void() +
  theme(legend.position = 'none') +
  coord_equal()

Filled Polygons - (2) Assign hidden elements a fill of NA so they get drawn invisibly

obj_df <- as.data.frame(obj) %>%
  transform(
    shade      = ifelse(hidden, NA, 'lightblue'),
    linecolour = ifelse(hidden, NA, 'black')
  )

ggplot(obj_df, aes(x, y, group = element_id)) +
  geom_polygon(aes(fill = I(shade), colour = I(linecolour)), size = 0.2) +
  theme_void() +
  theme(legend.position = 'none') +
  coord_equal() 

Filled Polygons - (3) Use the zorder variable to control draw order

ggplot(obj, aes(x, y, group = zorder)) +
  geom_polygon(fill = 'lightblue', colour='black', size = 0.2) +
  theme_void() +
  theme(legend.position = 'none') +
  coord_equal() 

Fake-shaded polygon

ggplot(obj, aes(x, y, group = zorder)) +
  geom_polygon(aes(fill = fny + fnz), colour = 'black', size = 0.2) +
  theme_void() +
  theme(legend.position = 'none') +
  coord_equal()


coolbutuseless/threed documentation built on May 5, 2019, 7:08 a.m.