剪辑/剪切多边形外部的所有内容或用白色填充外部

Posted

技术标签:

【中文标题】剪辑/剪切多边形外部的所有内容或用白色填充外部【英文标题】:Clip/Cut everything outside of Polygon or fill the outside with white 【发布时间】:2016-12-21 11:30:11 【问题描述】:

我有一个正方形的彩色噪声,上面有一个三角形。 现在,我希望多边形在圣诞节像“饼干切割机”一样消除这种噪音。产生一个被多边形路径包围的三角形噪声。

如何剪切与多边形边框重叠的所有像素,然后将其保存为 pdf?

我想出了两个想法:

方法 1 使用一个函数来测试像素(彩色噪声)是否落入形状中。让我们开始吧!问题:边框像素的边缘超出了线条。在这个例子中,它非常小。您可能会争论只是让多边形线更大一点。 方法二 反转多边形形状(等于:填充多边形外部),然后用白色填充。问题: 在绘图预览窗口中,结果看起来像我想要的。当我将其另存为 PDF 时,我得到的结果是一切都是白色的,带有黑色的多边形形状。

可重现的例子

library(magrittr)
library(ggplot2)
library(SDMTools)
polyGony <- c(0,0,100,50,50,100) %>% matrix(ncol=2,byrow = T) %>% as.data.frame()
deltaN <- 200  #grid width
sp1<-seq(1,100,length=deltaN)
sp2<-seq(1,100,length=deltaN)
sp<-expand.grid(x=sp1,y=sp2)

set.seed(1337)
sp$z <- sample(1:30,nrow(sp),replace = T)

# Method 1
outin = SDMTools::pnt.in.poly(sp[,1:2],polyGony)
outin$z <- sp$z
pointsInsideTri <- outin[outin$pip==1,-3]

p <- ggplot(pointsInsideTri, aes(x, y)) +
  geom_raster(aes(fill = z)) +
  scale_fill_gradientn(colours=c("#FFCd94", "#FF69B4", "#FF0000","#4C0000","#000000"))

p + geom_polygon(data = polyGony, aes(V1,V2),color="black", fill=NA) + theme(aspect.ratio = 1)

# Method 2
outSQ <-c(0,0,100,0,100,100,0,100)
invPolyGony <- c(outSQ,0,0,100,50,50,100) %>% matrix(ncol=2,byrow = T) %>% as.data.frame()


    p <- ggplot(sp, aes(x, y)) +
      geom_raster(aes(fill = z)) +
      scale_fill_gradientn(colours=c("#FFCd94", "#FF69B4", "#FF0000","#4C0000","#000000"))

    p + geom_polygon(data = invPolyGony, aes(V1,V2) ,colour="black", fill="white") + theme(aspect.ratio = 1)

【问题讨论】:

pdf 是您唯一的问题吗?对我来说,不清楚您在寻找什么。 我想用多边形路径环绕基于像素的图像。任何像素都不应“重叠”出多边形边界。然后我想把它保存在一个pdf文件中。 据我了解,您的故事具有误导性(或错误)。你知道你想做什么以及你想使用哪些方法。您的问题只是如何将结果保存为 pdf。 亲爱的克里斯托夫,我最后再次试图说服我的问题!是的,我知道我想要什么。但是我不知道该怎么做,方法1和2是我最好的尝试。它不是强制使用它们。 【参考方案1】:

我现在知道问题所在了。为了填充多边形之外的所有东西,路径(中间的洞)需要顺时针“运行”,外边界需要逆时针运行。

我做了一个简单的例子。我们有一个恒星的多边形。我希望星星之外的所有东西都是红色的。

star <- c(25.000,1.000,31.000,18.000,49.000,18.000,35.000,29.000,40.000,46.000,
          25.000,36.000,10.000,46.000,15.000,29.000,1.000,18.000,19.000,18.000) %>% matrix(ncol=2, byrow=T)
star <- rbind(star,star[1,])
rim  <- c(0,0, 50,0, 50,50,0,50,0,0) %>% matrix(ncol=2, byrow=T)

datapolyM <- rbind(rim,star) %>% as.data.frame()
names(datapolyM) <- c("x","y")

ggplot(datapolyM, aes(x=x, y=y)) + 
  geom_polygon(fill="red", colour="black")

导出为pdf!你会看到整张图片都被红色填充了!

现在让星星的路径顺时针运行:请尊重第二行中的应用和反转命令:

star <- c(25.000,1.000,31.000,18.000,49.000,18.000,35.000,29.000,40.000,46.000,
          25.000,36.000,10.000,46.000,15.000,29.000,1.000,18.000,19.000,18.000) %>% matrix(ncol=2, byrow=T) %>% apply(2, rev)
star <- rbind(star,star[1,])
rim  <- c(0,0, 50,0, 50,50,0,50,0,0) %>% matrix(ncol=2, byrow=T)

datapolyM <- rbind(rim,star) %>% as.data.frame()
names(datapolyM) <- c("x","y")
datapolyM$id <- "a"

ggplot(datapolyM, aes(x=x, y=y)) + 
  geom_polygon(fill="red")

现在再次导出为 pdf。这次你会看到它成功了!您已填充给定多边形形状之外的所有内容!

【讨论】:

很好的解决方案!当您想要突出显示具有冲突管辖区的图块(例如人口普查区和国会选区)时,它自然适用于制图。 很好,我稍微调整了一下以供我使用,将光栅限制为凸包,但效果非常好! '顺时针'运行是解决这个问题的关键。

以上是关于剪辑/剪切多边形外部的所有内容或用白色填充外部的主要内容,如果未能解决你的问题,请参考以下文章

扫描线填充算法

检查多边形内部或外部的一个点(纬度,经度)

使用 html5 画布将图像剪辑成多边形的可重用函数

使用 JTS,如何从外部点找到多边形边界上最近的点?

Backand 中的多边形对象支持与外部 MySQL

如何界定 ​​Voronoi 多边形的外部区域并与地图数据相交