# rcsr: Compute the Details of a 3D Spline for a Hive Plot Edge In bryanhanson/HiveR: 2D and 3D Hive Plots for R

## Description

This is a wild bit of trigonometry! Three points in 3D space, two ends and an control point, are rotated into 2D space. Then a spline curve is computed. This is necessary because spline curves are only defined in `R` as 2D objects. The new collection of points, which is the complete spline curve and when drawn will be the edge of a hive plot, is rotated back into the original 3D space. `rcsr` stands for rotate, compute spline, rotate back.

## Usage

 `1` ```rcsr(p0, cp, p1) ```

## Arguments

 `p0` A triple representing one end of the final curve (x, y, z). `cp` A triple representing the control point used to compute the final curve (x, y, z). `p1` A triple representing the other end of the final curve (x, y, z).

## Details

See the code for exactly how the function works. Based upon the process described at http://www.fundza.com/mel/axis_to_vector/index.html Timing tests show this function is fast and scales linearly (i.e. 10x more splines to draw takes 10x more time). Roughly 3 seconds were required to draw 1,000 spline curves in my testing.

## Value

A 3 column matrix with the x, y and z coordinates to be plotted to create a hive plot edge.

## Author(s)

Bryan A. Hanson, DePauw University. hanson@depauw.edu

## Examples

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139``` ```# This is a lengthy example to prove it works. # Read it and then copy the whole thing to a blank script. # Parts of it require rgl and are interactive. # So none of the below is run during package build/check. ### First, a helper function ## Not run: drawUnitCoord <- function() { # Simple function to draw a unit 3D coordinate system # Draw a Coordinate System r <- c(0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1) # in polar coordinates theta <- c(0, 0, 0, 90, 0, 180, 0, 270, 0, 0, 0, 0) # start, end, start, end phi <- c(0, 90, 0, 90, 0, 90, 0, 90, 0, 0, 0, 180) cs <- data.frame(radius = r, theta, phi) ax.coord <- sph2cart(cs) segments3d(ax.coord, col = "gray", line_antialias = TRUE) points3d( x = 0, y = 0, z = 0, color = "black", size = 4, point_antialias = TRUE ) # plot origin # Label the axes r <- c(1.1, 1.1, 1.1, 1.1, 1.1, 1.1) # in polar coordinates theta <- c(0, 90, 180, 270, 0, 0) phi <- c(90, 90, 90, 90, 0, 180) l <- data.frame(radius = r, theta, phi) lab.coord <- sph2cart(l) text3d(lab.coord, texts = c("+x", "+y", "-x", "-y", "+z", "-z")) } ### Now, draw a reference coordinate system and demo the function in it. drawUnitCoord() ### Draw a bounding box box <- data.frame( x = c(1, -1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, 1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, -1), y = c(1, 1, 1, 1, 1, -1, 1, -1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, 1), z = c(1, 1, 1, -1, 1, 1, -1, -1, -1, -1, 1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, -1, -1) ) segments3d(box\$x, box\$y, box\$z, line_antialias = TRUE, col = "red") ### Draw the midlines defining planes mid <- data.frame( x = c(0, 0, 0, 0, 0, 0, 0, 0, 1, -1, -1, -1, -1, 1, 1, 1, 1, -1, -1, -1, -1, 1, 1, 1), y = c(-1, -1, -1, 1, 1, 1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, 1, 1, 1, 1, -1), z = c(-1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, 1, 1, -1, 0, 0, 0, 0, 0, 0, 0, 0) ) segments3d(mid\$x, mid\$y, mid\$z, line_antialias = TRUE, col = "blue") ### Generate two random points p <- runif(6, -1, 1) # Special case where p1 is on z axis # Uncomment line below to demo # p[4:5] <- 0 p0 <- c(p, p, p) p1 <- c(p, p, p) ### Draw the pts, label them, draw vectors to those pts from origin segments3d( x = c(0, p, 0, p), y = c(0, p, 0, p), z = c(0, p, 0, p), line_antialias = TRUE, col = "black", lwd = 3 ) points3d( x = c(p, p), y = c(p, p), z = c(p, p), point_antialias = TRUE, col = "black", size = 8 ) text3d( x = c(p, p), y = c(p, p), z = c(p, p), col = "black", texts = c("p0", "p1"), adj = c(1, 1) ) ### Locate control point ### Compute and draw net vector from origin thru cp ### Connect p0 and p1 s <- p0 + p1 segments3d( x = c(0, s), y = c(0, s), z = c(0, s), line_antialias = TRUE, col = "grey", lwd = 3 ) segments3d( x = c(p, p), # connect p0 & p1 y = c(p, p), z = c(p, p), line_antialias = TRUE, col = "grey", lwd = 3 ) cp <- 0.6 * s # Now for the control point points3d( x = cp, # Plot the control point y = cp, z = cp, point_antialias = TRUE, col = "black", size = 8 ) text3d( x = cp, # Label the control point y = cp, z = cp, texts = c("cp"), col = "black", adj = c(1, 1) ) ### Now ready to work on the spline curve n2 <- rcsr(p0, cp, p1) # Compute the spline lines3d( x = n2[, 1], y = n2[, 2], z = n2[, 3], line_antialias = TRUE, col = "blue", lwd = 3 ) ### Ta-Da!!!!! ## End(Not run) ```

bryanhanson/HiveR documentation built on June 12, 2020, 2:08 a.m.