【计算机图形学】扫面转换算法(DDA算法 & 中点画线算法 & Bresenham画线算法)

这篇具有很好参考价值的文章主要介绍了【计算机图形学】扫面转换算法(DDA算法 & 中点画线算法 & Bresenham画线算法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

模块1 扫描转换算法

一 实验目的

  1. 编写直线、弧线的光栅扫描转换算法,并对线宽与线形的算法加以探讨
  2. 用DDA算法、中点画线算法、Bresenham画线算法绘制直线(如果键盘输入数据,给出数据值;如果绘制图案,图案中应包含各种斜率;如果鼠标确定任意两点,给出操作说明)
  3. 意识到各类直线的光栅扫描转换算法的局限性,并尝试改进后实现任意斜率的直线的画法

二 实验理论分析

DDA法:

  1. 主要思想:主要采用增量算法思想,即当x每递增1时,y会递增k。而由于像素只能取整数,所以对(y+0.5)取整后标注该像素。
  2. 局限性:当k的绝对值小于1时,能够较好的描绘直线;但是当k的绝对值大于1时,光栅点分布较为稀疏,像素标注情况较差。
  3. 改进方法:当k的绝对值大于1时,将x和y的位置互换。即取x和y变化大的轴作为参考轴,来保证直线被光栅化后有足够多的像素。

中点画线法:

  1. 主要思想:采用直线的一般式方程,即ax+by+c=0。构造判别式为d=F(xi+1,yi+0.5)=a(xi+1)+b(yi+0.5)+c,当d<0时,取y+1,当d≥0时,取y。
  2. 局限性:计算量太太大,不如DDA算法;只能绘制斜率在0到1之间的正斜率直线。
  3. 改进方法:构造判别式为d0=F(x0+1,y0+0.5)=a+0.5b,重构在d的正负影响下dnew和dold之间的关系,并优化d为整数运算。根据dx和dy的大小关系,以跨步大的轴为步长方向,另一个轴为d的迭代方向。

Bresenham法:

  1. 主要思想:通过计算像素点之间的差值来决定下一个像素点的位置。一旦d≥1,就把它减去1,保证d在0、1之间,即始终有d∈[0,1)。
  2. 局限性:计算不方便;只能绘制斜率在0到1之间的正斜率直线。
  3. 改进方法:对于计算方便而言,第一种改进方法是令e=d-0.5,逐步迭代后判断e的正负并更改e;第二种改进方法是用e*2△x替换e,从而获得整数算法并避免除法。对于任意斜率而言,可以根据dx和dy的大小关系,以跨步大的轴为步长方向,另一个轴为e的迭代方向。

三 实验内容

1:用DDA算法绘制任意斜率的直线

实验结果如下图所示:

使用中点法完成直线的扫描转换,可以画出任意斜率的直线计算机图形学实验报告,计算机图形学,算法,计算机图形学

第一步:输入起点的坐标和终点的坐标(【100,100】为起点,【0,0】为终点)

使用中点法完成直线的扫描转换,可以画出任意斜率的直线计算机图形学实验报告,计算机图形学,算法,计算机图形学

第二步:程序自动连接上述两点

2:用中点画线和Bresenham画线算法绘制部分斜率的直线

2.1-Bresenham画线算法实验结果如下图所示:

第一行的操作分别为:水平从左向右画线、从左下向右上画线、从左上向右下画线(不超过45度);

使用中点法完成直线的扫描转换,可以画出任意斜率的直线计算机图形学实验报告,计算机图形学,算法,计算机图形学

第二行的操作分别为:从左上向右下画线(超过45度)、从右上向左下画线、从右下向左上画线;

2.2-中点画线算法实验结果如下图所示:

第一行的操作分别为:水平从左向右画线、从左下向右上画线、从左上向右下画线(不超过45度);

使用中点法完成直线的扫描转换,可以画出任意斜率的直线计算机图形学实验报告,计算机图形学,算法,计算机图形学

第二行的操作分别为:从左上向右下画线(超过45度)、从右上向左下画线、从右下向左上画线;

3:用中点画线和Bresenham画线算法绘制任意斜率的直线

3.1-Bresenham画线算法实验结果如下图所示:

第一行的操作分别为:水平方向画线(左->右,右->左)、从左上向右下画线(k的绝对值大于1,k的绝对值小于1)、从左下向右上画线(k的绝对值大于1,k的绝对值小于1);

使用中点法完成直线的扫描转换,可以画出任意斜率的直线计算机图形学实验报告,计算机图形学,算法,计算机图形学

第二行的操作分别为:从右上向左下画线(k的绝对值大于1,k的绝对值小于1)、从右下向左上画线(k的绝对值大于1,k的绝对值小于1)、竖直方向画线(上->下,下->上);

3.2-中点画线算法实验结果如下图所示:

使用中点法完成直线的扫描转换,可以画出任意斜率的直线计算机图形学实验报告,计算机图形学,算法,计算机图形学

从任一点出发,即当前点为起点,在四周画出其他的任意斜率的直线。最终结果为如下的辐射状的图形,即可证明该算法可以画出任意斜率的直线。

四 程序说明

Project中程序的调用:

将当前cpp文件的属性——常规——从生成中排除中选择否,其他文件选择是,即可运行当前的cpp文件

1

//

// 程序名称:DDA

// 功  能:用DDA算法绘制任意斜率的曲线

// 编译环境:VS2019,EasyX_20220116

// 最后修改:2022-3-3

#include <graphics.h>

#include <math.h>

#include <conio.h>

#include <iostream>

using namespace std;

void DDA_Line(int x0, int y0, int x1, int y1, int color){

    int dx = x1 - x0, dy = y1 - y0, step, k;

    float x = x0, y = y0, xIncre, yIncre;

    //斜率绝对值大于1的时候,以 y 的变化为基准

    if (abs(dx) > abs(dy)) {

        step = abs(dx);

    }

    else {

       step = abs(dy);

    }

    //x和y的增量计算

    xIncre = (float)dx / (float)step;

    yIncre = (float)dy / (float)step;

    for (k = 0; k < step; k++) {

       putpixel(int(x + 0.5f), (int)(y + 0.5f), color);

       x += xIncre;

       y += yIncre;

    }

}文章来源地址https://www.toymoban.com/news/detail-849187.html

int main(){

    int x1, y1, x2, y2;

    cout << "please input the start point:" << endl;

    cin >> x1 >> y1;

    cout << "please input the end point:" << endl;

    cin >> x2 >> y2;

   

    initgraph(640, 480);

    DDA_Line(x1, y1, x2, y2, WHITE);

    _getch();

    closegraph();

    return 0;

}

2题:中点画线

//

// 程序名称:中点画线

// 功  能:用中点画线算法绘制部分斜率的曲线

// 编译环境:VS2019,EasyX_20220116

// 最后修改:2022-3-3

#include <graphics.h>

#include <math.h>

#include <conio.h>

#include <iostream>

using namespace std;

void MidPointLine(int x0, int y0, int x1, int y1, int color) {

    int dx, dy, increE, increNE, d, x, y;

    dx = x1 - x0;

    dy = y1 - y0;

    d = dx - 2 * dy;

    increE = -2 * dy;

    increNE = 2 * (dx - dy);

    x = x0;

    y = y0;

    putpixel(x, y, color);

    while (x < x1) {

       if (d > 0) {

           d += increE;

           x++;

       }

       else {

           d += increNE;

           y++;

           x++;

       }

       putpixel(x, y, color);

    }

}

int main(){

    initgraph(640, 480);

    ExMessage m;

    int x0, y0, x1, y1;

    while (true) {

       m = getmessage(EX_MOUSE | EX_KEY);

       switch (m.message) {

       case WM_LBUTTONDOWN:

           x0 = m.x;

           y0 = m.y;

           setfillcolor(GREEN);

           fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3);

       case WM_RBUTTONDOWN:

           x1 = m.x;

           y1 = m.y;

           MidPointLine(x0, y0, x1, y1, WHITE);

           setfillcolor(GREEN);

           fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3);

       case WM_KEYDOWN:

           if (m.vkcode == VK_ESCAPE)

              return 0;  // 按 ESC 键退出程序

       }

    }

    closegraph();

    return 0;

}

