七夕专属博文-使用QGraphics画“红心“或“黑心“(含数学模型讲解)

news/2025/2/13 0:15:21/

说明

实现的效果是这样的,使用QGraphicsEllipseItem和QGraphicsPolygonItem画“心”。

比如来个红心

再来个“黑心”:

“心形”模型详解

这里需要用到高中数学。

①要了解圆的参数方程,其公式是这样的:

x = a + r · cosθ 和 y = b + r · sinθ

其中(a, b)为圆心的坐标,r为圆的半径,θ是角度取值范围为[0, 2π]。

②在C++或各种语言里面有专门的sin、cos函数,在Qt框架里面使用QtMath的头文件。这里传的参数需要弧度,所以,而在数学里面,圆的参数方程里面传入的参数是角度,所以还要需要了解,角度转弧度公式:

弧度 = 角度 · (π / 180)

了解了公式后,下面来说下,这个爱心的画法:

首先是画两个带角度的圆。

左边的圆:角度是从0度到225度。

右边的圆:角度是从-45度到180度。

如下图:

 

然后找到2个圆心点,用圆的参数方程,找边上的2个点

再到两圆之间找法线上找任意一点:

通过这5个点构造多边形,如下:

这样将这3个图形组合起来,就是一个“心”了。

代码解析

程序结构如下:

 

源码如下:

Widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>class QGraphicsScene;QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();protected:void drawCricle(int x, int y, int height, int width, int startAngle, int endAngle);void drawPolygon();private:Ui::Widget *ui;QGraphicsScene *m_scene;
};
#endif // WIDGET_H

main.cpp

#include "Widget.h"#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);Widget w;w.show();return a.exec();
}

 Widget.cpp

#include "Widget.h"
#include "ui_Widget.h"
#include <QGraphicsEllipseItem>
#include <QGraphicsPolygonItem>
#include <QPolygonF>
#include <QPen>
#include <iostream>
#include <QtMath>
#include <QGraphicsScene>
#include <QDebug>
#include <QPoint>Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);ui->graphicsView->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);m_scene = new QGraphicsScene;ui->graphicsView->setScene(m_scene);drawCricle(-100, 0, 200, 200, 0, 360 * 10);drawCricle(100, 0, 200, 200, 360 * 14, 360 * 10);drawPolygon();this->setWindowTitle("it1995.cn Designed by FengFanChen");
}Widget::~Widget()
{delete m_scene;delete ui;
}void Widget::drawCricle(int x, int y, int height, int width, int startAngle, int endAngle)
{auto item(new QGraphicsEllipseItem(x, y, height, width));item->setBrush(Qt::red);item->setStartAngle(startAngle);item->setSpanAngle(endAngle);item->setPen(QPen(Qt::red));m_scene->addItem(item);
}void Widget::drawPolygon()
{double oneCricleHeartX = -2.5;double oneCricleHeartY = 95;double oneX = oneCricleHeartX + 100 * cos(135 * ( M_PI /180));double oneY = oneCricleHeartY + 100 * sin(135 * ( M_PI /180));double endX = 100;double endY = 100 + 200;
//    auto item(new QGraphicsEllipseItem(x, y, 10, 10));//auto item(new QGraphicsEllipseItem(100 - 5, 100 - 5 + 100, 10, 10));
//    auto item(new QGraphicsEllipseItem(endX, endY, 10, 10));
//    item->setBrush(Qt::blue);
//    m_scene->addItem(item);//    auto line1Item(new QGraphicsLineItem(oneX, oneY + 2.5, endX + 1, endY + 1));
//    m_scene->addItem(line1Item);//第二个double twoCricleHeartX = 200;double twoCricleHeartY = 95;
//    auto item(new QGraphicsEllipseItem(twoCricleHeartX - 5, twoCricleHeartY, 10, 10));
//    item->setBrush(Qt::blue);
//    m_scene->addItem(item);double twoX = twoCricleHeartX + 100 * cos(45 * ( M_PI /180));double twoY = twoCricleHeartY + 100 * sin(45 * ( M_PI /180));
//    auto item(new QGraphicsEllipseItem(twoX - 5, twoY, 10, 10));
//    item->setBrush(Qt::blue);
//    m_scene->addItem(item);
//    auto line2Item(new QGraphicsLineItem(twoX, twoY + 5, endX + 1, endY + 1));
//    m_scene->addItem(line2Item);auto polygonItem = (new QGraphicsPolygonItem());QPolygonF pf;pf.append(QPoint(endX + 1, endY + 1));pf.append(QPoint(oneX + 2, oneY + 5));pf.append(QPoint(oneCricleHeartX, oneCricleHeartY + 5));pf.append(QPoint(twoCricleHeartX, twoCricleHeartY + 5));pf.append(QPoint(twoX, twoY + 5));polygonItem->setPolygon(pf);polygonItem->setPen(QPen(Qt::red));polygonItem->setBrush(Qt::red);m_scene->addItem(polygonItem);
}

