surfacewidget.h
#ifndef SURFACEWIDGET_H
#define SURFACEWIDGET_H
#include <QWidget>
#include <QPainter>
#include <QMouseEvent>
#include <QToolTip>
#include <QDebug>
#include <cmath>
class SurfaceWidget : public QWidget
{
Q_OBJECT
public:
explicit SurfaceWidget(QWidget *parent = nullptr);
protected:
void paintEvent(QPaintEvent *event) override;
private:
// 声明为const成员函数,因为不修改类成员
double surfaceFunction(double x, double y) const;
QTransform m_transform;
double m_scale = 50.0;
bool m_selectedPointValid = false;
double m_selectedX = 0;
double m_selectedY = 0;
};
#endif // SURFACEWIDGET_H
surfacewidget.cpp
#include "surfacewidget.h"
SurfaceWidget::SurfaceWidget(QWidget *parent) : QWidget(parent)
{
setMouseTracking(true); // 启用鼠标移动跟踪
}
void SurfaceWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
int width = this->width();
int height = this->height();
// 设置坐标系:原点在中心,Y轴向上
painter.translate(width/2, height/2);
painter.scale(1, -1);
// 保存变换矩阵用于鼠标坐标转换
m_transform = painter.transform();
// 绘制曲面网格
int steps = 50;
// 绘制水平线
for (int i = -steps; i <= steps; ++i) {
double x = i * m_scale / steps;
QPainterPath path;
bool first = true;
for (int j = -steps; j <= steps; ++j) {
double y = j * m_scale / steps;
double z = surfaceFunction(x, y);
QPointF point(x * m_scale, y * m_scale - z * m_scale/2);
if (first) {
path.moveTo(point);
first = false;
} else {
path.lineTo(point);
}
}
painter.setPen(QPen(Qt::blue, 1));
painter.drawPath(path);
}
// 绘制垂直线
for (int j = -steps; j <= steps; ++j) {
double y = j * m_scale / steps;
QPainterPath path;
bool first = true;
for (int i = -steps; i <= steps; ++i) {
double x = i * m_scale / steps;
double z = surfaceFunction(x, y);
QPointF point(x * m_scale, y * m_scale - z * m_scale/2);
if (first) {
path.moveTo(point);
first = false;
} else {
path.lineTo(point);
}
}
painter.setPen(QPen(Qt::red, 1));
painter.drawPath(path);
}
// 绘制选中的顶点
if (m_selectedPointValid) {
double z = surfaceFunction(m_selectedX, m_selectedY);
QPointF point(m_selectedX * m_scale,
m_selectedY * m_scale - z * m_scale/2);
painter.setPen(QPen(Qt::green, 4));
painter.drawPoint(point);
}
}
double SurfaceWidget::surfaceFunction(double x, double y) const
{
// 定义曲面函数 - 双曲抛物面
return (x*x - y*y) / 100.0;
// 可选其他曲面函数:
// return 5 * sin(sqrt(x*x + y*y) / 2.0; // 正弦曲面
}
在mainwindow.ui中,添加QWidget,并提升为:SurfaceWidget