• Qt绘制椭圆曲线的角度问题(离心角和旋转角)


    最近有网友遇到一个问题,使用 QPainter::drawPie 或者 QPainter::drawArc 绘制同中心的圆和椭圆,指定同一起始点和角度,两条弧线的起点与圆心的连线不在同一直线上:
    在这里插入图片描述
    测试代码:

    QPainter painter(this);
       painter.setRenderHint(QPainter::Antialiasing);
       painter.translate(100, 100);
    
       QRectF ellipseRect(0, 0, 300, 200);
       QRectF circle(0, 0, 200, 200);
       circle.moveCenter(ellipseRect.center());
    // 绘制圆,红色
       painter.setPen(QPen(QColor(232, 63, 63, 128), 3.0));
       painter.drawPie(circle, 10 * 16, 70 * 16);
    // 绘制椭圆,绿色
       painter.setPen(QPen(QColor(63, 232, 63, 128), 3.0));
       painter.drawPie(ellipseRect, 10 * 16, 70 * 16);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    1. 原理

    Qt绘制椭圆曲线,使用的是椭圆离心角,参数方程是:

    x = a * cosθ
    y = b * sinθ

    即:在椭圆的外切圆和内切圆上,选择θ角度的两个点A,B,以A点x坐标和B点y坐标,确定椭圆上一个点M。
    在这里插入图片描述
    因此,当以∠θ绘制时,点A、B、M、圆心O,不在一条直线上。

    而通常情况下,以上图为例,以∠φ为参数调用接口,期望从M点开始绘制。需要∠φ与∠θ的转换关系。

    2. 离心角与旋转角的转换关系

    这里我称∠φ为旋转角,两者之间的转换公式推导参考这篇文章,这里写个结论:
    (这里的θ与φ与参考文章里的反过来的)

    tanθ = ( a / b) * tanφ
    tanφ = ( b / a) * tanθ

    再利用反三角函数计算出θ或者φ,需要注意的是,反三角函数的返回值总是在[-π/2, π/2],因此还需要进一步调整。

    由上图可以推测出,∠φ和∠θ一定是在同一个象限内,因此两者的差不可能超过π/2;而且,∠θ在一、三象限时,tanθ的符号相同,所以可以通过θ′ = θ±kπ,使得θ′与φ间隔在π/2以内。

    3. 转换代码

    qreal convertToEccentricAngle(qreal a, qreal b, qreal angle)
    {	
    	// *π和π/2使用宏即可*
        static qreal pi = qDegreesToRadians(180.0);
        static qreal half_pi = qDegreesToRadians(90.0);
    
        // 理论上两个角度差距不会很大,且落在同一象限
        // 反函数始终在第一象限和第四象限
        qreal ret = qAtan(a / b * qTan(angle));
        if(ret > angle)
        {
            ret -= int((ret - angle) / pi) * pi;
            if(ret - angle > half_pi)
                ret -= pi;
        }
        else
        {
            ret += int((angle - ret) / pi) * pi;
            if(angle - ret > half_pi)
                ret += pi;
        }
        return ret;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    使用该函数将指定的弧度制角转换到对应的离心角,也可以自己补充角度制的转换。

    效果如下:

    请添加图片描述

  • 相关阅读:
    自助取款机系统(C#)
    给Hexo添加说说功能
    [kubernetes/docker] failed to resolve reference ...:latest: not found
    利用浏览器DevTools中对React项目进行内存泄露排查
    SPI 详解
    Arduino程序设计(三) 光照采集 + 温度采集
    海外十大海外视频媒体推广网站-大舍传媒
    使用docker快速安装开发环境
    如何隐藏这个 columns: [ { title: ‘操作‘, dataIndex: ‘action‘,
    qml 使用Shape 画图形
  • 原文地址:https://blog.csdn.net/eiilpux17/article/details/126254551