效果
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/2af4ec103a844f5f9de3d789c022363b.gif)
代码
bool isClockwise(const QPolygonF& poly)
{
qreal sum = 0;
int len = poly.size();
for (int i = 0; i < len; ++i)
{
QPointF p1 = poly[i];
QPointF p2 = poly[(i + 1) % len];
sum += (p2.x() - p1.x()) * (p2.y() + p1.y());
}
return sum > 0;
}
double norm(double x, double y)
{
return sqrt(x * x + y * y);
}
QPolygonF shrinkPolygon(const QPolygonF& poly, double expand)
{
if (isClockwise(poly)) expand = -expand;
QList<QVector3D> polygon;
foreach(auto p, poly) {
QVector3D v3d(p.x(), p.y(), 0);
if (!polygon.contains(v3d))
polygon << v3d;
}
QList<QVector3D> new_polygon;
int len = polygon.length();
if(len<3) return poly;
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));
}
QPolygonF new_poly;
foreach(auto p, new_polygon) new_poly << QPointF(p.x(), p.y());
if (new_poly.first() != new_poly.back()) new_poly.append(new_poly.first());
return new_poly;
}