rcsr: Compute the Details of a 3D Spline for a Hive Plot Edge

Description Usage Arguments Details Value Author(s) Examples

View source: R/rcsr.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. [email protected]

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
# 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[1], p[2], p[3])
p1 <- c(p[4], p[5], p[6])

### Draw the pts, label them, draw vectors to those pts from origin

segments3d(x = c(0, p[1], 0, p[4]),
	y = c(0, p[2], 0, p[5]),
	z = c(0, p[3], 0, p[6]),
	line_antialias = TRUE, col = "black", lwd = 3)

points3d(x = c(p[1], p[4]),
	y = c(p[2], p[5]),
	z = c(p[3], p[6]),
	point_antialias = TRUE, col = "black", size = 8)
	
text3d(x = c(p[1], p[4]),
	y = c(p[2], p[5]),
	z = c(p[3], p[6]),
	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[1]), y = c(0, s[2]), z = c(0, s[3]),
	line_antialias = TRUE, col = "grey", lwd = 3)

segments3d(x = c(p[1], p[4]), # connect p0 & p1
	y = c(p[2], p[5]),
	z = c(p[3], p[6]),
	line_antialias = TRUE, col = "grey", lwd = 3)

cp <- 0.6*s # Now for the control point

points3d(x = cp[1], # Plot the control point
	y = cp[2],
	z = cp[3],
	point_antialias = TRUE, col = "black", size = 8)

text3d(x = cp[1], # Label the control point
	y = cp[2],
	z = cp[3],
	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)

HiveR documentation built on May 2, 2019, 2:08 a.m.