r - 右转

标签 r plot rotational-matrices

我有一个问题,我有一堆长度,想从原点开始(假装我正对着y轴的正端),我做一个右并沿着x轴正向移动了length_i的距离。这时我再右拐,走length_i的距离并重复n次。我可以做到,但是我认为有一种更有效的方法,而且我缺乏数学背景:

## Fake Data
set.seed(11)
dat <- data.frame(id = LETTERS[1:6], lens=sample(2:9, 6), 
    x1=NA, y1=NA, x2=NA, y2=NA)

##   id lens x1 y1 x2 y2
## 1  A    4 NA NA NA NA
## 2  B    2 NA NA NA NA
## 3  C    5 NA NA NA NA
## 4  D    8 NA NA NA NA
## 5  E    6 NA NA NA NA
## 6  F    9 NA NA NA NA

## Add a cycle of 4 column    
dat[, "cycle"] <- rep(1:4, ceiling(nrow(dat)/4))[1:nrow(dat)]

##For loop to use the information from cycle column
for(i in 1:nrow(dat)) {

    ## set x1, y1
    if (i == 1) {
       dat[1, c("x1", "y1")] <- 0
    } else {
       dat[i, c("x1", "y1")] <- dat[(i - 1), c("x2", "y2")]
    }

    col1 <- ifelse(dat[i, "cycle"] %% 2 == 0, "x1", "y1")
    col2 <- ifelse(dat[i, "cycle"] %% 2 == 0, "x2", "y2")
    dat[i, col2] <- dat[i, col1]

    col3 <- ifelse(dat[i, "cycle"] %% 2 != 0, "x2", "y2")
    col4 <- ifelse(dat[i, "cycle"] %% 2 != 0, "x1", "y1")
    mag <- ifelse(dat[i, "cycle"] %in% c(1, 4), 1, -1)
    dat[i, col3] <- dat[i, col4] + (dat[i, "lens"] * mag)

}


这样可以得到预期的结果:

> dat

  id lens x1 y1 x2 y2 cycle
1  A    4  0  0  4  0     1
2  B    2  4  0  4 -2     2
3  C    5  4 -2 -1 -2     3
4  D    8 -1 -2 -1  6     4
5  E    6 -1  6  5  6     1
6  F    9  5  6  5 -3     2


这是一个情节:

library(ggplot2); library(grid)
ggplot(dat, aes(x = x1, y = y1, xend = x2, yend = y2)) + 
    geom_segment(aes(color=id), size=3, arrow = arrow(length = unit(0.5, "cm"))) + 
    ylim(c(-10, 10)) + xlim(c(-10, 10))


这似乎很慢而且笨拙。我想有一种比for循环中的项目更好的方法。保持程序权利的一种更有效的方法是什么?

最佳答案

(如@DWin所建议)这是一个使用复数的解决方案,它对任何类型的turn都具有灵活性,而不仅仅是90度(-pi / 2弧度)直角。一切都是矢量化的:

set.seed(11)
dat <- data.frame(id = LETTERS[1:6], lens = sample(2:9, 6),
                                     turn = -pi/2)

dat <- within(dat, { facing   <- pi/2 + cumsum(turn)
                     move     <- lens * exp(1i * facing)
                     position <- cumsum(move)
                     x2       <- Re(position)
                     y2       <- Im(position)
                     x1       <- c(0, head(x2, -1))
                     y1       <- c(0, head(y2, -1))
                   })

dat[c("id", "lens", "x1", "y1", "x2", "y2")]
#   id lens x1 y1 x2 y2
# 1  A    4  0  0  4  0
# 2  B    2  4  0  4 -2
# 3  C    5  4 -2 -1 -2
# 4  D    8 -1 -2 -1  6
# 5  E    6 -1  6  5  6
# 6  F    9  5  6  5 -3


实际上,应将turn变量与lens一起视为输入。现在所有转弯都是-pi/2弧度,但是您可以将每个转角设置为任意值。所有其他变量均为输出。



现在有一点乐趣:

trace.path <- function(lens, turn) {
  facing   <- pi/2 + cumsum(turn)
  move     <- lens * exp(1i * facing)
  position <- cumsum(move)
  x        <- c(0, Re(position))
  y        <- c(0, Im(position))

  plot.new()
  plot.window(range(x), range(y))
  lines(x, y)
}

trace.path(lens = seq(0, 1,  length.out = 200),
           turn = rep(pi/2 * (-1 + 1/200), 200))




(我在此处尝试复制图形:http://en.wikipedia.org/wiki/Turtle_graphics

我也让您尝试以下方法:

trace.path(lens = seq(1, 10, length.out = 1000),
           turn = rep(2 * pi / 10, 1000))

trace.path(lens = seq(0, 1,  length.out = 500),
           turn = seq(0, pi, length.out = 500))

trace.path(lens = seq(0, 1,  length.out = 600) * c(1, -1),
           turn = seq(0, 8*pi, length.out = 600) * seq(-1, 1, length.out = 200))


随时添加您的!

关于r - 右转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20361768/

相关文章:

使用 r 中的数据框替换列名

r - 如何使用从 group_by (dplyr) 中退休的值创建列

重命名环境中的数据集

android - TYPE_ROTATION_VECTOR, TYPE_ORIENTATION 给出不同的结果,也有偏差

python - 如何旋转网格中的点并保持正交性

R:解开范围

r - ggplot2无法绘制曲线

python - Python 中 Colorbar 只显示一种颜色

plot - 如何在 Julia 中绘制带有错误栏的函数

python - 如何测试一个矩阵是否是旋转矩阵?