连接墙壁端点

如何解决连接墙壁端点

我有以下代表墙的点的列表:

walls = [[  76.7403,1283.2495,894.5198,1310.0122],[ 864.3867,415.2406,891.3730,1287.3810],[  80.0975,402.9981,899.7578,428.0596],[  75.9861,404.3390,101.6148,1292.0922],[ 469.9275,1118.6304,481.1644,1300.6523],[ 500.6000,897.3496,876.6120,908.2079],[ 102.0548,753.6523,402.9403,764.0107],[ 247.2823,968.0134,320.4769,977.5980],[ 503.2201,898.0987,515.2742,1136.6272],[ 400.9270,689.1513,411.8462,907.2622],[ 353.0995,1123.1868,362.8233,1293.9554],[ 248.6094,967.5870,261.0458,1124.8018],[ 246.0828,896.9332,411.2629,906.4570],[ 880.6799,60.5249,892.5886,411.2219],[ 249.5214,1116.5377,259.7009,1290.2698],[ 309.1409,899.7199,320.3546,978.5977],[  85.6537,1118.2689,259.5562,1128.9491],[ 249.0276,763.1385,261.5212,905.9616],[  86.2850,1117.8192,501.5602,1128.5548],[ 240.1799,1117.4913,385.9280,1128.2761],[ 288.5830,1117.4141,515.1036,1128.3738],[ 512.2842,1015.8013,592.7465,1022.5025],[ 249.2041,748.7802,260.6894,1140.3009],[ 401.1811,687.2712,411.9943,779.8344],[ 380.8932,1040.3300,386.9687,1126.2324]]  

我正在使用以下方法从这些墙形成一组多边形:

polys = []
for w in walls:
  x0,y0,x1,y1 = w
  poly = [
            (x0,y0),(x1,y1),(x0,y1)
        ]
  poly = list(itertools.chain.from_iterable(poly))
  polys.append(poly)

这些多边形最终看起来如下:

enter image description here

我想做的是连接墙壁端点,以使它们不会重叠,如图所示。这样做的最佳算法是什么?

以下是生成图像的代码:

<svg width="1200" height="1300">
<polygon points='76.7403,1310.0122,76.7403,1310.0122'/>
<polygon points='864.3867,891.373,1287.381,864.3867,1287.381'/>
<polygon points='80.0975,428.0596,80.0975,428.0596'/>
<polygon points='75.9861,404.339,1292.0922,75.9861,1292.0922'/>
<polygon points='469.9275,1300.6523,469.9275,1300.6523'/>
<polygon points='500.6,876.612,908.2079,500.6,908.2079'/>
<polygon points='102.0548,764.0107,102.0548,764.0107'/>
<polygon points='247.2823,977.598,247.2823,977.598'/>
<polygon points='503.2201,1136.6272,503.2201,1136.6272'/>
<polygon points='400.927,907.2622,400.927,907.2622'/>
<polygon points='353.0995,1293.9554,353.0995,1293.9554'/>
<polygon points='248.6094,967.587,1124.8018,248.6094,1124.8018'/>
<polygon points='246.0828,906.457,246.0828,906.457'/>
<polygon points='880.6799,411.2219,880.6799,411.2219'/>
<polygon points='249.5214,1290.2698,249.5214,1290.2698'/>
<polygon points='309.1409,978.5977,309.1409,978.5977'/>
<polygon points='85.6537,1128.9491,85.6537,1128.9491'/>
<polygon points='249.0276,905.9616,249.0276,905.9616'/>
<polygon points='86.285,1128.5548,86.285,1128.5548'/>
<polygon points='240.1799,385.928,1128.2761,240.1799,1128.2761'/>
<polygon points='288.583,1128.3738,288.583,1128.3738'/>
<polygon points='512.2842,1022.5025,512.2842,1022.5025'/>
<polygon points='249.2041,1140.3009,249.2041,1140.3009'/>
<polygon points='401.1811,779.8344,401.1811,779.8344'/>
<polygon points='380.8932,1040.33,1126.2324,380.8932,1126.2324'/>
</svg>

解决方法

目前还不清楚您的最终目标是什么。 您要剪切哪几行?所有松散的末端还是只是有些太长的末端?那线的不同厚度呢?

我想到的最简单的方法是将walls转换为具有特定宽度的线,而不是离散化这些线的端点,这样,生成的图像看起来会更清晰一些:

import matplotlib.pyplot as plt
import numpy as np


def walls2lines(walls):
    lines = []
    widths = []
    for w in walls:
        x0,y0,x1,y1 = w
        if (x1-x0) > (y1 - y0):
            widths.append(y1-y0)
            lines.append(((x0,y0 + widths[-1] / 2),(x1,y0 + widths[-1] / 2)))
        else:
            widths.append(x1-x0)
            lines.append(((x0 + widths[-1] / 2,y0),(x0 + widths[-1] / 2,y1)))

    return np.array(lines),np.array(widths)


def discretize_np(x,step):
    difference = x % step  # distance to the next discrete value
    difference[difference > step / 2] -= step  # round correctly
    return x - difference


lines,widths = walls2lines(walls=walls)
lines = discretize_np(lines,step=50)
widths *= 10 / widths.max()

fig = plt.figure()
ax = fig.subplots()

for l,w in zip(lines,widths):
    ax.plot(*l.T,lw=w,alpha=0.5)

lines

另一种可能性是真正查看不同矩形的重叠部分并尝试移动尊重的边界。但是,您遇到了许多不同的情况,因此很难找到一个好的通用解决方案,这实际上取决于您要寻找的内容。

我在eps上添加了walls2overlap,以也包括不太相交的矩形。我评论了一条线,以不同的方式处理自由端。 很多微调和反复试验...

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
from matplotlib.collections import PatchCollection


def walls2overlap(walls,eps=0):

    idx_overlap = np.ones((len(walls),len(walls)),dtype=bool)
    for i,w_i in enumerate(walls):
        for j,w_j in enumerate(walls):
            (x0_i,x1_i),(y0_i,y1_i) = w_i
            (x0_j,x1_j),(y0_j,y1_j) = w_j
            if (x0_i > x1_j+eps or x1_i < x0_j-eps or
                y0_i > y1_j+eps or y1_i < y0_j-eps):
                idx_overlap[i,j] = False

    return idx_overlap


def get_orientations(walls):
    """
    0: horizontal,1: vertical
    """
    (x0,x1),(y0,y1) = walls.transpose(1,2,0)
    return ((x1 -x0) < (y1 - y0)).astype(int)


def cut_walls(walls,idx_overlap):
    """Move the walls to the most extreme boundary
     of all intersecting walls of different orientation."""
    for i,w_i in enumerate(walls):
        o_i = orientations[i]
        idx_temp = np.logical_and(idx_overlap[i],orientations != o_i)
        if idx_temp.sum() <= 0:  # Set to 1,to keep free ended walls
            continue
        walls[i,o_i,0] = np.min(walls[idx_temp,0])
        walls[i,1] = np.max(walls[idx_temp,1])

    return walls


walls = np.reshape(walls,(-1,2),order='F')
idx_overlap = walls2overlap(walls=walls,eps=10)
orientations = get_orientations(walls)
walls = cut_walls(walls=walls,idx_overlap=idx_overlap)

fig,ax = new_fig(aspect=1)
rects = [Rectangle(xy=w[:,0],width=w[0,1] - w[0,height=w[1,1] - w[1,0])
         for w in walls]
ax.add_collection(PatchCollection(rects,color='k',alpha=0.5))

rectangles

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-