如何绘制以不同角度对齐的点并通过线连接这些点?

时间:2017-10-24 13:45:39

标签: r plot polygon area

我试图从R中的树干部分模拟环的形状,但每次我想接近真实的形状时它会变得更加困难。我开始用四个半径测量开始,我得到了一个很好的解决方案(https://plnkr.co/edit/SDkFm5VChO7W19VuOXmK?p=preview)。 但是,现在我想在不同的角度绘制四个以上的半径,并用模拟环的线连接这些点,就像我做的草图一样: see here

我的第一种方法是旋转数据矩阵,但我无法使所有半径都在同一位置开始(0,0)。我也尝试对轴进行评分但没有成功。

这就是为什么我想要一些方向去做,最后计算每个戒指的面积 欢迎任何帮助

1 个答案:

答案 0 :(得分:2)

我正在使用here中的spline.poly功能。

<强> spline.poly

spline.poly <- function(xy, vertices, k=3, ...) {
    # Assert: xy is an n by 2 matrix with n >= k.

    # Wrap k vertices around each end.
    n <- dim(xy)[1]
    if (k >= 1) {
        data <- rbind(xy[(n-k+1):n,], xy, xy[1:k, ])
    } else {
        data <- xy
    }

    # Spline the x and y coordinates.
    data.spline <- spline(1:(n+2*k), data[,1], n=vertices, ...)
    x <- data.spline$x
    x1 <- data.spline$y
    x2 <- spline(1:(n+2*k), data[,2], n=vertices, ...)$y

    # Retain only the middle part.
    cbind(x1, x2)[k < x & x <= n+k, ]
}

数据

df = data.frame(A = c(1, 4, 5, 8, 10),
                B = c(1, 3, 7, 9, 10),
                C = c(2, 6, 8, 9, 10),
                D = c(1, 3, 4, 7, 9),
                E = c(1, 2, 3, 4, 5))

<强> DRAW

#Calculate angles based on number of columns
angles = 0:(NCOL(df) - 1) * 2*pi/NCOL(df)

#Calculate x and y corresponding to each radial distance
toplot = lapply(1:NCOL(df), function(i){
    data.frame(x = df[,i]*cos(angles[i]),
               y = df[,i]*sin(angles[i]))
})

#Split toplot and merge back together the same rows
toplot2 = lapply(toplot, function(x) data.frame(x, ID = sequence(NROW(x))))
toplot2 = do.call(rbind, toplot2)
toplot2 = split(toplot2, toplot2$ID)

#Create empty plot    
graphics.off()
plot(do.call(rbind, toplot), type = "n", axes = FALSE, ann = FALSE, asp = 1)

#Allow drawing outside the plot region just in case
par(xpd = TRUE)

#Draw polygons
lapply(toplot2, function(a){
    polygon(spline.poly(xy = cbind(a$x, a$y), vertices = 100, k = 3))
})

#Draw points    
lapply(toplot, function(a){
    points(a)
})

#Draw radial lines    
lapply(toplot, function(a){
   lines(a)
})

enter image description here

<强> AREA

area_data = lapply(toplot2, function(a){
   spline.poly(xy = cbind(a$x, a$y), vertices = 100, k = 3)
})
library(geometry)
lapply(area_data, function(P) polyarea(P[,1], P[,2]))
#$`1`
#[1] 4.35568

#$`2`
#[1] 38.46985

#$`3`
#[1] 96.41331

#$`4`
#[1] 174.1584

#$`5`
#[1] 240.5837