有几个关键点要说:

①QGraphic的坐标系和数学里面的不一样,他和屏幕里面的坐标一样,y轴下方为正,y轴上方为负。

②在QGraphicsEllipseItem中有按角度画圆的函数:

void QGraphicsEllipseItem::setStartAngle(int angle)
Sets the start angle for an ellipse segment to angle, which is in 16ths of a degree. This angle is used together with spanAngle() for representing an ellipse segment (a pie). By default, the start angle is 0.

从官方文档可以知道,他扩大了16倍,也就是说360 * 16是直角坐标系的360,所以如果是90度的角度,就是90 * 16。

③代码里面的这些代码:

QPolygonF pf;
pf.append(QPoint(endX + 1, endY + 1));
pf.append(QPoint(oneX + 2, oneY + 5));
pf.append(QPoint(oneCricleHeartX, oneCricleHeartY + 5));
pf.append(QPoint(twoCricleHeartX, twoCricleHeartY + 5));
pf.append(QPoint(twoX, twoY + 5));

 这些+1,+2,+5是用来调节的,避免算点时因为精度丢失,导致要画的“心”不好看。

源码打包下载

地址如下:

Qt/DrawHeart at master · fengfanchen/Qt · GitHub


http://www.ppmy.cn/news/392381.html

相关文章

ecstore ego.php,商派(ONex)的bbc多用户商城bbc问题解答总集ecstore

1.bbc的前台用户登录失效时间是多少 前台系统默认设置的是3600秒&#xff0c;如果设置为记住密码则是7天 2.oms运行时报错 今天运行oms时出现错误&#xff0c;请问可能会是什么原因导致&#xff1f; TrackThu, 18 Feb 16 11:25:07 0800 t function does not exist in /data/gua…

商派oneX新零售系统上架华为云云商店,首次参与“828企业节”

01 商派oneX平台上架「华为云」云商店* 华为联运模式开启数字化转型新篇章* 由华为云与生态伙伴联合发起的首届828 B2B企业节将于8月28日正式启动。828 B2B企业节是中国首个基于数字赋能的“B2B企业节”&#xff0c;旨在助力中国企业通过数字化转型实现创新发展&#xff0c;…

商派onex本地部署无法进入的问题

商派最新版的ONex本地虚拟机部署项目无法进入注册的问题解决 进入项目的database.php文件&#xff0c;复制host的值 vim /etc/hosts&#xff0c;将hosts内容添加到/etc/hosts里面去就可以了 转载于:https://www.cnblogs.com/wangning528/p/7904314.html

如何查找自己笔记本的产品密钥

1.首先在键盘按下WinR打开运行 2.输入regedit&#xff0c;回车之后会打开注册表 3.依次展开到 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SoftwareProtectionPlatform目录下&#xff0c;单击SoftwareProtectionPlatform 4.双击右侧的BackupProd…

windows server 2003 R2密钥

windows server 2003 R2 密钥 windows server 2003 R2 32位密钥 序列号: MDGIK PF6YO PD8D ROW-TIKNE Windows Server 2003 R2 64位密钥 序列号: RYCR6-T7Y6M-2TVHK C2YW3-7TYQ8 W

通过CMD命令查找产品密钥

1.winr&#xff0c;输入cmd。 2.输入wmic path softwarelicensingservice get OA3xOriginalProductKey

如何查看电脑的产品密钥

如何查看电脑的产品密钥 密钥有使用次数&#xff0c;换了新的电脑之后&#xff0c;电脑本身的windows是已激活状态&#xff0c;那么怎么查看电脑的密钥呢&#xff1f; 1. 在键盘按下WinR打开运行。 2. 输入regedit&#xff0c;回车会打开注册表。 3. 输入绝对路径&#xff1…

查询您的 Windows 11 产品密钥

如果您想查询您的 Windows 11 产品密钥&#xff0c;可以使用命令提示符或 PowerShell 来实现。下面是如何使用命令提示符查询产品密钥的步骤 &#xff1a; 1. 打开开始菜单。 2. 在搜索栏中输入“命令提示符”或“cmd”&#xff0c;然后按回车键。 3. 在弹出的窗口中&#xff…