我的情节有两条来自原点的光线。我想以逆时针方向遮蔽从光线 1 到光线 2 的区域。我在想我可能不得不使用 geom_polygon。我希望能够为 任何两条任意光线 执行此操作,但我似乎无法弄清楚。

*我想坚持使用笛卡尔坐标。

这是我的意思的一个例子:

d <- data.frame()

base <- ggplot(d) + xlim(-5, 5) + ylim(-5, 5) + geom_blank()

ray1 <- geom_segment(aes(x=0,y=0,xend=5,yend=4))
ray2 <- geom_segment(aes(x=0,y=0,xend=0,yend=5))

shading <- geom_polygon(data=data.frame(x=c(0,5,5,0), y=c(0,4,5,5)),
  aes(x,y), fill="blue", alpha=0.2)

base + ray1 + ray2 + shading

在这个例子中,我能够通过检查获得多边形的顶点,但我将生成几对随机光线,我不想每次都手动完成这个过程。

有什么建议吗?

最佳答案

我认为这会更简单;但我已经找到了这个丑陋的解决方案。这是一个辅助函数,用于计算沿 base 中定义的限制的所有交点

findslice<-function(seg1, seg2, base=NULL, lim=getlims(base)) {
    getlims<-function(x) {
        list(y=x$scales$get_scales("y")$limits,
        x=x$scales$get_scales("x")$limits)
    }
    gethit<-function(seg, lim) {
        with(seg$mapping, {
            x<-eval(x); y<-eval(y);
            xend<-eval(xend); yend<-eval(yend);
            dx<-(xend-x); dy<-(yend-y)
            bx<-ifelse(dx>0,max(lim$x), min(lim$x))
            by<-ifelse(dy>0,max(lim$y), min(lim$y))
            sx<-ifelse(dx>0,1, 3)
            sy<-ifelse(dy>0,2, 4)
            if(identical(dx,0)) {
                return(list(x=x,y=by, side=sy))
            }
            if (identical(dy,0)) {
                return(list(x=bx,y=y, side=sx))
            }
            nx<-bx
            ny<-(y+dy)*(nx-x)/dx
            side<-sx
            if (abs(ny)>abs(by)) {
                ny<-by
                nx<-(x+dx)*(ny-y)/dy
                side<-sy
            }
            return(list(x=nx, y=ny, side=side))
        })
    }
    p1<-gethit(seg1, lim)
    p2<-gethit(seg2, lim)
    side<-p1$side
    corners<-data.frame(x=lim$x[c(2,1,1,2)], y=lim$y[c(2,2,1,1)])
    r<-data.frame(x=c(seg1$mapping$x, p1$x), y=c(seg1$mapping$y, p1$y))
    while(side != p2$side) {
        r<-rbind(r, corners[side, ])
        side <- (side %% 4) +1
    }
    r<-rbind(r, data.frame(x=p2$x, y=p2$y))
    r
}

这将创建多边形绘图所需的 data.frame。例如
base <- ggplot(d) + xlim(-5, 5) + ylim(-5, 5) + geom_blank()

ray1 <- geom_segment(aes(x=0,y=0,xend=5,yend=4))
ray2 <- geom_segment(aes(x=0,y=0,xend=0,yend=5))

shading <- geom_polygon(data=findslice(ray1, ray2, base),
  aes(x,y), fill="blue", alpha=0.2)

base + ray1 + ray2 + shading + ggtitle("Take 1")

这个想法是它会超出限制,然后开始环绕边缘。所以另一个例子是
ray1 <- geom_segment(aes(x=0,y=0,xend=5,yend=4))
ray2 <- geom_segment(aes(x=0,y=0,xend=0,yend=5))

shading <- geom_polygon(data=findslice(ray1, ray2, base),
  aes(x,y), fill="blue", alpha=0.2)

base + ray1 + ray2 + shading + ggtitle("Take 2")

关于r - ggplot2 : filling the area between two rays,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24591878/

10-12 19:21