用于测试的三组数据点

 // polygon 1pointlist.append(QVector3D( 395, 188, 0 ));pointlist.append(QVector3D( 353, 69 , 0 ));pointlist.append(QVector3D( 481, 15 , 0 ));pointlist.append(QVector3D( 576, 131, 0 ));pointlist.append(QVector3D( 504, 232, 0 ));pointlist2 = Expand2(pointlist, 20);// polygon 2pointlist3.append(QVector3D( 51.4701, 127.368 ,0 ));pointlist3.append(QVector3D( 134.662, 127.368 ,0 ));pointlist3.append(QVector3D( 148.152, 44.9652 ,0 ));pointlist3.append(QVector3D( 46.9732, 44.9652 ,0 ));pointlist3.append(QVector3D( 31.2343, 77.1771 ,0 ));pointlist4 = Expand2(pointlist3, 20);// polygon 3pointlist5.append(QVector3D( 217.853, 561.103, 0 ));pointlist5.append(QVector3D( 398.476, 561.103, 0 ));pointlist5.append(QVector3D( 313.786, 424.765, 0 ));pointlist5.append(QVector3D( 439.697, 326.631, 0 ));pointlist5.append(QVector3D( 175.883, 326.631, 0 ));pointlist5.append(QVector3D( 133.163, 489.938, 0 ));pointlist6 = Expand2(pointlist5, 20);

修改后最终效果


代码一

之前在网上看到很多种代码, 但都有bug, 要么就是只支持凸多边形, 如下


QList<QVector3D> Expand(QList<QVector3D> polygon, double expand)
{QList<QVector3D> new_polygon;int len = polygon.length();for (int i = 0; i < len; i++){QVector3D p = polygon[i];QVector3D p1 = polygon[i == 0 ? len - 1 : i - 1];QVector3D p2 = polygon[i == len - 1 ? 0 : i + 1];double v1x = p1.x() - p.x();double v1y = p1.y() - p.y();double n1 = norm(v1x, v1y);v1x /= n1;v1y /= n1;double v2x = p2.x() - p.x();double v2y = p2.y() - p.y();double n2 = norm(v2x, v2y);v2x /= n2;v2y /= n2;double l = -expand / sqrt((1 - (v1x * v2x + v1y * v2y)) / 2);double vx = v1x + v2x;double vy = v1y + v2y;double n = l / norm(vx, vy);vx *= n;vy *= n;new_polygon.append(QVector3D(vx + p.x(), vy + p.y(), 0));}return new_polygon;
}

代码二

也有修复了bug, 加入了凹多边形的检测的, 但是却会有内缩外扩混淆的问题, 代码如下

QList<QVector3D> Expand(QList<QVector3D> polygon, float expand)
{QList<QVector3D> new_polygon;int len = polygon.length();if(len<3) return polygon;for (int i = 0; i < len; i++){QVector3D p = polygon[i];QVector3D p1 = polygon[i == 0 ? len - 1 : i - 1];QVector3D p2 = polygon[i == len - 1 ? 0 : i + 1];float v1x = p1.x() - p.x();float v1y = p1.y() - p.y();float n1 = norm(v1x, v1y);float vv1x = v1x / n1;float vv1y = v1y / n1;float v2x = p2.x() - p.x();float v2y = p2.y() - p.y();float n2 = norm(v2x, v2y);float vv2x = v2x / n2;float vv2y = v2y / n2;float vectorLen = -expand / sqrt((1 - (vv1x * vv2x + vv1y * vv2y)) / 2.0f);float judge = v1x * v2y - v2x * v1y;if (judge > 0) vectorLen *= -1;float vx = vv1x + vv2x;float vy = vv1y + vv2y;vectorLen = vectorLen / norm(vx, vy);vx *= vectorLen;vy *= vectorLen;new_polygon.append(QVector3D(vx + p.x(), vy + p.y(), 0));}return new_polygon;
}

最终修改代码

修复了凹凸多边形, 以及内缩外扩混淆问题, 虽然实现了功能, 但方法却很蠢, 希望大神不吝赐教

QList<QVector3D> Expand(QList<QVector3D> polygon, float expand)
{QList<QVector3D> new_polygon;int len = polygon.length();if(len<3) return polygon;int flag = 0;for (int i = 0; i < len; i++){QVector3D p = polygon[i];QVector3D p1 = polygon[i == 0 ? len - 1 : i - 1];QVector3D p2 = polygon[i == len - 1 ? 0 : i + 1];float v1x = p1.x() - p.x();float v1y = p1.y() - p.y();float n1 = norm(v1x, v1y);float vv1x = v1x / n1;float vv1y = v1y / n1;float v2x = p2.x() - p.x();float v2y = p2.y() - p.y();float n2 = norm(v2x, v2y);float vv2x = v2x / n2;float vv2y = v2y / n2;float vectorLen = -expand / sqrt((1 - (vv1x * vv2x + vv1y * vv2y)) / 2.0f);float judge = v1x * v2y - v2x * v1y;if (judge < 0) vectorLen *= -1;if (judge < 0) flag++;float vx = vv1x + vv2x;float vy = vv1y + vv2y;vectorLen = vectorLen / norm(vx, vy);vx *= vectorLen;vy *= vectorLen;new_polygon.append(QVector3D(vx + p.x(), vy + p.y(), 0));}if(flag==len) {new_polygon.clear();for (int i = 0; i < len; i++){QVector3D p = polygon[i];QVector3D p1 = polygon[i == 0 ? len - 1 : i - 1];QVector3D p2 = polygon[i == len - 1 ? 0 : i + 1];float v1x = p1.x() - p.x();float v1y = p1.y() - p.y();float n1 = norm(v1x, v1y);float vv1x = v1x / n1;float vv1y = v1y / n1;float v2x = p2.x() - p.x();float v2y = p2.y() - p.y();float n2 = norm(v2x, v2y);float vv2x = v2x / n2;float vv2y = v2y / n2;float vectorLen = -expand / sqrt((1 - (vv1x * vv2x + vv1y * vv2y)) / 2.0f);float vx = vv1x + vv2x;float vy = vv1y + vv2y;vectorLen = vectorLen / norm(vx, vy);vx *= vectorLen;vy *= vectorLen;new_polygon.append(QVector3D(vx + p.x(), vy + p.y(), 0));}}return new_polygon;
}

