Learn R Programming

cgalMeshes (version 2.2.0)

parametricMesh: Mesh of a parametric surface

Description

Mesh of a parametric surface.

Usage

parametricMesh(
  f,
  urange,
  vrange,
  periodic = c(FALSE, FALSE),
  nu,
  nv,
  clean = FALSE,
  fcolor = NULL,
  fnormal = NULL
)

Value

A rgl mesh (mesh3d object), with normals if

fnormal is given.

Arguments

f

vectorized function of two variables returning a three-dimensional point

urange, vrange

the ranges of the two variables

periodic

two Boolean values, whether f is periodic in the first variable and in the second variable

nu, nv

numbers of subdivisions

clean

Boolean, whether to merge the duplicated vertices in the output mesh; use only if necessary because it costs time

fcolor

if given (i.e. not NULL), a vectorized function returning at (u,v) a color for the vertex f(u,v); the behavior is undefined if some vertices are merged by clean=TRUE

fnormal

if given (i.e. not NULL), a vectorized function returning at (u,v) the normal for the vertex f(u,v); the behavior is undefined if some vertices are merged by clean=TRUE

Examples

Run this code
library(cgalMeshes)
library(rgl)
# Richmond surface
Richmond <- function(r, t){
  radius <- 0.5
  r <- r + 1/4
  exprho <- exp(r*(1 + 3*radius) - 2 - radius)
  u <- exprho * cospi(2*t)
  v <- exprho * sinpi(2*t)
  rbind(
    -v/(u*u+v*v) - u*u*v + v*v*v/3,
    3*u,
     u/(u*u+v*v) - u*v*v + u*u*u/3
  ) 
}
rmesh <- parametricMesh(
  Richmond, urange = c(0, 1), vrange = c(0, 1),
  periodic = c(FALSE, TRUE), nu = 100, nv = 100
)
rmesh <- addNormals(rmesh)
# plot
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(50, 10, zoom = 0.8)
shade3d(rmesh, color = "gold")

# an example with normals ####
library(cgalMeshes)
library(rgl)
# twisted sphere
fx <- function(u, v) cos(u) * cos(v)
fy <- function(u, v) sin(u) * cos(v)
fz <- function(u, v) sin(v) + u
f <- function(u, v) {
  rbind(fx(u, v), fy(u, v), fz(u, v))
}
if(require("dfdr")) {
  # compute the gradient with the 'dfdr' package
  dfx <- gradient(fx, FALSE, u, v)
  dfy <- gradient(fy, FALSE, u, v)
  dfz <- gradient(fz, FALSE, u, v)
  fnormal <- Vectorize(function(u, v) {
    dx <- dfx(u, v)
    dy <- dfy(u, v)
    dz <- dfz(u, v)
    v1 <- c(dx[1L], dy[1L], dz[1L])
    v2 <- c(dx[2L], dy[2L], dz[2L])
    - crossProduct(v1, v2)
  })
} else {
  fnormal <- NULL
}
# compute mesh of the parametric surface
rmesh <- cgalMeshes::parametricMesh(
  f, c(0, 2*pi), c(0, 2*pi), c(FALSE, TRUE), nu = 60L, nv = 30L, 
  fnormal = fnormal
)
# plot
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(50, 10) 
shade3d(rmesh, color = "midnightblue", specular = "black")

##| example with colors: torus figure 8 ####
library(rgl)
library(cgalMeshes)
library(colorspace) # to use the  lighten  function
# function mapping (u,v) to a color
clrs <- c(
  hcl.colors(128L, "Rocket"), 
  hcl.colors(128L, "Rocket", rev = TRUE)
)
framp <- colorRamp(clrs)
fcolor <- function(u, v) {
  cols <- framp(v/(2*pi))
  cols <- rgb(cols[, 1L], cols[, 2L], cols[, 3L], maxColorValue = 255)
  lighten(cols, 0.3*cos(u))
}
# parameterization
f <- function(u, v, c = 1){
  h <- c + sin(v) * cos(u) - sin(2*v) * sin(u) / 2
  x <- h * cos(u)
  y <- h * sin(u)
  z <- sin(u) * sin(v) + cos(u) * sin(2*v) / 2
  rbind(x, y, z)  
}
# make the mesh and plot it
rmesh <- parametricMesh(
  f, c(0, 2*pi), c(0, 2*pi), periodic = c(TRUE, TRUE),
  nu = 100L, nv = 100L, fcolor = fcolor)
rmesh <- addNormals(rmesh)
open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.9)
shade3d(rmesh, meshColor = "vertices")

Run the code above in your browser using DataLab