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

如何使用.slib文件中的圆弧坐标在Qt中正确绘制圆弧

.slib门电路符号绘制:圆弧参数解析与Qt实现方案

问题背景

开发需求为读取.slib格式文件,生成AND、NOT、XNOR、MUX等标准门电路符号。解析图元时,line(直线)类型参数逻辑清晰可直接使用,但arc(圆弧)类型的参数定义无明确说明,无法正确映射到绘制接口,导致图形渲染出错。

现有文件格式样例

直线(line)格式

直线参数共4个,依次为起点X坐标、起点Y坐标、终点X坐标、终点Y坐标,所有参数值乘以文件头定义的全局缩放系数SCALE即为实际坐标:

line (66 * SCALE, 80 * SCALE, 0 * SCALE, 80 * SCALE); 
line (94 * SCALE, 70 * SCALE, 62 * SCALE, 70 * SCALE);
...

圆弧(arc)格式

圆弧参数共6个,现有样例如下:

arc (145 * SCALE, 100 * SCALE, 94 * SCALE, 70 * SCALE,94.9268 * SCALE,126.774 * SCALE);     
arc (94 * SCALE, 130 * SCALE, 145 * SCALE, 100 * SCALE,94.9268 * SCALE, 73.2256 * SCALE);    
arc (61 * SCALE, 130 * SCALE, 61 * SCALE, 70 * SCALE,8.75 * SCALE, 100 * SCALE);

根据文件标注的点位对应关系:

  • 第一行arc:从点O(145,100)绘制到点F(94,70)
  • 第二行arc:从点L(94,130)绘制到点O(145,100)
  • 第三行arc:从点K(62,30)绘制到点E(62,70)

已尝试方案与问题

初期仅使用每行arc的前4个参数(即起点、终点坐标),手动估算圆弧外接矩形和角度参数编写Qt绘制代码:

QPainterPath path;  // arc from L --->  F 
path.moveTo(94,70);
QRect bound1 (44,70,102,60);
path.arcTo(bound1,90,-180);
        
QPainterPath path1;  // arc from K ---> E
path1.moveTo(62,70);
QRect bound2 (42,70,40,60);
path1.arcTo(bound2,90,-180);

渲染结果存在明显偏差:或门输入导线与相邻圆弧无法正确衔接。核心问题是未明确arc最后2个参数的含义,无法生成精确的圆弧路径。

圆弧参数定义与正确绘制方法

参数含义确认

.slib中arc的6个参数按顺序定义为:
arc (起点X, 起点Y, 终点X, 终点Y, 圆弧圆心X, 圆弧圆心Y)
可通过距离公式校验:所有样例中,最后两个参数对应的点到起点、终点的距离完全相等,符合圆弧圆心的几何定义。

Qt端绘制步骤

Qt的QPainterPath::arcTo接口需要三个核心参数:圆弧外接矩形、起始角度、扫描角度,所有参数均可通过slib给出的6个值精确计算,无需手动估算:

  1. 坐标缩放:将读取到的6个原始值统一乘以SCALE,得到实际绘制坐标:起点(x1,y1)、终点(x2,y2)、圆心(cx,cy)
  2. 半径计算:圆心到起点的直线距离即为圆弧半径r = sqrt(pow(x1 - cx, 2) + pow(y1 - cy, 2)),可用圆心到终点的距离做校验,二者误差应在浮点精度范围内
  3. 外接矩形计算:圆弧为外接矩形的内切圆的一部分,矩形左上角坐标为(cx - r, cy - r),宽、高均为2*r
  4. 角度计算:Qt角度规则为0度指向X轴正方向(3点钟方向),逆时针为角度正方向。起始角度为圆心到起点连线与0度方向的夹角,可通过qRadiansToDegrees(atan2(y1 - cy, x1 - cx))计算;终点角度为圆心到终点连线的夹角,二者差值即为扫描角度,负值代表顺时针旋转绘制。

通用绘制代码

#include <QPainterPath>
#include <QtMath>

// 传入slib读取的6个未缩放圆弧参数、全局缩放系数,将圆弧路径追加到指定QPainterPath
void addSlibArcToPath(QPainterPath* path, 
                      qreal rawX1, qreal rawY1, 
                      qreal rawX2, qreal rawY2, 
                      qreal rawCx, qreal rawCy, 
                      qreal scale)
{
    // 坐标缩放
    qreal x1 = rawX1 * scale;
    qreal y1 = rawY1 * scale;
    qreal x2 = rawX2 * scale;
    qreal y2 = rawY2 * scale;
    qreal cx = rawCx * scale;
    qreal cy = rawCy * scale;

    // 计算半径
    qreal radius = qSqrt(qPow(x1 - cx, 2) + qPow(y1 - cy, 2));
    // 生成外接矩形
    QRectF arcBounds(cx - radius, cy - radius, 2 * radius, 2 * radius);
    // 计算起始、扫描角度
    qreal startAngle = qRadiansToDegrees(qAtan2(y1 - cy, x1 - cx));
    qreal endAngle = qRadiansToDegrees(qAtan2(y2 - cy, x2 - cx));
    qreal spanAngle = endAngle - startAngle;

    // 绘制圆弧
    path->moveTo(x1, y1);
    path->arcTo(arcBounds, startAngle, spanAngle);
}

使用该方法绘制时,圆弧会精确经过给定的起点、终点,弧度完全匹配文件定义,可与相邻直线、圆弧无缝衔接,不会出现导线错位的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:48:28