2题:Bresenham画线

//

// 程序名称:bresenham画线

// 功  能:用bresenham画线算法绘制部分斜率的曲线

// 编译环境:VS2019,EasyX_20220116

// 最后修改:2022-3-3

#include <graphics.h>

#include <math.h>

#include <conio.h>

#include <iostream>

using namespace std;

void bresenham(int x0, int y0, int x1, int y1, int color) {

    int x, y, dx, dy, i, e;

    dx = x1 - x0;

    dy = y1 - y0;

    e = -dx;

    x = x0;

    y = y0;

    for (i = 0; i <= dx; i++) {

       putpixel(x, y, color);

       x++;

       e += 2 * dy;

       if (e >= 0) {

           y++;

           e -= 2 * dx;

       }

    }

}

int main() {

    initgraph(640, 480);

    ExMessage m;

    int x0, y0, x1, y1;

    while (true) {

       m = getmessage(EX_MOUSE | EX_KEY);

       switch (m.message) {

       case WM_LBUTTONDOWN:

           x0 = m.x;

           y0 = m.y;

           setfillcolor(GREEN);

           fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3);

       case WM_RBUTTONDOWN:

           x1 = m.x;

           y1 = m.y;

           bresenham(x0, y0, x1, y1, WHITE);

           setfillcolor(GREEN);

           fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3);

       case WM_KEYDOWN:

           if (m.vkcode == VK_ESCAPE)

              return 0;  // 按 ESC 键退出程序

       }

    }

    closegraph();

    return 0;

}

