【计算机图形学】

您所在的位置:网站首页 ps如何画任意直线图形图案 【计算机图形学】

【计算机图形学】

2024-07-09 09:19| 来源: 网络整理| 查看: 265

1. 问题描述:

理解基本图形元素光栅化的基本原理,实现直线绘制的中点画线算法、Bresenham算法、圆弧生成的中点画圆算法。掌握OpenGL画线及设置线的属性(颜色、线宽、线型)方法。

2. 算法描述: 1) 中心画线算法:

下面展示一些 伪代码。

void MidPLine(int x0,int y0,int x1,int y1,void (*setPixel)(int x,int y)) { a⬅abs(y0 - y1); b⬅abs(x0 - x1); d⬅a + b / 2; if(y0 > y1) { x⬅x0; y⬅y0; setPixel(x, y); while (x < x1) { if (d < 0) { x++; y++; d⬅d + a + b; // 取直线上方的像素点 } else { x++; d += a; // 取直线下方的像素点 } if (abs(斜率) >= 1) setPixel(y, x); else setPixel(x, y); } else { // 与上一种情况类似 } } 2) Bresenham算法:

下面展示一些 伪代码。

void BresLine(int x0, int y0, int x1, int y1, void (*setPixel)(int x, int y)) { SetPixel(x0, y0); // 绘出起始点(x0,y0) dx⬅abs(x0 - x1); // 表示两点x轴方向上的差值 dy⬅abs(y0 - y1); // 表示两点y轴方向上的差值 // 当(x0,y0)(x1,y1)表示同一个点时,退出函数。 if (dx < dy){ // 下面将斜率变换至0≤丨k丨≤1区间 flag = 1; // 此情况下丨k丨>=1,以x1,x2表示y轴的点;y1,y2表示x轴的点,以y轴为计长方向 swap_value(&x0, &y0); swap_value(&x1, &y1); swap_value(&dx, &dy); } int tx⬅ (x1 - x0) > 0 ? 1 : -1; // tx表示直线相对于起点在x轴的方向 int ty⬅ (y1 - y0) > 0 ? 1 : -1; // ty表示直线相对于起点在y轴的方向 int curx = x0; int cury = y0; int dS⬅2 * dy; // 用于表示迭代式中的项 int dT⬅2 * (dy - dx); // 用于表示迭代式中的项 int d⬅dS - dx; // 用于表示迭代式中的项 while (curx != x1){ if (d < 0) // 取直线下方的像素点 d += dS; else{ // 取直线上方的像素点 cury += ty; d += dT; } if(flag) SetPixel(cury, curx); else SetPixel(curx, cury); curx += tx; } } 3) 中心画圆算法:

下面展示一些 伪代码。

void MidPoint_Circle(int x0,int y0,int x1,int y1,void (*setPixel)(int x,int y)) { r⬅sqrt((1.0 * x1 - x0) * (1.0 * x1 - x0) + (1.0 * y1 - y0) * (1.0 * y1 - y0)); // 计算半径 x⬅0; y⬅r; d⬅1 - r; // 是公式中 1.25-r 取整后的结果 Cirpot(x0, y0, x, y, SetPixel); // 进行8路对称 while (x < y) { if (d < 0) d += 2 * x + 3; // 表明当前中点在圆内,下一个点亮的像素点选取圆外的像素点 else { d += 2 * (x - y) + 5; // 表明当前中点在圆外,下一个点亮的像素点选取圆内的像素点 y--; } x++; Cirpot(x0, y0, x, y, SetPixel); } } 测试结果: 1) 使用中点画线算法(任意斜率均可以画出,函数名:MidPLine)完成画线:

实际运行结果: 在这里插入图片描述

2) 使用Bresenham算法(任意斜率均可以画出,函数名:BresLine)完成画线:

实际运行结果: 在这里插入图片描述

3) 使用中点画圆算法(函数名:MidPoint_Circle)完成画圆:

实际运行结果: 在这里插入图片描述

4) 用OpenGL画直线方法(函数名:OpenGLLine)完成画线:

实际运行结果: 在这里插入图片描述

分析与评论: 1) 中点画线算法:

本算法以起点到终点的计长方向距离 = max{|x1-x0|,|y1-y0|} 来进行扫描画线,时间复杂度为O(max{|x1-x0|,|y1-y0|})。

2) Bresenham算法:

Bresenham算法与中点画线算法一样,扫描的像素点是以起点到终点的计长方向距离 = max{|x1-x0|,|y1-y0|},所以时间复杂度也为O(max{|x1-x0|,|y1-y0|})。

3) 中点画圆算法:

以起点(x0,y0)为圆心,线段两端的距离为半径画圆。在画圆的过程中以x轴的计长方向上的值来扫描像素点,所以总的时间复杂度是O(|x结束-x起始|)。但是由于本算法中有一步将”1.25-r”取整为”1-r”将导致出现误差,如果用双精度存不取整将更精确。

4) 用OpenGL画直线方法完成画线:

相比于中间画线算法和Bresenham算法,这种算法是封装好的函数,对于初学者来说很友好,只需修改对应参数即可,可操控性强。

附录: Source Code(in C) 链接: 直线和圆弧绘制算法实现.rar (代码仅供参考)

没有币的同学来Gitee吧!记得留下Star噢~ Jack-lllll 的Gitee仓库



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3