首页 文章

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

提问于
浏览
1

我试图从R中的主干部分模拟环的形状,但每次我想接近真实的形状时它变得更加困难 . 我开始使用四个半径测量,我得到了一个很好的解决方案(see here) . 但是,现在我想在不同的角度绘制超过四个半径,并用模拟环的线连接这些点,就像我做的草图一样:
enter image description here

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

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

1 回答

  • 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, ]
    }
    

    DATA

    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
    

相关问题