如何使用 R 从多边形的中心绘制辐条到它的边界

How to draw spokes from the center of a polygon to it's boundary using R

假设我们有一个有五个顶点的多边形。顶点的两个坐标是-

>x=c(1,4,6,3,-2)

>y=c(1,1,5,9,4) 

我们将多边形的中心定义为点(mean(x),mean(y))。

我正在努力从多边形的中心到多边形的边界绘制 辐条 以便辐条在中心形成相同的角度(即,两个相邻的辐条创建中心等角)。我还希望有序地拥有多边形边界上的所有点(下图中的红色圆圈)。

这是我想要的粗略样本图(凸): 注意:我处理的多边形不一定是凸的。

样本图(非凸)

输出我要:1)直线的坐标(即直线通过原点和多边形的边界线段)。
2) 对于每个等距角(图 2 中的 theta),我希望 a 绘制对应于每个 theta 的辐条(如图 2 所示)。请注意,角度介于 0 到 360 度之间。

3) 如果是我的第二个多边形(非凸面),其中同一条线穿过两个边界段(创建三个相交点),我想要三个坐标对应于相同的角度 (theta)。

谁能帮我用 R 做这件事?提前致谢。

我对此进行了修改以处理所示的凸形情况。

您将必须编写代码来计算辐条从中心到每个边缘线段的交点。没那么难,真的,但从来没有在 R 中见过它。然后你将不得不遍历你有兴趣绘制的角度,遍历线段,找到它相交的那些,对这些值进行排序,然后画线到你感兴趣的路口。 然后你会到最远的地方,或者一些组合(可能是最近和最远之间的虚线)。

在伪代码中:

  for each spoke you want to draw
      calculate the spoke-line from the center to some point far outside
      initialize edge intersection-point list to empty
      for each edge-segment
          calculate the intersection-point of spoke-line and edge-segment
               if the intersection-point exists 
                  add it to the intersection list
      now go through the intersections and find the furthest
      draw the spoke from the center to the furthest intersection point
      continue with the next spoke

这可能需要几个小时来研究和编写,除非你不断地编写这种图形代码。

给你。您需要 sp 和 rgeos 包:

spokey <- function(xy,n=20){
    xcent = mean(xy[,1])
    ycent = mean(xy[,2])
    cent = sp::SpatialPoints(cbind(xcent, ycent))
    pts = sp::SpatialPoints(xy)
    ## take the furthest distance from centre to vertex, times two!
    r = 2 * max(sp::spDistsN1(pts, cent))
    theta=seq(0,2*pi,length=n+1)[-(n+1)]
    ## construct a big wheel of spoke lines
    sl = sp::SpatialLines(
        lapply(1:length(theta),function(id){
            t = theta[id]
            sp::Lines(
                list(
                    sp::Line(
                        rbind(
                            c(xcent, ycent),
                            c(xcent + r * cos(t),ycent + r * sin(t))
                            )
                        )
                    ),ID=id)
        }))
    ## construct the polygon as a SpatialPolygons object:
    pol = sp::SpatialPolygons(list(sp::Polygons(list(sp::Polygon(rbind(xy,xy[1,]))),ID=1)))
    ## overlay spokes on polygon as "SpatialLines" so we do line-on-line
    ## intersect which gets us points
    spokes = rgeos::gIntersection(sl, as(pol,"SpatialLines"), byid=TRUE)
    spokes
}

它需要一个坐标矩阵,其中第一个点不是最后一个点:

xy1 = structure(c(4.49425847117117, 4.9161781929536, 7.95751618746858, 
7.92235621065338, 9.76825499345149, 9.9616348659351, 8.04541612950659, 
7.83445626861537, 6.42805719600729, 0.644241009906543, 2.40223985066665, 
1.24196061576498, 2.13854002455263, 7.935927470861, 9.41043173309254, 
9.33179150577352, 6.50074332228897, 7.34612576596839, 2.76533252463575, 
1.07456763727692, 3.88595576393172, 1.17286792142569, 2.745672467806, 
5.20317957152522, 5.81264133324759, 8.21116826647756), .Dim = c(13L, 
2L))

然后:

> plot(xy1,asp=1)
> polygon(xy1)
> spokes = spokey(xy1,20) # second arg is number of spokes
> points(spokes,pch=19,col="red")

得到你:

不信,从中心到点画线段:)

 segments(mean(xy1[,1]),mean(xy1[,2]), coordinates(spokes)[,1], coordinates(spokes)[,2])

函数 coordinates(spokes) 将为您提供辐条点的两列矩阵 - 目前它作为 SpatialPoints 对象返回。