QCustomPlot中用直线标示曲线的值

摘自:https://blog.csdn.net/v6543210/article/details/84140985

QCustomPlot是一个非常好用的曲线控件,详细的介绍可以参见:https://www.cnblogs.com/swarmbees/p/6060473.html

要实现随着鼠标的移动,显示一条竖线并标明曲线的数值。

源码是参考https://blog.csdn.net/sunnyloves/article/details/82344815

添加了一些个性化。

 

一、使用

1.在初始化函数中new几个tracer,分别是XAxisTracer,DataTracer,CrossLine。

            //跟踪器
            plot.m_xTracer = new MyTracer(plot.m_custPlot, MyTracer::XAxisTracer, plot.m_custPlot);//x轴
            plot.m_tracer1 = new MyTracer(plot.m_custPlot, MyTracer::DataTracer, plot.m_custPlot);
            plot.m_tracer2 = new MyTracer(plot.m_custPlot, MyTracer::DataTracer, plot.m_custPlot);
            plot.m_lineTracer = new MyTracer(plot.m_custPlot, MyTracer::CrossLine, plot.m_custPlot);//直线

 2.添加对鼠标移动事件的响应

connect(m_custPlot, SIGNAL(mouseMove(QMouseEvent*)), this, SLOT(myMouseMoveEvent(QMouseEvent*)));

3.实现响应函数myMouseMoveEvent

其中pixelToCoord将鼠标的位置转换成具体的坐标系下的值

m_plot.m_custPlot->graph(0)->data()->findBegin(x_val);获取第一条曲线上相应的值。

EMSTabPage.m_plot.m_tracer1->updatePosition(x_val, value1);更新tracer的值

最后replot()就可以了。

    void MEMSCurve::myMouseMoveEvent(QMouseEvent* event)
    {
        int x_pos = event->pos().x();
        int y_pos = event->pos().y();
     
        float x_val = EMSTabPage.m_plot.m_custPlot->xAxis->pixelToCoord(x_pos);
        float y_val = EMSTabPage.m_plot.m_custPlot->yAxis->pixelToCoord(y_pos);
        EMSTabPage.m_plot.m_xTracer->updatePosition(x_val, y_val);
     
        auto iter = EMSTabPage.m_plot.m_custPlot->graph(0)->data()->findBegin(x_val);
        double value1 = iter->mainValue();
        iter = EMSTabPage.m_plot.m_custPlot->graph(1)->data()->findBegin(x_val);
        double value2 = iter->mainValue();
     
        EMSTabPage.m_plot.m_tracer1->updatePosition(x_val, value1);
        EMSTabPage.m_plot.m_tracer2->updatePosition(x_val, value2);
     
        EMSTabPage.m_plot.m_lineTracer->updatePosition(x_val, y_val);
     
        ui->custPlot->replot();//曲线重绘    
    }

代码实现:

在MyTracer中主要看updatePosition这个函数。

    void MyTracer::updatePosition(double xValue, double yValue)
    {
        if (!visible)
        {
            setVisible(true);
            visible = true;
        }
        if (yValue > plot->yAxis->range().upper)
            yValue = plot->yAxis->range().upper;
        switch (type) {
        case XAxisTracer:
        {
            tracer->position->setCoords(xValue, 1);
            label->position->setCoords(0, 15);
            arrow->start->setCoords(0, 15);
            arrow->end->setCoords(0, 0);
            setText(toQString(MStrTools::Time2String(xValue)));
            break;
        }
        case YAxisTracer:
        {
            tracer->position->setCoords(0, yValue);
            label->position->setCoords(-60, 0);
            //arrow->start->setCoords(-20, 0);
            //arrow->end->setCoords(0, 0);
            setText(QString::number(yValue, 'f', 1));
            break;
        }
        case DataTracer:
        {
            tracer->position->setCoords(xValue, yValue);
            label->position->setCoords(25, 0);
            //setText(toQString(MStrTools::Time2String(xValue)) + "\n "+ QString::number(yValue, 'f', 1));
            setText( QString::number(yValue, 'f', 1));
            break;
        }
        case CrossLine:
        {
            line->point1->setCoords(xValue, yValue);
            line->point2->setCoords(xValue, yValue - 1000.0);
     
            break;
        }
     
        default:
            break;
        }

 

源码可以在https://download.csdn.net/download/v6543210/10789372 下载
---------------------
作者:阿龙哥哥
来源:CSDN
原文:https://blog.csdn.net/v6543210/article/details/84140985
版权声明:本文为博主原创文章,转载请附上博文链接!

在Unity中使用贝塞尔曲线(Bezier)模拟角色的曲线跳跃,通常涉及以下步骤: 1. 设计贝塞尔曲线路径:首先你需要创建一条贝塞尔曲线作为角色跳跃的路径。这可以通过在Unity编辑器中使用Curves工具或者通过编程方式定义控制点来实现。 2. 计算曲线上的点:使用贝塞尔曲线公式根据时间参数t来计算曲线上的点。对于二次或三次贝塞尔曲线,你需要至少两个或三个控制点来定义曲线形状。 3. 应用曲线数据到角色动画:获取曲线上的点坐标,并将其应用到角色的Transform组件上,以此来控制角色沿着曲线移动。 以下是一个简化的代码示例,展示了如何实现角色沿着二次贝塞尔曲线跳跃的基本框架: ```csharp using UnityEngine; public class BezierCurveJump : MonoBehaviour { public Transform pointA; // 起始控制点 public Transform pointB; // 结束控制点 public Transform pointC; // 贝塞尔曲线控制点 private float journeyLength; // 曲线总长度 private float startTime; // 起跳时间 private bool isJumping = false; // 是否正在跳跃 void Start() { // 计算曲线总长度,用于后续时间控制 journeyLength = CalculateCurveLength(pointA.position, pointC.position, pointB.position); } void Update() { // 检测跳跃触发条件 if (Input.GetButtonDown("Jump") && !isJumping) { isJumping = true; startTime = Time.time; } // 实现跳跃逻辑 if (isJumping) { float distCovered = (Time.time - startTime) * 100; // 模拟动画速度 float fracJourney = distCovered / journeyLength; // 计算完成比例 // 计算曲线上的当前点 Vector3 currentPoint = CalculateBezierPoint(fracJourney, pointA.position, pointC.position, pointB.position); // 设置角色位置 transform.position = currentPoint; // 检查是否完成跳跃 if (fracJourney >= 1.0f) { isJumping = false; } } } // 根据时间参数t计算贝塞尔曲线上的点 Vector3 CalculateBezierPoint(float t, Vector3 p0, Vector3 p1, Vector3 p2) { float u = 1 - t; float tt = t * t; float uu = u * u; Vector3 p = uu * p0; p += 2 * u * t * p1; p += tt * p2; return p; } // 计算贝塞尔曲线总长度的近似 float CalculateCurveLength(Vector3 start, Vector3 mid, Vector3 end) { // 此处可以使用数积分方法(例如辛普森法则)来计算曲线长度 // 这里仅提供框架,具体实现需要根据贝塞尔曲线公式进行计算 return 0.0f; // 替换为实际计算长度的代码 } } ``` 请注意,上述代码中的`CalculateCurveLength`函数需要你根据贝塞尔曲线的公式进行具体实现,通常涉及到数积分的方法,比如辛普森法则,来计算曲线长度的近似
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值