// 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);
}