| Title: | Voxel Data Visualization with Isometric Cubes |
|---|---|
| Description: | A voxel is a representation of a value on a regular, three-dimensional grid; it is the 3D equivalent of a 2D pixel. Voxel data can be visualised with this package using fixed viewpoint isometric cubes for each data point. This package also provides sample voxel data and tools for transforming the data. |
| Authors: | Mike Cheng [aut, cre, cph] |
| Maintainer: | Mike Cheng <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 1.0.0 |
| Built: | 2026-05-12 08:46:54 UTC |
| Source: | https://github.com/coolbutuseless/isocubes |
Calculate voxel coordinates from a matrix where values in the matrix indicate height above the ground
calc_heightmap_coords( mat, fill = NULL, scale = 1, flipx = FALSE, flipy = TRUE, ground = "xy", solid = TRUE, check_visibility = FALSE, verbose = FALSE )calc_heightmap_coords( mat, fill = NULL, scale = 1, flipx = FALSE, flipy = TRUE, ground = "xy", solid = TRUE, check_visibility = FALSE, verbose = FALSE )
mat |
integer matrix. The matrix will be interpreted as cubes flat on the page, with the value in the matrix interpreted as the height above the page. |
fill |
matrix of colours the same dimensions as the |
scale |
scale factor for values in matrix. Default = 1 |
flipx, flipy
|
Should the matrix be flipped in the horizontal/vertical directions (respectively)?
Default: Note: |
ground |
Orientation of the ground plane. Default: 'xy'. Possible values 'xz', 'xy' |
solid |
Should the heightmap be made 'solid' i.e. without holes? default: TRUE. This can be an expensive operation in terms of both memory and CPU, but should be OK for simple examples. Set to FALSE if things take too long. This operation works by extruding cubes down from the top of the height map to the floor to ensure gaps do not appear when the slope is too great. |
check_visibility |
Should non-visible cubes be removed? Default: FALSE. If you plan on rotating or manipulating the returned coordinates then this should definitely by FALSE. If TRUE, then non-visible voxels will be entirely removed from the returned coordinates i.e. they will be missing if you change the rendering viewpoint from the default. |
verbose |
Be verbose? default: FALSE |
data.frame of voxel coordinates
# Plot the standard volcano mat <- volcano # normalise height mat <- mat - min(mat) # Assign a distinct colour for each height value val <- as.vector(mat) val <- round(255 * val / max(val)) fill <- matrix("", nrow=nrow(mat), ncol=ncol(mat)) fill[] <- terrain.colors(256)[val + 1L] # Calculate coordinates of heightmap, render as isocubes coords <- calc_heightmap_coords(mat, fill = fill, scale = 0.3) head(coords) isocubesGrob(coords, size = 2, y = 0) |> grid::grid.draw()# Plot the standard volcano mat <- volcano # normalise height mat <- mat - min(mat) # Assign a distinct colour for each height value val <- as.vector(mat) val <- round(255 * val / max(val)) fill <- matrix("", nrow=nrow(mat), ncol=ncol(mat)) fill[] <- terrain.colors(256)[val + 1L] # Calculate coordinates of heightmap, render as isocubes coords <- calc_heightmap_coords(mat, fill = fill, scale = 0.3) head(coords) isocubesGrob(coords, size = 2, y = 0) |> grid::grid.draw()
Returned value is depth-sorted in back-to-front rendering order
calc_visibility( coords, xyplane = "flat", handedness = "right", value = "index", verbosity = 0, ... )calc_visibility( coords, xyplane = "flat", handedness = "right", value = "index", verbosity = 0, ... )
coords |
data.frame of x,y,z coordinates for the cubes (integer coordinates) |
xyplane |
How is the xyplane oriented with respect to the unit isometric cube?. "left", "right", "flat" (or "top"). Default: "flat". |
handedness |
How is the z-axis positioned with respect to the xy-plane? I.e. is this a right-handed or left-handed coordinate system? Default: "right" |
value |
type of value to return. Default: 'index'. Valid values are 'index' and 'full'. If 'index', then returns an integer vector of which rows to render in back-to-front ordering. 'full' returns more information in a data.frame |
verbosity |
Verbosity level. Default: 0 |
... |
other values passed to |
if value argument is 'index' then integer vector of visible
vertices in back-to-front draw ordering.
For value = 'full' return a data.frame with more complete
information.
obj_sphere <- gen_sphere() nrow(obj_sphere) calc_visibility(obj_sphere) |> length() calc_visibility(obj_sphere, value = 'full') |> head()obj_sphere <- gen_sphere() nrow(obj_sphere) calc_visibility(obj_sphere) |> length() calc_visibility(obj_sphere, value = 'full') |> head()
Align the object with the given coordinates
coord_align(coords, loc = c(0, 0, 0), x = "mean", y = "mean", z = "mean")coord_align(coords, loc = c(0, 0, 0), x = "mean", y = "mean", z = "mean")
coords |
data.frame with 'x', 'y' and 'z' coordinates |
loc |
location to align to. Default: c(0, 0, 0) |
x, y, z
|
how to align the x coordinates to the given location. Default: 'mean'. Valid values 'min', 'mean', 'max', 'identity', 'median' |
data.frame of transformed coordinates
gen_sphere() |> coord_align(z = 'max', y = 'min') |> isocubesGrob(size = 3) |> grid::grid.draw()gen_sphere() |> coord_align(z = 'max', y = 'min') |> isocubesGrob(size = 3) |> grid::grid.draw()
Rotate object around a coordinate axis
coord_rotate(coords, theta, axis = "z")coord_rotate(coords, theta, axis = "z")
coords |
data.frame with 'x', 'y' and 'z' coordinates |
theta |
angle in radians. |
axis |
axis to rotate around. Default: 'z'. Valid values: 'x', 'y', 'z' |
data.frame of transformed coordinates
obj_letter |> coord_rotate(pi/2, 'y') |> isocubesGrob() |> grid::grid.draw()obj_letter |> coord_rotate(pi/2, 'y') |> isocubesGrob() |> grid::grid.draw()
Translate object
coord_translate(coords, x = 0, y = 0, z = 0)coord_translate(coords, x = 0, y = 0, z = 0)
coords |
data.frame with 'x', 'y' and 'z' coordinates |
x, y, z
|
amount to translate along each axis. Default: 0 |
data.frame of transformed coordinates
gen_sphere() |> coord_translate(x = 20, z = 40) |> isocubesGrob(size = 2) |> grid::grid.draw()gen_sphere() |> coord_translate(x = 20, z = 40) |> isocubesGrob(size = 2) |> grid::grid.draw()
Generate voxel coordinates defined by an implicit function
gen_isosurface( f, upper = 0, lower = -Inf, scale = 1, nx = 51, ny = nx, nz = nx )gen_isosurface( f, upper = 0, lower = -Inf, scale = 1, nx = 51, ny = nx, nz = nx )
f |
function of the form |
lower, upper
|
When the supplied function is evaluated, the lower and upper limits define the range of values which will be considered to be inside the object. The efault [-Inf, 0] means that any value less than or equal to zero is inside, and all positive values are outside. |
scale |
extra scaling factor applied to coordinates before calling function |
nx, ny, nz
|
the dimensions of the volume within which the function will be evaluated |
data.frame of coordinates
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Create a sphere of radius 10 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ coords <- gen_isosurface( f = function(x, y, z) {x^2 + y^2 + z^2}, upper = 10^2 ) coords |> isocubesGrob() |> grid::grid.draw() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Create a complex shape #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ grid::grid.newpage() f <- function(x, y, z) { (x-2)^2 * (x+2)^2 + (y-2)^2 * (y+2)^2 + (z-2)^2 * (z+2)^2 + 3 * (x^2 * y^2 + x^2 * z^2 + y^2 * z^2) + 6 * x * y * z - 10 * (x^2 + y^2 + z^2) + 22 } gen_isosurface( f = f, scale = 0.1, nx = 70 ) |> isocubesGrob(size = 2) |> grid::grid.draw()#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Create a sphere of radius 10 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ coords <- gen_isosurface( f = function(x, y, z) {x^2 + y^2 + z^2}, upper = 10^2 ) coords |> isocubesGrob() |> grid::grid.draw() #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # Create a complex shape #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ grid::grid.newpage() f <- function(x, y, z) { (x-2)^2 * (x+2)^2 + (y-2)^2 * (y+2)^2 + (z-2)^2 * (z+2)^2 + 3 * (x^2 * y^2 + x^2 * z^2 + y^2 * z^2) + 6 * x * y * z - 10 * (x^2 + y^2 + z^2) + 22 } gen_isosurface( f = f, scale = 0.1, nx = 70 ) |> isocubesGrob(size = 2) |> grid::grid.draw()
To simplify implementation, only odd side lengths are generated.
gen_prism(x = 5, y = x, z = x)gen_prism(x = 5, y = x, z = x)
x, y, z
|
prism dimensions. Default 5x5x5. Note that due to the quantization of coordinates to integer values for rendering, this function rounds up even dimensions to the next odd number. |
data.frame of voxel coordinates
gen_prism(3, 5, 7) |> isocubesGrob() |> grid::grid.draw()gen_prism(3, 5, 7) |> isocubesGrob() |> grid::grid.draw()
Generate voxel coordinates for a sphere centered at the origin
gen_sphere(r = 10)gen_sphere(r = 10)
r |
radius. Default: 10 |
data.frame of voxel coordinates
gen_sphere(1) |> isocubesGrob() |> grid::grid.draw()gen_sphere(1) |> isocubesGrob() |> grid::grid.draw()
The x, y and z axes are drawn in red, green and blue respectively.
isoaxesGrob( size = 5, x = 0.5, y = 0.5, default.units = "mm", xyplane = "flat", handedness = "right", labels = TRUE, verbosity = 0, ... )isoaxesGrob( size = 5, x = 0.5, y = 0.5, default.units = "mm", xyplane = "flat", handedness = "right", labels = TRUE, verbosity = 0, ... )
size |
length of each axis in |
x, y
|
the origin of the isometric coordinate system.
If these values are given as vanilla floating point values, they
will be interpreted as 'npc' units, otherwise a valid grid unit
object must be supplied.
By default the origin is the middle of the graphics device
i.e. |
default.units |
Default unit for size of a cube is 'mm' |
xyplane |
How is the xyplane oriented with respect to the unit isometric cube?. "left", "right", "flat" (or "top"). Default: "flat". |
handedness |
How is the z-axis positioned with respect to the xy-plane? I.e. is this a right-handed or left-handed coordinate system? Default: "right" |
labels |
Include axis labels? Default: TRUE |
verbosity |
Verbosity level. Default: 0 |
... |
other values passed to |
grid grob object
isoaxesGrob() |> grid::grid.draw()isoaxesGrob() |> grid::grid.draw()
Create a grob of isocubes representing the voxels at the given coordiantes
isocubesGrob( coords, fill = NULL, fill_left = NULL, fill_right = NULL, intensity = c(1, 0.3, 0.7), size = 5, x = 0.5, y = 0.5, col = "black", default.units = "mm", xyplane = "flat", handedness = "right", verbosity = 0, ... )isocubesGrob( coords, fill = NULL, fill_left = NULL, fill_right = NULL, intensity = c(1, 0.3, 0.7), size = 5, x = 0.5, y = 0.5, col = "black", default.units = "mm", xyplane = "flat", handedness = "right", verbosity = 0, ... )
coords |
data.frame of x,y,z coordinates for the cubes (integer coordinates) |
fill |
fill colour for the top face of cube. Default: NULL will attempt to use the 'fill' colour in the coords data.frame, otherwise 'grey50' |
fill_left, fill_right
|
fill colours for left and fight faces of cube. |
intensity |
c(1, 0.3, 0.6) Intensity shading for |
size |
dimensions of cube i.e. the length of the vertical edge of the cube. Default: 5mm |
x, y
|
the origin of the isometric coordinate system.
If these values are given as vanilla floating point values, they
will be interpreted as 'npc' units, otherwise a valid grid unit
object must be supplied.
By default the origin is the middle of the graphics device
i.e. |
col |
Stroke colour for outline of cube faces. Default: black. If |
default.units |
Default unit for size of a cube is 'mm' |
xyplane |
How is the xyplane oriented with respect to the unit isometric cube?. "left", "right", "flat" (or "top"). Default: "flat". |
handedness |
How is the z-axis positioned with respect to the xy-plane? I.e. is this a right-handed or left-handed coordinate system? Default: "right" |
verbosity |
Verbosity level. Default: 0 |
... |
other values passed to |
grid grob object
obj_sphere <- gen_sphere(r = 10) fill <- rainbow(nrow(obj_sphere)) isocubesGrob(obj_sphere, fill = fill, size = 2) |> grid::grid.draw() # The 'obj_organic' data.frame includes a 'fill' column which will be # used by default grid::grid.newpage() isocubesGrob(obj_organic, size = 2) |> grid::grid.draw()obj_sphere <- gen_sphere(r = 10) fill <- rainbow(nrow(obj_sphere)) isocubesGrob(obj_sphere, fill = fill, size = 2) |> grid::grid.draw() # The 'obj_organic' data.frame includes a 'fill' column which will be # used by default grid::grid.newpage() isocubesGrob(obj_organic, size = 2) |> grid::grid.draw()
Create grob representing isometric grid of lines
isolinesGrob( N = 50, size = 5, x = 0.5, y = 0.5, col = "black", default.units = "mm", verbosity = 0, ... )isolinesGrob( N = 50, size = 5, x = 0.5, y = 0.5, col = "black", default.units = "mm", verbosity = 0, ... )
N |
extents |
size |
dimensions of cube i.e. the length of the vertical edge of the cube. Default: 5mm |
x, y
|
the origin of the isometric coordinate system.
If these values are given as vanilla floating point values, they
will be interpreted as 'npc' units, otherwise a valid grid unit
object must be supplied.
By default the origin is the middle of the graphics device
i.e. |
col |
Stroke colour for outline of cube faces. Default: black. If |
default.units |
Default unit for size of a cube is 'mm' |
verbosity |
Verbosity level. Default: 0 |
... |
other values passed to |
isometric line grid
isolinesGrob() |> grid::grid.draw()isolinesGrob() |> grid::grid.draw()
Create grob representing isometric grid of points
isopointsGrob( N = 50, size = 5, x = 0.5, y = 0.5, col = "black", pch = ".", default.units = "mm", verbosity = 0, ... )isopointsGrob( N = 50, size = 5, x = 0.5, y = 0.5, col = "black", pch = ".", default.units = "mm", verbosity = 0, ... )
N |
extents |
size |
dimensions of cube i.e. the length of the vertical edge of the cube. Default: 5mm |
x, y
|
the origin of the isometric coordinate system.
If these values are given as vanilla floating point values, they
will be interpreted as 'npc' units, otherwise a valid grid unit
object must be supplied.
By default the origin is the middle of the graphics device
i.e. |
col |
Stroke colour for outline of cube faces. Default: black. If |
pch |
plotting character. default '.' |
default.units |
Default unit for size of a cube is 'mm' |
verbosity |
Verbosity level. Default: 0 |
... |
other values passed to |
isometric point grid
isopointsGrob(pch = '+') |> grid::grid.draw()isopointsGrob(pch = '+') |> grid::grid.draw()
Voxel coordinates for the letter R
obj_letterobj_letter
An object of class data.frame with 68 rows and 3 columns.
Other datasets:
obj_organic,
obj_test
head(obj_letter) isocubesGrob(obj_letter, size = 5, y = 0.05) |> grid::grid.draw()head(obj_letter) isocubesGrob(obj_letter, size = 5, y = 0.05) |> grid::grid.draw()
Voxel coordinates for an organic shape
obj_organicobj_organic
An object of class tbl_df (inherits from tbl, data.frame) with 14292 rows and 4 columns.
Other datasets:
obj_letter,
obj_test
head(obj_organic) cubes <- isocubesGrob(obj_organic, size = 2) |> grid::grid.draw()head(obj_organic) cubes <- isocubesGrob(obj_organic, size = 2) |> grid::grid.draw()
Voxel coordinates for a test object useful for debugging orientation and visibility checks
obj_testobj_test
An object of class data.frame with 16 rows and 4 columns.
Other datasets:
obj_letter,
obj_organic
head(obj_test) isocubesGrob(obj_test, size = 5, y = 0.05) |> grid::grid.draw()head(obj_test) isocubesGrob(obj_test, size = 5, y = 0.05) |> grid::grid.draw()
Generate a random colour palette
rand_palette(N = 256, seed = NULL)rand_palette(N = 256, seed = NULL)
N |
number of colors |
seed |
integer seed. Default: NULL |
character vector of colors
rand_palette(N = 20)rand_palette(N = 20)