You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用QSGGeometry绘制圆角矩形填充异常的问题求助

QSGGeometry绘制圆角矩形填充异常的问题排查与修复

问题描述

使用QSGGeometry/QSGFlatColorMaterial绘制直角矩形时显示正常,但绘制圆角矩形时无法正确填充内部区域。尝试设置DrawTriangleFan绘制模式并在多边形开头添加QPointF(150, 150),结果仍不符合预期。

原因分析

  1. 默认绘制模式不匹配:QSGGeometry默认使用DrawTriangleStrip模式,该模式仅能正确填充简单凸多边形(如直角矩形),但无法处理带圆弧轮廓的圆角矩形——这类复杂轮廓的顶点序列无法通过三角条带模式生成正确的填充面。
  2. DrawTriangleFan使用错误:之前添加的中心顶点位置(150,150)并非圆角矩形的实际中心,且顶点序列的排列逻辑未匹配扇形绘制的要求(需以中心为起点,外围顶点按统一顺/逆时针顺序排列,无需重复起点)。

修复方案

推荐两种可靠的修复方式:

方式一:正确使用DrawTriangleFan模式

  • 以圆角矩形的中心作为第一个顶点
  • 按顺时针(或逆时针)顺序排列所有外围顶点(无需重复起点)
  • 将几何的绘制模式设置为QSGGeometry::DrawTriangleFan

示例代码:

QPolygonF polygon;
// 添加中心顶点(圆角矩形中心:(115, 115),对应230x230的矩形)
polygon << QPointF(115, 115);
// 按顺时针顺序添加圆角矩形外围顶点
polygon << QPointF(0, 10)
        << QPointF(0.78585, 6.10755)
        << QPointF(2.92893, 2.92893)
        << QPointF(6.10755, 0.78585)
        << QPointF(10, 0)
        << QPointF(220, 0)
        << QPointF(223.892, 0.78585)
        << QPointF(227.071, 2.92893)
        << QPointF(229.214, 6.10755)
        << QPointF(230, 10)
        << QPointF(230, 220)
        << QPointF(229.214, 223.892)
        << QPointF(227.071, 227.071)
        << QPointF(223.892, 229.214)
        << QPointF(220, 230)
        << QPointF(10, 230)
        << QPointF(6.10755, 229.214)
        << QPointF(2.92893, 227.071)
        << QPointF(0.78585, 223.892)
        << QPointF(0, 220);

QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), polygon.count());
// 设置绘制模式为TriangleFan
geometry->setDrawingMode(QSGGeometry::DrawTriangleFan);

QSGFlatColorMaterial *material = new QSGFlatColorMaterial();
material->setColor(QColor("red"));

QSGGeometry::Point2D *vertices = geometry->vertexDataAsPoint2D();
for (int i = 0; i < polygon.count(); i++) {
    QPointF point = polygon.at(i);
    vertices[i].set(point.x(), point.y());
}

方式二:使用QPainterPath生成三角化几何数据(更通用)

对于更复杂的图形,直接使用QPainterPath创建圆角矩形,再将路径转换为三角化的顶点数据,确保填充正确:

QPainterPath path;
// 创建圆角矩形:x=0, y=0, width=230, height=230, radius=10
path.addRoundedRect(QRectF(0, 0, 230, 230), 10, 10);

// 将路径转换为三角化的顶点序列
QList<QSGGeometry::Point2D> vertices;
QVector<QPolygonF> polygons = path.toSubpathPolygons();
for (const QPolygonF &poly : polygons) {
    if (poly.size() > 2) {
        // 添加子路径的中心顶点
        QPointF center = poly.boundingRect().center();
        vertices.append(QSGGeometry::Point2D(center.x(), center.y()));
        // 添加子路径的外围顶点
        for (const QPointF &p : poly) {
            vertices.append(QSGGeometry::Point2D(p.x(), p.y()));
        }
    }
}

QSGGeometry *geometry = new QSGGeometry(QSGGeometry::defaultAttributes_Point2D(), vertices.size());
geometry->setDrawingMode(QSGGeometry::DrawTriangleFan);
memcpy(geometry->vertexData(), vertices.data(), vertices.size() * sizeof(QSGGeometry::Point2D));

QSGFlatColorMaterial *material = new QSGFlatColorMaterial();
material->setColor(QColor("red"));

关键注意点

  • 所有填充类的几何绘制,必须确保顶点序列能被当前绘制模式正确解析:DrawTriangleStrip仅适用于凸多边形,DrawTriangleFan需要中心顶点+有序外围顶点,复杂图形建议使用三角剖分。
  • 顶点顺序必须保持统一的顺时针或逆时针方向,避免出现交叉顶点导致填充错误。

内容的提问来源于stack exchange,提问作者posix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 17:57:49