目录
实验 1 直线的绘制...............................................................................................................2
实验 2 直线的 DDA 生成算法..............................................................................................5
实验 3 直线中点生成算法.................................................................................................10
实验 4 直线 Bresenham 生成算法.................................................................................... 17
实验 5 中点画圆算法.........................................................................................................23
实验 6 中点画椭圆算法.....................................................................................................27
实验 7 多边形有序边表算法.............................................................................................31
实验 8 边标志多边形填充算法.........................................................................................40
实验 9 种子填充算法.........................................................................................................47
实验 10 直线的裁剪...........................................................................................................57
实验 11 多边形的裁剪算法...............................................................................................63
实验 12 Weiler-Athenton 多边形裁剪算法....................................................................... 70
一、方法..........................................................................................................................70
二、算法..........................................................................................................................70
三、数据结构..................................................................................................................71
四、核心代码详注..........................................................................................................73
五、结论..........................................................................................................................80
六、分析总结..................................................................................................................80
实验 13 视窗变换...............................................................................................................81
实验 14 3D 房屋绘制.......................................................................................................... 88
实验 15 金字塔.................................................................................................................104
实验 16 交互技术应用.....................................................................................................111
实验 17 光照模型实例......................................................................................................156
实验 18 阴影 Shade..........................................................................................................166
实验 19 纹理实验.............................................................................................................173
实验 20 贝塞尔曲线.........................................................................................................181
实验 1 直线的绘制
一、要求:绘制一条直线,界面如图
二、步骤:
1. 启动 Qt,选择 New Project
2. 选择”Application” - “Qt Widgets Application” - “Choose”
3. 输入项目名称”cgExperiment01DrawLine”,选择路径,设为默认项目路径。注意:Qt
不支持中文路径。点击“下一步”。
4. 选择库函数等配套组件 kits 为 Desktop Qt 5.11.1 MinGW 32bit,点击“下一步”。
5. 选择主窗口 MainWindow 模式,保留“创建界面”,点击“下一步”。
6. 点击“完成”。
7. 双击“mainwindow.ui”,打开主界面,修改主界面属性
8. 将主窗口尺寸拖动到合适大小
9. 修改属性 windowtitle 为“绘制直线”。
10. 向主界面中拖入一个 Group Box 控件,对象名称 ObjectName 为“groupBox_set”,标
题 Title 设为“参数设置”,尺寸可以拖动到合适大小
11. 向“groupBox_set”中拖入一个 Label 控件“label_x0”,标题 Title 设为“直线起点 x0: ”,
尺寸为:宽度 80,高度 20,右对齐
12. 向“groupBox_set”中拖入一个 Line Edit 控件“lineEdit_x0”,尺寸为:宽度 80,高度 20,
初始值设为 0
13. 按住 Ctrl 键,用鼠标选中 label_x0 和 lineEdit_x0,然后复制、粘贴,产生一对复本,
将其拖曳到合适位置,修改其属性,分别为 label_y0 和 lineEdit_y0
14. 用复制粘贴的办法产生直线终点控件 label_x1,lineEdit_x1,label_y1,和 lineEdit_y1
15. 向“groupBox_color”中拖入一个 Frame 控件“frame_color”,尺寸设置为合适大小,
frameShape 设为“Panel”,frameShadow 设为“Sunken”,自动填充背景 autoFillBackgroud 选项
选中,调色板 palette 设置背景为蓝色
16. 向“groupBox_color”中拖入一个 PushBotton 控件“pushButton_color”,标题 Title 设为
“更改颜色”,尺寸设置为合适大小
17. 向“groupBox_set”中拖入一个 Push Botton 控件“pushButton_ok”,标题 Title 设为“确
定”,尺寸自定义
18. 打开 mainwindow.h 头文件,添加
#include
#include
19. 在 mainwindow.h 头文件中添加
public:
void paintEvent(QPaintEvent*);
20. 在 mainwindow.cpp 文件中添加
void MainWindow::paintEvent(QPaintEvent*)
{
int w = ui->groupBox_set->width();
int h = ui->groupBox_set->height();
int x = width()-w-10;
int y = ui->groupBox_set->y();
ui->groupBox_set->setGeometry(QRect(x, y, w, h));
}
21. 在 mainwindow.h 头文件中添加
#include
#include
#include
#include
22. 在 mainwindow.h 头文件中添加
private:
QVector points;
QColor color;
23. 打开mainwindow.cpp文件,在构造函数中增加如下代码:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
points.append(QPoint(ui->lineEdit_x0->text().toInt(),
ui->lineEdit_y0->text().toInt()+
ui->mainToolBar->height()));
points.append(QPoint(ui->lineEdit_x1->text().toInt(),
ui->lineEdit_y1->text().toInt()+
ui->mainToolBar->height()));
color = ui->frame_color->palette().background().color();
}
24. 打开ui,为按钮“更改颜色”、“确定”添加槽函数,右键单击按钮即可添加
private slots:
void on_pushButton_color_clicked();
void on_pushButton_ok_clicked();
25. 打开mainwindow.cpp文件,完成槽函数代码
void MainWindow::on_pushButton_color_clicked()
{
color = QColorDialog::getColor();
ui->frame_color->setPalette(QPalette(color));
}
void MainWindow::on_pushButton_ok_clicked()
{
points[0] = QPoint(ui->lineEdit_x0->text().toInt(),
ui->lineEdit_y0->text().toInt()+
ui->mainToolBar->height());
points[1] = QPoint(ui->lineEdit_x1->text().toInt(),
ui->lineEdit_y1->text().toInt()+
ui->mainToolBar->height());
update();
}
26. 在paintEvent函数中增加绘制代码
QPainter* ptr = new QPainter(this);
if(points.size()>=2)
{
ptr->save();
ptr->setPen(color);
ptr->drawLine(points[0], points[1]);
ptr->restore();
}
delete ptr;
27. 运行程序
实验 2 直线的 DDA 生成算法
一、要求:用 DDA 算法绘制一条直线,界面同实验 1。
二、算法:
1. 可以将上一个实验的 mainwindow.ui 文件复制到本项目中来,覆盖本项目的 ui 文件,
这样可以简化界面设计
2. 创建一个直线类 line,添加如下代码
#ifndef LINE_H
#define LINE_H
#include
#include
#include
class line
{
private:
QPoint p0;
QPoint p1;
QColor color;
public:
line(QPoint p0, QPoint p1, QColor color);
void showLineInDDA(QPainter* ptr);
};
#endif // LINE_H
#include "line.h"
line::line(QPoint p0, QPoint p1, QColor color)
:p0(p0), p1(p1), color(color)
{
}
void line::showLineInDDA(QPainter* ptr)
{
int x, y;
double m, tx, ty;
QPoint temp;
ptr->save();
ptr->setPen(color);
if(p0.y() == p1.y())//水平边
{
if(p0.x()>p1.x())
{
temp = p0;
p0 = p1;
p1 = temp;
}
for(x=p0.x(); x
drawPoint(x, p0.y());
}
else if(p0.x() == p1.y())//垂直边
{
if(p0.y()>p1.y())
{
temp = p0;
p0 = p1;
p1 = temp;
}
for(y=p0.y(); ydrawPoint(p0.x(), y);
}
else
{
m = (double)(p1.y()-p0.y())/(double)(p1.x()-p0.x());
if(m>-1 && m<1)//斜率在-45°到 45°之间
{
if(p0.x()>p1.x())
{
temp = p0;
p0 = p1;
p1 = temp;
}
ty = p0.y();
for(x=p0.x(); x
drawPoint(x, y);
ty += m;
}
}
else//斜率超过 45°
{
if(p0.y()>p1.y())
{
temp = p0;
p0 = p1;
p1 = temp;
}
tx = p0.x();
for(y=p0.y(); ydrawPoint(x, y);
tx += 1/m;
}
}
}
ptr->restore();
}
3. 在主窗口程序添加如下代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
#include
#include
#include
#include
#include "line.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void paintEvent(QPaintEvent*);
private slots:
void on_pushButton_color_clicked();
void on_pushButton_ok_clicked();
private:
Ui::MainWindow *ui;
QVector points;
QColor color;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
}
ui->setupUi(this);
points.append(QPoint(ui->lineEdit_x0->text().toInt(),
ui->lineEdit_y0->text().toInt()+
ui->mainToolBar->height()));
points.append(QPoint(ui->lineEdit_x1->text().toInt(),
ui->lineEdit_y1->text().toInt()+
ui->mainToolBar->height()));
color = ui->frame_color->palette().background().color();
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::paintEvent(QPaintEvent*)