首页 > 其他分享 >Qt 求圆和椭圆上任意角度点的坐标

Qt 求圆和椭圆上任意角度点的坐标

时间:2024-04-02 17:35:20浏览次数:16  
标签:求圆 椭圆 const Qt int 45 旋转 QPoint painter

0.圆相关公式

在笛卡尔坐标系上,一个标准的圆是这样的:

 已知圆心坐标 (x0,y0),半径 R,角度 a,则圆边上点(x',y')的坐标为:

C 的三角函数参数为弧度,转换如下:

角度转弧度: 

弧度转角度:

但我们知道,Qt 绘图是屏幕坐标系,起点在左上角,以右下角为正方向:

 (可以把计算后的 y 取反来得到想要的效果)

 1 void MainWindow::paintEvent(QPaintEvent *event)
 2 {
 3     event->accept();
 4  
 5     QPainter painter(this);
 6     painter.setPen(QPen(Qt::red,2));
 7     //移动坐标中心点到窗口中心,默认左上角为起点,往右下为正方向
 8     painter.translate(width()/2,height()/2);
 9     //画一个圆,圆心为起点(上一步移动到的正中),半径100px
10     const int R=100;
11     painter.drawEllipse(QPoint(0,0),R,R);
12     //计算45度角圆边上的点,角度需要转换为弧度
13     const double a=qDegreesToRadians((double)45);
14     const int x=0+R*cos(a);
15     const int y=0+R*sin(a);
16     //因为屏幕坐标系y轴正方向和笛卡尔坐标系相反,所以y取反就是我们要的结果了
17     painter.drawLine(QPoint(0,0),QPoint(x,-y)); //y取反
18 }

运行结果:

1.椭圆相关公式

在笛卡尔坐标系上,一个标准的椭圆是这样的:

 已知圆心坐标 (x0,y0),横轴 A(长半轴),竖轴 B(短半轴),角度 a,则圆边上点(x',y')的坐标为:

 椭圆半径:

 (可以发现,与普通圆相比,不考虑椭圆角度的话只是半径变化了,其他部分是一样的)

 1 void MainWindow::paintEvent(QPaintEvent *event)
 2 {
 3     event->accept();
 4  
 5     QPainter painter(this);
 6     painter.setPen(QPen(Qt::red,2));
 7     //移动坐标中心点到窗口中心,默认左上角为起点,往右下为正方向
 8     painter.translate(width()/2,height()/2);
 9     //画一个圆,圆心为起点(上一步移动到的正中),半径100px
10     const int A=150; //横轴
11     const int B=100; //竖轴
12     painter.drawEllipse(QPoint(0,0),A,B);
13     //计算45度角圆边上的点,角度需要转换为弧度
14     const double a=qDegreesToRadians((double)45);
15     const int R=A*B/sqrt(pow(A*sin(a),2)+pow(B*cos(a),2)); //计算对应角度的半径
16     const int x=0+R*cos(a);
17     const int y=0+R*sin(a);
18     //因为屏幕坐标系y轴正方向和笛卡尔坐标系相反,所以y取反就是我们要的结果了
19     painter.drawLine(QPoint(0,0),QPoint(x,-y)); //y取反
20 }

运行结果:

2.旋转矩阵

上面的角度都是从右侧开始,椭圆也是标准椭圆,如果我们想旋转一定角度来绘制,就需要用到我们的旋转矩阵了。

(本节主要来自参考博客)

已知 A(x,y) ,求旋转 a 角度后的 B(x’,y’) 坐标:

 公式推导:

 根据矩阵乘法计算规则,可以推出:

操作流程:

  • 把图形的各点平移,令旋转中心平移至原点;
  • 乘以旋转矩阵;
  • 再平移至原来的旋转中心。

我们将上面椭圆的代码改一下,逆时针旋转 45 度:

 1  
 2 void MainWindow::paintEvent(QPaintEvent *event)
 3 {
 4     event->accept();
 5  
 6     QPainter painter(this);
 7     painter.setPen(QPen(Qt::red,2));
 8     //移动坐标中心点到窗口中心,默认左上角为起点,往右下为正方向
 9     painter.translate(width()/2,height()/2);
10     //画一个圆,圆心为起点(上一步移动到的正中),半径100px
11     const int A=150; //横轴
12     const int B=100; //竖轴
13     painter.rotate(-45); //在屏幕坐标系,qpainter是顺时针转的
14     painter.drawEllipse(QPoint(0,0),A,B);
15     painter.rotate(45);
16  
17     //计算45度角圆边上的点,角度需要转换为弧度
18     const double a=qDegreesToRadians((double)45);
19     const int R=A*B/sqrt(pow(A*sin(a),2)+pow(B*cos(a),2)); //计算对应角度的半径
20     const int x=0+R*cos(a);
21     const int y=0+R*sin(a);
22     //根据旋转矩阵计算
23     const double a2=qDegreesToRadians((double)45);
24     const int x2=x*cos(a2)-y*sin(a2);
25     const int y2=x*sin(a2)+y*cos(a2);
26     //因为屏幕坐标系y轴正方向和笛卡尔坐标系相反,所以y取反就是我们要的结果了
27     painter.drawLine(QPoint(0,0),QPoint(x2,-y2)); //y取反
28 }

