QT 绘制贝塞尔曲线,并且获得曲线上的点的坐标

137 篇文章 44 订阅

贝塞尔曲线的几个步骤
1、起始点
2、控制点
3、控制点
4、结束点
附上下图(网上找的)
在这里插入图片描述
利用QT绘制曲线然后通过定时器遍历整条曲线,先看一下效果:
在这里插入图片描述

实现代码:

#pragma once
#include <QPainter>
#include <QPoint>
#include <QRect>

#include <QtWidgets/QMainWindow>
#include "ui_PathLine.h"

class PathLine : public QMainWindow {
	Q_OBJECT

public:
	PathLine(QWidget *parent = Q_NULLPTR);

	void paintEvent(QPaintEvent *event)override;

	void mousePressEvent(QMouseEvent *event)override;
	void mouseMoveEvent(QMouseEvent *event)override;
	void mouseReleaseEvent(QMouseEvent *event)override;

private:
	void drawBeser(QPainter&painter);
private slots:
	void slotTimeOut();
private:
	Ui::PathLineClass ui;

	
	bool _leftDown = false;//鼠标左键按下

	int _penWidth = 2;

	QPoint* startPoint = nullptr;
	QRect* startRect = nullptr;

	QPoint* endPoint = nullptr;
	QRect* endRect = nullptr;

	QPoint* c1 = nullptr;
	QRect* c1Rect = nullptr;

	QPoint* c2 = nullptr;
	QRect* c2Rect = nullptr;

	QPainterPath _pathTest;

	bool _selected = false;//是否选中点
	QPoint* _selectPoint = nullptr;

	QPointF pointPercent;//百分之比的点

	QTimer* _timer = nullptr;
	double _percent = 0.0;
};

#include <QMouseEvent>
#include <QPaintEvent>
#include <QTimer>
#include "PathLine.h"

PathLine::PathLine(QWidget *parent)
	: QMainWindow(parent) {
	ui.setupUi(this);

	startPoint = new QPoint(100, 100);
	startRect = new QRect(QPoint(95, 95), QPoint(105, 105));

	endPoint = new QPoint(200, 200);
	endRect = new QRect(QPoint(195, 195), QPoint(205, 205));

	c1 = new QPoint(180, 50);
	c1Rect = new QRect(QPoint(175, 45), QPoint(185, 55));

	c2 = new QPoint(120, 250);
	c2Rect = new QRect(QPoint(115, 245), QPoint(125, 255));

	ui.centralWidget->setMouseTracking(true);
	this->setMouseTracking(true);

	_timer = new QTimer(this);
	_timer->setTimerType(Qt::PreciseTimer);//设置定时器的精度,精确到毫秒
	connect(_timer, SIGNAL(timeout()), this, SLOT(slotTimeOut()));
	_timer->start(500);
}

void PathLine::paintEvent(QPaintEvent *event) {
	QPainter painter(this);
	painter.setRenderHint(QPainter::Antialiasing, true);
	QPen pen;
	pen.setColor(QColor(255, 0, 0));
	pen.setWidth(_penWidth);
	pen.setStyle(Qt::SolidLine);
	painter.setPen(pen);
	
	drawBeser(painter);
}

void PathLine::mousePressEvent(QMouseEvent *event) {
	if (event->button() == Qt::LeftButton) {
		_leftDown = true;

	}
	update();
}

void PathLine::mouseMoveEvent(QMouseEvent *event) {
	QPoint pos = event->pos();
	if (_leftDown){//左键按下
		if (_selected){//并且选中点
			_selectPoint->setX(pos.x());
			_selectPoint->setY(pos.y());
		}
	} else {
		if (startRect->contains(pos)) {
			_penWidth = 4;
			_selected = true;
			_selectPoint = startPoint;
		} else if (endRect->contains(pos)) {
			_penWidth = 4;
			_selected = true;
			_selectPoint = endPoint;
		} else if (c1Rect->contains(pos)) {
			_penWidth = 4;
			_selected = true;
			_selectPoint = c1;
		} else if (c2Rect->contains(pos)) {
			_penWidth = 4;
			_selected = true;
			_selectPoint = c2;
		} else {
			_selected = false;
			_penWidth = 2;
			_selectPoint = nullptr;
		}
	}

	update();
}

void PathLine::mouseReleaseEvent(QMouseEvent *event) {
	if (event->button() == Qt::LeftButton) {
		_leftDown = false;
	} else if (event->button() == Qt::RightButton) {
		
	}
	update();
}

void PathLine::drawBeser(QPainter&painter) {
	QPainterPath pathTest;
	painter.drawEllipse(*startPoint, 2, 2);
	painter.drawEllipse(*endPoint, 2, 2);
	painter.drawEllipse(*c1, 2, 2);
	painter.drawEllipse(*c2, 2, 2);
	pathTest.moveTo(*startPoint);
	pathTest.cubicTo(*c1, *c2, *endPoint);

	pointPercent = pathTest.pointAtPercent(_percent);
	painter.drawEllipse(pointPercent, 5, 5);

	painter.drawPath(pathTest);

}

void PathLine::slotTimeOut() {
	_percent += 0.01;
	update();
}

源码下载
aaa

  • 6
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

wb175208

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值