3题:中点画线

//

// 程序名称:中点画线:加强版

// 功  能:用中点画线算法绘制任意斜率的曲线

// 编译环境:VS2019,EasyX_20220116

// 最后修改:2022-3-3

#include <graphics.h>

#include <math.h>

#include <conio.h>

#include <iostream>

using namespace std;

void MidPointLine(int x0, int y0, int x1, int y1, int color)

{

    int a, b, d1, d2, d, x, y;

    float m;

    if (x1 < x0) {

       d = x0;

       x0 = x1;

       x1 = d;

       d = y0;

       y0 = y1;

       y1 = d;

    }

    a = y0 - y1; //y差值

    b = x1 - x0; //x差值

    if (b == 0) {

       m = -1 * a * 100;

    }

    else {

       m = (float) a / (x0 - x1);

    }

    x = x0;

    y = y0;

    putpixel(x, y, color);

    //斜率在0~1

    if (m >= 0 && m <= 1){

       d = 2 * a + b;

       d1 = 2 * a;

       d2 = 2 * (a + b);

       while (x < x1) {

           if (d <= 0) {

              x++;

              y++;

              d += d2;

           }

           else {

              x++;

              d += d1;

           }

           putpixel(x, y, color);

       }

    }

    //斜率在-1~0

    else if (m <= 0 && m >= -1) {

       d = 2 * a - b;

       d1 = 2 * a - 2 * b;

       d2 = 2 * a;

       while (x < x1) {

           if (d > 0) {

              x++;

              y--;

              d += d1;

           }

           else {

              x++;

              d += d2;

           }

           putpixel(x, y, color);

       }

    }

    //斜率在1~∞

    else if (m > 1) {

       d = a + 2 * b; d1 = 2 * (a + b), d2 = 2 * b;

       while (y < y1) {

           if (d > 0) {

              x++;

              y++;

              d += d1;

           }

           else {

              y++;

               d += d2;

           }

           putpixel(x, y, color);

       }

    }

    //斜率在∞~-1

    else {

       d = a - 2 * b; d1 = -2 * b, d2 = 2 * (a - b);

       while (y > y1) {

           if (d <= 0) {

              x++;

              y--;

              d += d2;

           }

           else {

              y--;

              d += d1;

           }

           putpixel(x, y, color);

       }

    }

}

