mikefc

threed - 3d object transformation library

threed is a small, dependency-free R library for doing 3d object transformations i.e. translation, scaling, rotation and perspective projection.

The only 3d object format currently supported is the mesh3d format from rgl (as well as some extensions to the mesh3d format to support point and line objects).

Features:

  • standard translate, scale and rotate transformations
  • perspective + orthographic projection
  • as.data.frame.mesh3d
    • convert 3d objects into data.frames
    • calculates a lot of meta data such as face normals, vertex normals and whether a face is hidden from view.
  • fortify.mesh3d
    • this enables a mesh3d object to be given as the ggplot2 data argument.
  • Includes some built-in mesh3d objects (see threed::mesh3dobj) e.g.
    • cube, icosahedron, teapot, cow, bunny

Rendering objects

  • threed is just a 3d object transformation package and does not include any facility for rendering of objects.
  • Examples are included below showing how to convert 3d objects to a data.frame and then render with:
    • ggplot2 and geom_polygon()
    • Base R plotting with polygon()

Installation

# install.packages("devtools")
devtools::install_github("coolbutuseless/threed")

Drawing a cube in ggplot2

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Define camera position and what it's looking at.
# Use the inverse of this to transform all objects in the world
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
camera_to_world <- threed::look_at_matrix(eye = c(3, 4, 5), at = c(0, 0, 0))

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#  - take a cube object
#  - position it in the camera view
#  - perform perspective projection
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
obj <- threed::mesh3dobj$cube %>%
  transform_by(invert_matrix(camera_to_world)) %>%
  perspective_projection()

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Use ggplot to plot the obj
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ggplot(obj) + 
  geom_polygon(aes(x = x, y = y, group = zorder, fill = 0.5 * fnx + fny), colour = 'black', size = 0.2) +
  theme_minimal() +
  theme(
    legend.position = 'none',
    axis.text       = element_blank()
  ) +
  coord_equal()