运行结果:

(第一次计算的角度坐标是计算标准椭圆下的位置,第二次是根据椭圆的旋转角度做旋转得到的坐标)

(本来就有 45 度,从右侧逆时针旋转,再旋转 45 度就成了垂直向上了)

 (虽然线可以直接 QPainter 旋转的方式绘制,但是这样文本也旋转了)

标签:求圆,椭圆,const,Qt,int,45,旋转,QPoint,painter
From: https://www.cnblogs.com/ybqjymy/p/18111115

相关文章

  • windows下编译paho.mqtt
    1、准备(1)Github仓库地址:https://github.com/eclipse/paho.mqtt.chttps://github.com/eclipse/paho.mqtt.cpp(2)VisualStudio2022以及CMakehttps://visualstudio.microsoft.com/zh-hans/vs/community/https://cmake.org/download/2、编译C库首先clone源码到本地文件......
  • Vue3连接mqtt订阅消息
    Vue3中使用以及订阅没有安装可使用npminstallmqtt--save(暂时使用了[email protected])页面引入引用mqtt库不要直接引用mqtt会报错importmqttfrom'mqtt/dist/mqtt'代码:1.获取动态配置(关于mqtt的动态配置)<script>////引入mqttimportmqttfrom"mqt......
  • Qt qSin()用法
    在Qt中,qSin()是一个数学函数,用于计算给定角度的正弦值。它的使用方法如下:1#include<QtCore/qmath.h>2//...3doubleangle=45.0;//角度值(以度为单位)4doubleradians=qDegreesToRadians(angle);//将角度转换为弧度5doublesinValue=qSin(radians);//计算......
  • Qt QScatterSeries理论总结
    一、概述QScatterSeries类以散点图的形式呈现数据。散点数据在图表上显示为点的集合。对于每个点,都指定了两个值,用于确定它在水平轴和垂直轴上的位置。同时,这个这个类是继承至QXYSeries类,散点图的很多功能特性和QLineSeries和QSplineSeries基本一致的。都是横纵坐标代......
  • Qt中的撤销/重做功能
    作为一个例子,本例只实现了在列表控件“添加项”和“修改项名称”的2个操作。界面上显示一个列表框,列表框需要在界面设计器中设为IconMode,这样就会是图标在上文本在下的显示样式。“添加”按钮用来在列表框中加一个项。点击图标下面的文本可以修改文本名称。程序测试环境是VS2017和......
  • Qt 配置Eigen
    Eigen简介Eigen支持包括固定大小、任意大小的所有矩阵操作,甚至是稀疏矩阵;支持所有标准的数值类型,并且可以扩展为自定义的数值类型;支持多种矩阵分解及其几何特征的求解;它不支持的模块生态系统提供了许多专门的功能,如非线性优化,矩阵功能,多项式解算器,快速傅立叶变换等。......
  • QT开发:报错:QAxBase: Error calling IDispatch member Open: Exception thrown by serv
    在Qt中打开excel出现下面的错误提示:QAxBase:ErrorcallingIDispatchmemberOpen:Exceptionthrownbyserver怎么解决?错误提示通常意味着在尝试使用Qt的ActiveX模块(QAxBase)打开Excel文件时发生了异常。这可能是由于多种原因引起的,包括文件损坏、权限问题、Excel安装问题或者Q......
  • Qt程序员必看/关于Qt收费的官方答复
    一、答复说明Qt软件从诞生之日就是GPL/LGPL开源授权和商业授权并存的,开源不代表免费而是为了共享。关于您的问题,我做大致的回复。Qt商用版本的模块是否都是LGPL协议,所有模块是否存在GPL这种要求强制开源的协议?如果购买Qt商业许可,那么客户就不需要收到GPL儿GPL的协议约束,可以......
  • Qt中的ui文件
    Qt中的ui文件简介Qt中的UI文件是一种特殊的XML格式文件,用于描述应用程序的用户界面。这些文件可以使用Qt的可视化设计工具QtDesigner来创建和编辑。QtDesigner提供了直观的界面,允许用户通过拖放和配置界面元素来设计应用程序的图形用户界面(GUI)。UI文件包含了界面上各种控件的......
  • Qt 实现的万能采集库( 屏幕/相机/扬声器/麦克风采集)
    【写在前面】        之前应公司需要,给公司写过一整套直播的库(推拉流,编解码),类似于libobs。    结果后来因为没有相关项目,便停止开发&维护了。    不过里面很多有用的组件,然后也挺好用的,遂开源出来一部分。    因此,本篇就简单讲一下用......