int main() {

    initgraph(640, 480);

    ExMessage m;

    int x0, y0, x1, y1;

    while (true) {

       m = getmessage(EX_MOUSE | EX_KEY);

       switch (m.message) {

       case WM_LBUTTONDOWN:

           x0 = m.x;

           y0 = m.y;

           setfillcolor(GREEN);

           fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3);

       case WM_RBUTTONDOWN:

           x1 = m.x;

           y1 = m.y;

           MidPointLine(x0, y0, x1, y1, WHITE);

           setfillcolor(GREEN);

           fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3);

       case WM_KEYDOWN:

           if (m.vkcode == VK_ESCAPE)

              return 0;  // 按 ESC 键退出程序

       }

    }

    closegraph();

    return 0;

}

3题:Bresenham画线

//

// 程序名称:bresenham画线:加强版

// 功  能:用bresenham画线算法绘制任意斜率的曲线

// 编译环境:VS2019,EasyX_20220116

// 最后修改:2022-3-3

#include <graphics.h>

#include <math.h>

#include <conio.h>

#include <iostream>

using namespace std;

void bresenham(int x0, int y0, int x1, int y1, int color) {

    int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;

    int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;

    int erro = (dx > dy ? dx : -dy) / 2;

    while (putpixel(x0, y0, color), x0 != x1 || y0 != y1) {

       int e2 = erro;

       if (e2 > -dx) {

           erro -= dy;

           x0 += sx;

       }

        if (e2 < dy) {

           erro += dx;

           y0 += sy;

       }

    }

}

int main() {

    initgraph(640, 480);

    ExMessage m;

    int x0, y0, x1, y1;

    while (true) {

       m = getmessage(EX_MOUSE | EX_KEY);

       switch (m.message) {

       case WM_LBUTTONDOWN:

           x0 = m.x;

           y0 = m.y;

           setfillcolor(GREEN);

           fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3);

       case WM_RBUTTONDOWN:

           x1 = m.x;

           y1 = m.y;

           bresenham(x0, y0, x1, y1, WHITE);

           setfillcolor(GREEN);

           fillrectangle(m.x - 3, m.y - 3, m.x + 3, m.y + 3);

       case WM_KEYDOWN:

           if (m.vkcode == VK_ESCAPE)

              return 0;  // 按 ESC 键退出程序

       }

    }

    closegraph();

    return 0;

}