中间用到的自定义函数

double norm(double x, double y)
{return sqrt(x * x + y * y);
}

实现凹凸多边形外扩与内缩, 无内缩外扩混乱问题相关推荐

  1. 借助花生壳把内网网站映射给外网。(内网穿透/路由器端口映射)、外网控制内网...

    其实这个东西几年前我就弄过,但是当时心智不成熟,没学会怎么玩耍,今天玩了一把也没啥的, 1.搭建网站 假设内网电脑是192.168.100.9 访问Http://192.168.100.9能打开网站, ...

  2. 企‮增业‬长‮两的‬种方式:内‮式生‬增长、外‮式延‬增长

    企‮增业‬长‮两的‬种方式:内‮式生‬增长.外‮式延‬增长 内‮式生‬增长三‮维大‬度:增长战略.增长机制.增长团队 外延式‮长增‬三‮维大‬度:模式.流量.资本 无‮不内‬实,不外不强! 企业‮增的 ...

  3. 解决外网与内网或内网之间的通信,NAT穿透

    在网络编码中会发现程序在局域网中是可以适用的,但是在外网与内网之间和内网与内网之间就不可行. 问题就在于NAT.首先介绍下NAT. NAT的作用NAT(Network Address Translat ...

  4. 内网服务器如何提供外网远程连接访问

    在局域网本地网络环境时,我们一般用远程桌面连接来访问内部windows服务器,或在个人电脑上用SSH客户端来远程访问内网的Linux主机.远程桌面连接和SSH都是系统自带的,且可以通过简单配置即可以开 ...

  5. 群晖nas免费内网穿透,实现外网异地远程访问

    一般群晖nas都部署在内网网络中,但现在基本不会被分配公网IP,要想在外网环境下远程访问家里/公司的群晖nas,普遍是做内网穿透来实现,通过第三方公网IP服务器进行转发. 这里推荐一款免费的内网穿透软 ...

  6. 内网网站发布到外网-五种方法

    转自:http://www.nat123.com/Pages_8_549.jsp 汇总固定公网IP.动态公网IP.内网环境无公网IP,这三种网络环境下的发布内网网站到外网的实现教程方案. 一,固定公网 ...

  7. 内网ip映射到外网(路由器是tp-link)

    参考:https://service.tp-link.com.cn/detail_article_3403.html 1.ipconfig查看服务器所在的网关,浏览器访问网关ip(eg:192.168 ...

  8. Apache 2.4.7在CentOS6.4中安装配置反向代理解决单外网IP对应多个内网主机的方法实践

    欢迎转载,转载时请保留全文及出处. Apache 2.4.7在CentOS6.4中安装配置反向代理解决单外网IP对应多个内网主机的方法实践 Apache安装 下载源程序(http://httpd.ap ...

  9. css引入样式-行内样式、内嵌样式和外链样式

    css初识及引入样式 概念:css通常称为css样式表或层叠样式表 作用: - 主要用于设置HTML页面中的文本内容(字体.大小.对齐方式等).图片的外形(宽高.边框样式.边距等)以及版面的布局和外观 ...

最新文章

  1. linux修改ssh端口
  2. java触发full gc的几种情况概述
  3. 微信小程序align_微信小程序四色花瓣
  4. 弱引用使用场景桌面_面试|再次讲解Threadlocal使用及其内存溢出
  5. 【过程记录 】windows和ubuntu两台电脑局域网进行socket通信收发数据和传输文件
  6. SuperSocket源码解析之开篇 (转)
  7. java嵌入式db_Java DB嵌入式模式
  8. LSGO软件技术团队与信息1402班开展真人CS活动
  9. mysql 数据库之表操作
  10. ARP挂马***--嗅探欺骗的最恐怖方式
  11. 数据--第21课-递归课后练习
  12. SPI 机制-插件化扩展功能
  13. python与审计底稿关系_干货!审计底稿,六大禁忌
  14. python utf 8 mac_Mac python 开发环境一些设置
  15. 使用kaminari实现分页
  16. Supermap Iserver 安装指南
  17. 【​观察】六脉神剑第四式-全面保障之移形换影
  18. SQLyog 试用期过的解决办法
  19. Unity VR开发教程 OpenXR+XR Interaction Toolkit (三) 转向和移动
  20. 使用jupyter notebook运行卷积神经网络出现的版本问题

热门文章

  1. draggable布局 vue_vue-draggable 学习和使用
  2. 为什么要使用抽屉式光纤配线箱?
  3. Java中利用Calendar类得到每月对应的天数
  4. iOS小团队创业经验分享
  5. 如何巧妙使用Camtasia制作PPT讲解视频?
  6. 【C语言基础】利用复合梯形求积公式计算定积分
  7. MySQL数据库基础语法总结
  8. MWC21上海全球首秀,全馆通行证先到先得
  9. C++ STL轻松导学
  10. 每日学术速递2.11