varias una para pairs librerias grafico graficas graficar grafica ejemplos dibujar curvas curva cuadricula r plot bezier cubic-spline catmull-rom-curve

para - Calcule una curva spline 2D en R



pairs en r (3)

Estoy tratando de calcular una curva spline similar a Bezier que pasa a través de una secuencia de coordenadas xy. Un ejemplo sería como el siguiente resultado de la función cscvn en Matlab ( enlace de ejemplo ):

Creo que el paquete de grid (ya no se mantiene) solía hacer esto (función grid.xspline ?), Pero no he podido instalar una versión archivada del paquete, y no encuentro ningún ejemplo exactamente en la línea de lo que me gustaría

El paquete bezier también parece prometedor, pero es muy lento y tampoco puedo hacerlo del todo bien:

library(bezier) set.seed(1) n <- 10 x <- runif(n) y <- runif(n) p <- cbind(x,y) xlim <- c(min(x) - 0.1*diff(range(x)), c(max(x) + 0.1*diff(range(x)))) ylim <- c(min(y) - 0.1*diff(range(y)), c(max(y) + 0.1*diff(range(y)))) plot(p, xlim=xlim, ylim=ylim) text(p, labels=seq(n), pos=3) bp <- pointsOnBezier(cbind(x,y), n=100) lines(bp$points) arrows(bp$points[nrow(bp$points)-1,1], bp$points[nrow(bp$points)-1,2], bp$points[nrow(bp$points),1], bp$points[nrow(bp$points),2] )

Como puede ver, no pasa por ningún punto, excepto los valores finales.

¡Agradecería mucho alguna orientación aquí!


Puede que no sea el mejor enfoque, la grid bit grid no está inactiva. Se incluye como paquete predeterminado con la instalación R. Es el motor de gráficos subyacente para trazar bibliotecas como celosía y ggplot. No debería necesitar instalarlo, solo debería poder cargarlo. Así es como podría traducir tu código para usar grid.xpline

set.seed(1) n <- 10 x <- runif(n) y <- runif(n) xlim <- c(min(x) - 0.1*diff(range(x)), c(max(x) + 0.1*diff(range(x)))) ylim <- c(min(y) - 0.1*diff(range(y)), c(max(y) + 0.1*diff(range(y)))) library(grid) grid.newpage() pushViewport(viewport(xscale=xlim, yscale=ylim)) grid.points(x, y, pch=16, size=unit(2, "mm"), default.units="native") grid.text(seq(n), x,y, just=c("center","bottom"), default.units="native") grid.xspline(x, y, shape=c(0,rep(-1, 10-2),0), open=TRUE, default.units="native") popViewport()

lo que resulta en

tenga en cuenta que la cuadrícula es bastante baja, por lo que no es muy fácil trabajar con ella, pero le permite un mayor control de qué y dónde trazar.

Y si desea extraer los puntos a lo largo de la curva en lugar de dibujarlos, mire la página de ayuda de " ?xsplinePoints .


Gracias a todos los que ayudaron con esto. Estoy resumiendo las lecciones aprendidas más algunos otros aspectos.

Catmull-Rom spline contra B-spline cúbico

Los valores de forma negativa en la función xspline devuelven una spline tipo Catmull-Rom, con spline pasando por los puntos xy. Los valores positivos devuelven una spline de tipo B cúbico. Los valores cero devuelven una esquina aguda. Si se da un único valor de forma, esto se usa para todos los puntos. La forma de los puntos finales siempre se trata como una esquina aguda (forma = 0), y otros valores no influyen en la spline resultante en los puntos finales:

# Catmull-Rom spline vs. cubic B-spline plot(p, xlim=extendrange(x, f=0.2), ylim=extendrange(y, f=0.2)) text(p, labels=seq(n), pos=3) # Catmull-Rom spline (-1) xspline(p, shape = -1, border="red", lwd=2) # Catmull-Rom spline (-0.5) xspline(p, shape = -0.5, border="orange", lwd=2) # cubic B-spline (0.5) xspline(p, shape = 0.5, border="green", lwd=2) # cubic B-spline (1) xspline(p, shape = 1, border="blue", lwd=2) legend("bottomright", ncol=2, legend=c(-1,-0.5), title="Catmull-Rom spline", col=c("red", "orange"), lty=1) legend("topleft", ncol=2, legend=c(1, 0.5), title="cubic B-spline", col=c("blue", "green"), lty=1)

Extracción de resultados de xspline para trazado externo

Esto requirió cierta búsqueda, pero el truco es aplicar el argumento draw=FALSE a xspline .

# Extract xy values plot(p, xlim=extendrange(x, f=0.1), ylim=extendrange(y, f=0.1)) text(p, labels=seq(n), pos=3) spl <- xspline(x, y, shape = -0.5, draw=FALSE) lines(spl) arrows(x0=(spl$x[length(spl$x)-0.01*length(spl$x)]), y0=(spl$y[length(spl$y)-0.01*length(spl$y)]), x1=(spl$x[length(spl$x)]), y1=(spl$y[length(spl$y)]) )


No hay necesidad de usar la grid realmente. Puede acceder a xspline desde el paquete de graphics .

A continuación de su código y la shape de @mrflick:

set.seed(1) n <- 10 x <- runif(n) y <- runif(n) p <- cbind(x,y) xlim <- c(min(x) - 0.1*diff(range(x)), c(max(x) + 0.1*diff(range(x)))) ylim <- c(min(y) - 0.1*diff(range(y)), c(max(y) + 0.1*diff(range(y)))) plot(p, xlim=xlim, ylim=ylim) text(p, labels=seq(n), pos=3)

Solo necesitas una línea adicional:

xspline(x, y, shape = c(0,rep(-1, 10-2),0), border="red")