到了这里,关于【计算机图形学】扫面转换算法(DDA算法 & 中点画线算法 & Bresenham画线算法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【计算机图形学|直线生成算法】Bresenham画法详解

    Bresenham画法是一种用于计算计算机图形中线条的算法,其原理是沿着所需绘制的线段中的像素点进行递增或递减,来进行准确的点阵绘制。 实现该算法的关键在于确定像素在基准线上的位置,以及在每次迭代时进行相应的调整。该算法比传统的直线算法更快且更准确,在低速

    2024年02月07日
    浏览(52)
  • 计算机图形学03:改进的中点BH算法

    作者 :非妃是公主 专栏 :《计算机图形学》 博客地址 :https://blog.csdn.net/myf_666 个性签:顺境不惰,逆境不馁,以心制境,万事可成。——曾国藩 专栏名称 专栏地址 软件工程 专栏——软件工程 计算机图形学 专栏——计算机图形学 操作系统 专栏——操作系统 软件测试 专

    2024年01月17日
    浏览(46)
  • 【Weiler-Atherton算法】 计算机图形学多边形裁剪算法

    源代码: https://github.com/ricar0/Weiler-Atherton-Alogrithm/tree/master 通常来说就是利用多边形来裁剪多边形的一种方法,一般情况下是利用矩形来裁剪凹凸多边形 凸多边形 凹多边形 上面红色划线部分就是裁剪出的部分 OPENGL基础语法 基本上就是一些画线和画多边形的操作,难度较低

    2023年04月09日
    浏览(63)
  • 计算机图形学:直线段裁剪,Cohen-Sutherland算法

    在二维观察中,需要对窗口进行裁剪,即只保留窗口内的图形,去掉窗口外的图形。直线段裁剪即判断直线在窗口内的部分,去除在窗口外的部分(红圈处)。 其基本思想为编码,即对于直线上任一点(x,y),根据其坐标所在的区域,赋予一个4位的二进制码D3D2D1D0。 编码规则如

    2024年02月07日
    浏览(48)
  • 计算机图形学:三次Bezier曲线的绘制(算法原理及代码实现)

    一、实现方案        贝塞尔曲线原理:贝塞尔曲线是计算机图形图像造型的基本工具,是图形造型运用得最多的基本线条之一。它通过控制曲线上的四个点(起始点、终止点以及两个相互分离的中间点)来创造、编辑图形。其中起重要作用的是位于曲线中央的控制线。这条

    2024年02月11日
    浏览(50)
  • 【计算机图形学 】扫描线多边形填充算法 | OpenGL+鼠标交互

    传送门 实现多边形扫描线填充算法,并和鼠标进行交互。 具体原理略过,会贴上完整代码,可直接运行。 环境: vs2019,OpenGL的库(可以搜索如何用vs使用OpenGL的库,可以使用vs自带的插件或者其他方法,很方便) 要点: 1.NET和AET的创建,改动 2.改变鼠标点击和鼠标拖拽的响应

    2023年04月08日
    浏览(73)
  • 【计算机图形学】裁剪算法(Cohen-Sutherland算法 & 中值分割算法 & Liang-Barsky算法)

    一 实验目的 编写直线段、多边形裁剪算法 熟悉Cohen-Sutherland算法、中值分割算法和Liang-Barsky算法的裁剪 二 实验算法理论分析 Cohen-Sutherland 算法:     中值分割算法: 与CS算法一样,首先对直线段端点进行编码,并把线段与窗口的关系一样分为3种情况:全在、完全不在、线

    2024年02月03日
    浏览(48)
  • 【计算机图形学算法工具技巧】用Blender查看三维点云ply文件的点的序号和坐标

    因为用最近在学拉普拉斯曲面编辑的算法,需要查看三维点云ply文件的点的序号和坐标,然后固定或移动这些点的坐标。 这里介绍使用Blender 3.2软件查看三维点云ply文件的点的序号和坐标。 导入ply文件 隐藏不必要的物体(如cube),并将物体模式变成编辑模型!! 选择 gemo

    2024年02月13日
    浏览(71)
  • 计算机图形学实验——利用MFC对话框实现多边形绘制与填充(扫描线填充算法)附源码

    内容概括: 利用基于对话框的MFC项目 实现鼠标点击绘制多边形 实现扫描线算法填充多边形 源码见Yushan-Ji/ComputerGraphics: ECNU2023秋 计算机图形学课程实验代码 (github.com) 通过鼠标交互输入多边形 对各种多边形进行填充,包括边界自交的情况 利用 OnLButtonDown 和 OnRButtonDown 函数,

    2024年02月04日
    浏览(70)
  • 【图形学】探秘图形学奥秘:DDA与Bresenham算法的解密与实战

    ​ 🌈个人主页: Sarapines Programmer 🔥 系列专栏: 《图形学 | 图像解码》 ⏰诗赋清音:云生高巅梦远游, 星光点缀碧海愁。 山川深邃情难晤, 剑气凌云志自修。 ​ 目录 🌌1. 初识模式识别 🌌2. 开发环境的使用及基本图形生成 🌍2.1 开发环境及实现 🌍2.2 实验目的 🌍2

    2024年01月21日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包