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

19 篇文章 0 订阅

用于测试的三组数据点

	// polygon 1
    pointlist.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 2
    pointlist3.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 3
    pointlist5.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);
}
  • 3
    点赞
  • 8
    收藏
  • 打赏
    打赏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论 13

打赏作者

木风可可

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值