Qt实现环形拖动旋转框

目的

本来设计如图一个环形属性旋转框, 其难点是在于如何在一个圆形的窗口中 如何鼠标拖动指示器实现旋转并依据角度变化, 依据设计范围准确显示当前值。

可能有些会想到利用顺时针, 逆时针, 这虽然是一个好的想法idea, 那么问题来了? 你怎么判断顺时针,逆时针, 这个想法设计我网上搜了下, 感觉问题相对来说就弄复杂了。

一种方法就是可以参考环形进度条原理, 去设计。 我只需要找一个相对某个初始化参考位置, 另一个位置变化, 然后求出转动角度(0-360),结合你给定的数值范围, 360° ,可以求出当前位置的数值。稍微难一点在于如何求出两者之间夹角, 以及弧度与角度转换。
如何求夹角
c++ 弧度值与角度值的转换
数学函数库

double Rad_to_deg  = 45.0 / atan(1.0);
弧度值到角度值的转换  用   角度 =  弧度值* Rad_to_deg 
角度值到弧度值的转换  用  弧度值 = 角度 /  Rad_to_deg

我采用的是三点求夹角, 通过向量夹角余弦公式法

比如已知三点M(1,1),A(2,2),B(2,1)求角度∠AMB
1.先求向量MA,MB
向量公式 MA=(A.x-M.x)i+(B.x-M.x)j
所以:
MA=(2-1,2-1)=(1,1)
MB=(2-1,1-1)=(1,0)
则两向量的数量积为:
MA*MB=1×11×01
2.求向量的模
向量的模=sqrt(x*x+y*y)
|MA|=√(1×1)+(1×1)=√2
|MB|=(1*1)+(0*0)=1
将以上结果带入向量夹角余弦公式得:
cos∠AMB=MA*MB/|MA|*|MB|=2/2
则∠AMB=45

核心思路 :以圆心为原点, 正y轴向上一定长度某个点为一个点, 另一个点为窗口鼠标移动或者点击某个点, 然后求其三点之间夹角。

在这里插入图片描述
代码: 返回的值是0-360.

double DashBoardWidget::getAngle(const QPointF &point)
{
   QPointF v1(m_yOriginPos.x()  - m_originPos.x(), m_yOriginPos.y()  - m_originPos.y());
   QPointF v2(point.x() - m_originPos.x(), point.y() - m_originPos.y());
   double N(v2.x() * v1.x() + v2.y() * v1.y());
   double M1 = sqrt(v1.x() * v1.x() + v1.y() * v1.y());
   double M2 = sqrt(v2.x() * v2.x() + v2.y() * v2.y());
   double cosValue = N / (M1 * M2);
   double radtoDeg = 45.0 / atan(1.0);
   bool positiveAngle = (point.x() >= m_originPos.x()) ? true : false;
   double cos = radtoDeg * acos(cosValue);
   double realAngle = cos;
   if(!positiveAngle){
       realAngle = 360.0 - realAngle;
   }
   qDebug() << __FUNCTION__ << "cosValue!" << cos << realAngle;
//   double angel = acos(cosValue);
   return realAngle;
}

如下是网上搜到较多的仪表盘之类的博客, 可看看, 拓展思路
博客大佬一
QPainter中坐标系变换问题
基本图形绘制
在这里插入图片描述
大佬博客二

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道阻且长,行则降至

无聊,打赏求刺激而已

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值