Given starting and ending points on a sphere and the center of the sphere, draw the great circle arc between the starting and ending points. If the starting and ending points have different radii, a segment of a logarithmic spiral will join them.

arc3d(from, to, center, radius, n, circle = 50, base = 0,
plot = TRUE, ...)

## Arguments

from

One or more points from which to start arcs.

to

One or more destination points.

center

One or more center points.

If not missing, a vector of length n giving the radii at each point between from and to. If missing, the starting and ending points will be joined by a logarithmic spiral.

n

If not missing, how many segments to use between the first and last point. If missing, a value will be calculated based on the angle between starting and ending points as seen from the center.

circle

How many segments would be used if the arc went completely around a circle.

base

See Details below.

plot

Should the arcs be plotted, or returned as a matrix?

...

Additional parameters to pass to points3d.

## Details

If any of from, to or center is an n by 3 matrix with n > 1, multiple arcs will be drawn by recycling each of these parameters to the number of rows of the longest one.

If the vector lengths of from - center and to - center differ, then instead of a spherical arc, the function will draw a segment of a logarithmic spiral joining the two points.

By default, the arc is drawn along the shortest great circle path from from to to, but the base parameter can be used to modify this. If base = 1 is used, the longer arc will be followed. Larger positive integer values will result in base - 1 loops in that direction completely around the sphere. Negative values will draw the curve in the same direction as the shortest arc, but with abs(base) full loops. It doesn't make much sense to ask for such loops unless the radii of from and to differ, because spherical arcs would overlap. Normally the base parameter is left at its default value of 0.

When base is non-zero, the curve will be constructed in multiple pieces, between from, to, -from and -to, for as many steps as necessary. If n is specified, it will apply to each of these pieces.

## Value

If plot = TRUE, called mainly for the side effect of drawing arcs. Invisibly returns the object ID of the collection of arcs. If plot = FALSE, returns a 3 column matrix containing the points that would be drawn as the arcs.

Duncan Murdoch

## Examples

normalize <- function(v) v/sqrt(sum(v^2))

# These vectors all have the same length

from <- t(apply(matrix(rnorm(9), ncol = 3), 1, normalize))
to <- normalize(rnorm(3))
center <- c(0, 0, 0)

open3d()
spheres3d(center, radius = 1, col = "white", alpha = 0.2)

arc3d(from, to, center, col = "red")
arc3d(from, 2*to, center, col = "blue")

text3d(rbind(from, to, center, 2*to),
text = c(paste0("from", 1:3), "to", "center", "2*to"),
depth_mask = FALSE, depth_test = "always")

