首页 > 解决方案 > 使用可自定义的插值点数计算 R 中的 2d 样条路径

问题描述

我想在 R 中计算(而不是绘制)2d 样条路径。关于该主题有一个老问题建议xspline()在 R 中计算 2D 样条曲线

xspline()有点适合我的目的,但有重要的限制:

可重现的例子:

library(ggplot2)

# control points
x <- c(.1, .5, .7, .8)
y <- c(.9, .6, .5, .1)

plot.new() # necessary for xspline(); would be great if it could be avoided

# how do I set the number of interpolation points?
# how do I modify the exact path (beyond shape parameter)?
path <- xspline(x, y, shape = 1, draw = FALSE)

# plot path (black) and control points (blue) with ggplot
ggplot(data = NULL, aes(x, y)) +
  geom_point(data = as.data.frame(path), size = 0.5) +
  geom_point(data = data.frame(x, y), size = 2, color = "blue")

reprex 包于 2021-08-14 创建 (v2.0.0 )

有没有容易获得的替代品xspline()

标签: rggplot2

解决方案


{grid} 包中的xsplinePoints()允许您将xsplineGrob对象转换为 xy 坐标。一种解决方案可能是将这些函数包装为沿 x 样条返回点。

library(grid)
splines <- function(x, y, shape = 1, ..., density = 1) {
  # Density controls number of points, though not the exact number
  xs <- xsplineGrob(x * density, y * density, shape = shape, ...,
                    default.units = "inches")
  # xsplinePoints seem to always return inches
  xy <- xsplinePoints(xs)
  # Drop units
  xy <- lapply(xy, convertUnit, unitTo = "inches", valueOnly = TRUE)
  data.frame(x = xy$x / density,  y = xy$y / density)
}

我认为xsplinePoints()根据图形设备的大小进行一些幕后计算,其中较小的设备需要较少的点。该density参数背后的想法是让您(间接)控制返回的点数,方法是在将数据交给网格之前人为地膨胀尺寸,然后在返回给用户之前放气。

与您的示例进行比较:

library(ggplot2)

# control points
x <- c(.1, .5, .7, .8)
y <- c(.9, .6, .5, .1)

plot.new() 

path <- xspline(x, y, shape = 1, draw = FALSE)

# plot path (black) and control points (blue) with ggplot
ggplot(data = NULL, aes(x, y)) +
  geom_point(data = as.data.frame(path), size = 0.5) +
  geom_point(data = data.frame(x, y), size = 2, color = "blue") +
  # density = 1 (red) and density = 3 (green)
  geom_point(data = splines(x, y), colour = "red") +
  geom_point(data = splines(x, y, density = 3), colour = "green")

reprex 包(v1.0.0)于 2021 年 8 月 14 日创建


推荐阅读