Defines a clipping plane for render_options(). Geometry on the
negative side of the plane is removed, i.e. a point p is kept when
dot(normal, p) + offset >= 0.
Usage
clip_plane(normal, offset = 0, space = c("world", "eye"))Arguments
- normal
Numeric vector of length 3: the plane normal. It points toward the side of the plane that is kept. It does not have to be unit-length; it is normalized internally and
offsetis always interpreted as a distance in world units.- offset
Numeric scalar: the signed distance of the plane from the origin along
normal, in world units. For exampleoffset = -dplaces the plane at distancedfrom the origin (in the direction ofnormal).- space
Character, either
"world"(default) or"eye":"world"The plane is fixed in world coordinates and does not move when the camera moves. This is the convention used by rgl's
clipplanes3d(), VTK/PyVista, ParaView and three.js."eye"The plane is defined relative to the camera, i.e.
offsetis a distance from the camera, and the plane moves and rotates with it.
Value
A list with components normal, offset and
space, suitable for the clip_planes argument of
render_options().
Details
By default the plane is defined in world space, so the cut is a
fixed feature of the scene: it does not move when the camera is moved
around, which is what you want for cross-sections and multi-view figures.
Set space = "eye" for a camera-relative plane that travels with the
camera (the classic OpenGL glClipPlane behaviour), e.g. for
cutaway views.
Examples
# World space (default): keep the half of the scene with x <= 0.
# The cut stays at x = 0, no matter where the camera is placed.
clip_plane(normal = c(-1, 0, 0), offset = 0)
#> $normal
#> [1] -1 0 0
#>
#> $offset
#> [1] 0
#>
#> $space
#> [1] "world"
#>
# Keep only the part with z >= -0.5 (remove everything below z = -0.5):
clip_plane(normal = c(0, 0, 1), offset = 0.5)
#> $normal
#> [1] 0 0 1
#>
#> $offset
#> [1] 0.5
#>
#> $space
#> [1] "world"
#>
# Eye space: remove everything closer than 2 units to the camera
# (a camera-attached cutaway).
clip_plane(normal = c(0, 0, -1), offset = -2, space = "eye")
#> $normal
#> [1] 0 0 -1
#>
#> $offset
#> [1] -2
#>
#> $space
#> [1] "eye"
#>
# A world-space cut through a cuboid; the cut stays at x = 0 for any camera
cuboid <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
cut_opts <- render_options(clip_planes = list(
clip_plane(normal = c(-1, 0, 0), offset = 0)))
mesh_pixels <- function(img) sum(image_to_array(img)[, , 1] < 1)
cam <- camera(eye = c(3, 3, 3), center = c(0, 0, 0))
full <- render_mesh(cuboid$vertices, cuboid$triangles, camera = cam)
cut <- render_mesh(cuboid$vertices, cuboid$triangles, camera = cam,
options = cut_opts)
mesh_pixels(cut) < mesh_pixels(full) # TRUE: half of the cuboid is gone
#> [1] TRUE