{"x":{"material":{"color":"#000000","alpha":1,"lit":true,"ambient":"#000000","specular":"#FFFFFF","emission":"#000000","shininess":50,"smooth":true,"front":"filled","back":"filled","size":3,"lwd":1,"fog":true,"point_antialias":false,"line_antialias":false,"texture":null,"textype":"rgb","texmipmap":false,"texminfilter":"linear","texmagfilter":"linear","texenvmap":false,"depth_mask":true,"depth_test":"less","isTransparent":false,"polygon_offset":[0,0],"margin":"","floating":false,"tag":""},"rootSubscene":45,"objects":{"51":{"id":51,"type":"spheres","material":{"alpha":0.200000002980232,"isTransparent":true},"vertices":"0","colors":"1","radii":[[1]],"centers":"2","ignoreExtent":false,"fastTransparency":true,"flags":32811},"52":{"id":52,"type":"linestrip","material":{"lit":false},"vertices":"3","colors":"4","centers":"5","ignoreExtent":false,"flags":32832},"53":{"id":53,"type":"linestrip","material":{"lit":false},"vertices":"6","colors":"7","centers":"8","ignoreExtent":false,"flags":32832},"54":{"id":54,"type":"text","material":{"lit":false,"depth_mask":false,"depth_test":"always"},"vertices":"9","colors":"10","texts":[["from1"],["from2"],["from3"],["to"],["center"],["2*to"]],"cex":[[1]],"adj":[[0.5,0.5,0.5]],"centers":"11","family":[["sans"]],"font":[[1]],"ignoreExtent":false,"flags":33808},"49":{"id":49,"type":"light","vertices":[[0,0,1]],"colors":[[1,1,1,1],[1,1,1,1],[1,1,1,1]],"viewpoint":true,"finite":false},"48":{"id":48,"type":"background","material":{},"colors":"12","centers":"13","sphere":false,"fogtype":"none","fogscale":1,"flags":32768},"50":{"id":50,"type":"background","material":{"lit":false,"back":"lines"},"colors":"14","centers":"15","sphere":false,"fogtype":"none","fogscale":1,"flags":32768},"45":{"id":45,"type":"subscene","par3d":{"antialias":8,"FOV":30,"ignoreExtent":false,"listeners":45,"mouseMode":{"none":"none","left":"trackball","right":"zoom","middle":"fov","wheel":"pull"},"observer":[0,0,8.01757431030273],"modelMatrix":[[1,0,0,0.138905823230743],[0,0.342020153999329,0.939692616462708,0.134582847356796],[0,-0.939692616462708,0.342020153999329,-8.38733768463135],[0,0,0,1]],"projMatrix":[[3.73205065727234,0,0,0],[0,3.73205065727234,0,0],[0,0,-3.86370325088501,-28.9024276733398],[0,0,-1,0]],"skipRedraw":false,"userMatrix":[[1,0,0,0],[0,0.342020143325668,0.939692620785909,0],[0,-0.939692620785909,0.342020143325668,0],[0,0,0,1]],"userProjection":[[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]],"scale":[1,1,1],"viewport":{"x":0,"y":0,"width":1,"height":1},"zoom":1,"bbox":[-1.30690371990204,1.02909207344055,-1.78698778152466,1,-1,1],"windowRect":[0,0,256,256],"family":"sans","font":1,"cex":1,"useFreeType":true,"fontname":"NULL","maxClipPlanes":2147483647,"glVersion":"NA","activeSubscene":0},"embeddings":{"viewport":"replace","projection":"replace","model":"replace","mouse":"replace"},"objects":[50,51,52,53,54,49],"subscenes":[],"flags":34171}},"crosstalk":{"key":[],"group":[],"id":[],"options":[]},"width":480,"height":480,"context":{"shiny":false,"rmarkdown":null},"buffer":{"accessors":[{"bufferView":0,"componentType":5121,"count":1,"type":"VEC3"},{"bufferView":1,"componentType":5126,"count":1,"type":"VEC4"},{"bufferView":2,"componentType":5121,"count":1,"type":"VEC3"},{"bufferView":3,"componentType":5126,"count":50,"type":"VEC3"},{"bufferView":4,"componentType":5121,"count":1,"type":"VEC4"},{"bufferView":5,"componentType":5126,"count":50,"type":"VEC3"},{"bufferView":6,"componentType":5126,"count":50,"type":"VEC3"},{"bufferView":7,"componentType":5121,"count":1,"type":"VEC4"},{"bufferView":8,"componentType":5126,"count":50,"type":"VEC3"},{"bufferView":9,"componentType":5126,"count":6,"type":"VEC3"},{"bufferView":10,"componentType":5121,"count":1,"type":"VEC4"},{"bufferView":11,"componentType":5126,"count":6,"type":"VEC3"},{"bufferView":12,"componentType":5126,"count":1,"type":"VEC4"},{"bufferView":13,"componentType":5121,"count":1,"type":"VEC3"},{"bufferView":14,"componentType":5121,"count":1,"type":"VEC4"},{"bufferView":15,"componentType":5121,"count":1,"type":"VEC3"}],"bufferViews":[{"buffer":0,"byteLength":3,"byteOffset":0},{"buffer":0,"byteLength":16,"byteOffset":4},{"buffer":0,"byteLength":3,"byteOffset":20},{"buffer":0,"byteLength":600,"byteOffset":24},{"buffer":0,"byteLength":4,"byteOffset":624},{"buffer":0,"byteLength":600,"byteOffset":628},{"buffer":0,"byteLength":600,"byteOffset":1228},{"buffer":0,"byteLength":4,"byteOffset":1828},{"buffer":0,"byteLength":600,"byteOffset":1832},{"buffer":0,"byteLength":72,"byteOffset":2432},{"buffer":0,"byteLength":4,"byteOffset":2504},{"buffer":0,"byteLength":72,"byteOffset":2508},{"buffer":0,"byteLength":16,"byteOffset":2580},{"buffer":0,"byteLength":3,"byteOffset":2596},{"buffer":0,"byteLength":4,"byteOffset":2599},{"buffer":0,"byteLength":3,"byteOffset":2603}],"buffers":[{"byteLength":2606,"bytes":"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\nAACAPwAAAAEBAQEAAAA="}]},"players":[],"webGLoptions":{"preserveDrawingBuffer":true}},"evals":[],"jsHooks":[]}