计算机图形学课程总结

原创 2017年01月03日 17:01:46

计算机图形学是我大三上学期开设的课程。现在写个博客,做点总结,也算是没白学这么课程吧~

一、 解释图形学中名词的含义

  • 图形要素:几何要素和非几何要素。
  • 多边形扫描转换:从多边形顶点表示到点阵表示的转换。
  • 消隐:在绘制图形时,消除被遮挡的不可见的线或面。
  • 扭失:曲面片四个顶点的二阶导。
  • 引力场技术:物体延伸到空间中对另一个物体产生吸引效应的技术。
  • 灭点:指立体图形的各边延伸至同一相交点。
  • 正则形体:由几何形体内部的点集和紧紧包裹这些点集的表皮所构成。
  • 反走样:减少或消除图形因锯锯齿齿而失真的技术。
  • 显示分辨率:显示器在显示图像时的分辨率。
  • C1连接:两条相邻曲线段在相交点处,具有相同的一阶导。
  • C2连接:两条相邻曲线段在相交点处,具有相同的一阶导和二阶导。
  • 简单光照模型:由环境光放射、漫反射及镜面光反射构成。
  • 深度缓冲存储:三维图形中处理图像深度坐标的过程。
  • 捕捉技术:利用外部设备捕捉计算机能直接理解的数据,如物体尺寸测量、物体空间定位等。
  • 存储分辨率:帧缓冲区的大小
  • 法向量插值法:保留双向性插值,并对顶点采用法向量插值,其中顶点的法向矢量值由该点相邻的多边形面片的法向矢量值取平均值取得。
  • CRT:阴极射线管
  • DPU:分散处理单元
  • 象素:基本原色素及其灰度的基本编码。
  • 4连通:同一像素在上、下、左、右四个方向上连通。
  • 实体:同时具有几何要素和视觉要素的对象。
  • 型值点:位于最终得到的自由曲线上的点。
  • 控制点:不位于最终得到的自由曲线上的点。
  • 颜色位面法:每一个位面控制一种颜色或灰度,每一个象素点在每一个位面中占一位,通过几个位面中德同一位组合成一个象素。

二、概念简述

  • 图像和图形的区别:图形是无中生有,由计算机软件绘制出来的,它是面向对象的,同时具有几何属性和视觉属性。而图像是由计算机外部设备捕捉得到的,并面向计算机内传输的信息。
  • 字符的两种表示方式:点阵字符和矢量字符。
  • 实体的表示方法:边界表示、分解表示、构造实体几何表示、扫描表示和元球表示。

三、基本图形生成算法

  • 画任意斜率的直线(基于 DDA 算法)
#include <graphics.h>
#include <conio.h>

// 四舍五入
int Round(float x)
{
    return (int)(x < 0 ? x - 0.5 : x + 0.5);
}

// 使用 DDA 算法画任意斜率的直线(包括起始点,不包括终止点)
void Line_DDA(int x1, int y1, int x2, int y2, int color)
{
    float x, y;     // 当前坐标点
    float cx, cy;   // x、y 方向上的增量

    int steps = abs(x2 - x1) > abs(y2 - y1) ? abs(x2 - x1) : abs(y2 - y1);

    x = (float)x1;
    y = (float)y1;
    cx = (float)(x2 - x1) / steps;
    cy = (float)(y2 - y1) / steps;

    for(int i = 0; i < steps; i++)
    {
        putpixel(Round(x), Round(y), color);    // 在坐标 (x, y) 处画一个 color 颜色的点
        x += cx;
        y += cy;
    }
}

// 主函数
void main()
{
    initgraph(640, 480);

    // 测试画线
    Line_DDA(100, 1, 1, 478, GREEN);
    Line_DDA(1, 478, 638, 1, GREEN);

    // 按任意键退出
    getch();
    closegraph();
}
  • 画任意斜率的直线(基于直线的中点算法)
#include <graphics.h>
#include <conio.h>

// 使用中点算法画任意斜率的直线(包括起始点,不包括终止点)
void Line_Midpoint(int x1, int y1, int x2, int y2, int color)
{
    int x = x1, y = y1;
    int a = y1 - y2, b = x2 - x1;
    int cx = (b >= 0 ? 1 : (b = -b, -1));
    int cy = (a <= 0 ? 1 : (a = -a, -1));

    putpixel(x, y, color);

    int d, d1, d2;
    if (-a <= b)        // 斜率绝对值 <= 1
    {
        d = 2 * a + b;
        d1 = 2 * a;
        d2 = 2 * (a + b);
        while(x != x2)
        {
            if (d < 0)
                y += cy, d += d2;
            else
                d += d1;
            x += cx;
            putpixel(x, y, color);
        }
    }
    else                // 斜率绝对值 > 1
    {
        d = 2 * b + a; 
        d1 = 2 * b;
        d2 = 2 * (a + b);
        while(y != y2) 
        { 
            if(d < 0)
                d += d1; 
            else 
                x += cx, d += d2; 
            y += cy; 
            putpixel(x, y, color);
        } 
    }
}

// 主函数
void main()
{
    initgraph(640, 480);

    // 测试画线
    Line_Midpoint(100, 1, 1, 478, GREEN);
    Line_Midpoint(1, 478, 638, 1, GREEN);

    // 按任意键退出
    getch();
    closegraph();
}
  • 画任意斜率的直线(基于 Bresenham 算法)
#include <graphics.h>
#include <conio.h>

// 使用 Bresenham 算法画任意斜率的直线(包括起始点,不包括终止点)
void Line_Bresenham(int x1, int y1, int x2, int y2, int color)
{
    int x = x1;
    int y = y1;
    int dx = abs(x2 - x1);
    int dy = abs(y2 - y1);
    int s1 = x2 > x1 ? 1 : -1;
    int s2 = y2 > y1 ? 1 : -1;

    bool interchange = false;   // 默认不互换 dx、dy
    if (dy > dx)                // 当斜率大于 1 时,dx、dy 互换
    {
        int temp = dx;
        dx = dy;
        dy = temp;
        interchange = true;
    }

    int p = 2 * dy - dx;
    for(int i = 0; i < dx; i++)
    {
        putpixel(x, y, color);
        if (p >= 0)
        {
            if (!interchange)       // 当斜率 < 1 时,选取上下象素点
                y += s2;
            else                    // 当斜率 > 1 时,选取左右象素点
                x += s1;
            p -= 2 * dx;
        }
        if (!interchange)
            x += s1;                // 当斜率 < 1 时,选取 x 为步长
        else
            y += s2;                // 当斜率 > 1 时,选取 y 为步长
        p += 2 * dy;
    }
}

// 主函数
void main()
{
    initgraph(640, 480);

    // 测试画线
    Line_Bresenham(100, 1, 1, 478, GREEN);
    Line_Bresenham(1, 478, 638, 1, GREEN);

    // 按任意键退出
    getch();
    closegraph();
}
  • 画圆(基于中点算法)
#include <graphics.h>
#include <conio.h>

// 中点画圆法
void Circle_Midpoint(int x, int y, int r, int color)
{
    int tx = 0, ty = r, d = 1 - r;

    while(tx <= ty)
    {
        // 利用圆的八分对称性画点
        putpixel(x + tx, y + ty, color);
        putpixel(x + tx, y - ty, color);
        putpixel(x - tx, y + ty, color);
        putpixel(x - tx, y - ty, color);
        putpixel(x + ty, y + tx, color);
        putpixel(x + ty, y - tx, color);
        putpixel(x - ty, y + tx, color);
        putpixel(x - ty, y - tx, color);

        if(d < 0)
            d += 2 * tx + 3;
        else
            d += 2 * (tx - ty) + 5, ty--;

        tx++;
    }
}

// 主函数
void main()
{
    initgraph(640, 480);

    // 测试画圆
    Circle_Midpoint(320, 240, 200, RED);
    Circle_Midpoint(320, 240, 101, RED);

    // 按任意键退出
    getch();
    closegraph();
}
  • 画圆(基于正负算法)
#include <graphics.h>
#include <conio.h>

// 正负画圆法
void Circle_PN(int x, int y, int r, int color)
{
    int tx = 0, ty = r, f = 0;

    while(tx <= ty)
    {
        // 利用圆的八分对称性画点
        putpixel(x + tx, y + ty, color);
        putpixel(x + tx, y - ty, color);
        putpixel(x - tx, y + ty, color);
        putpixel(x - tx, y - ty, color);
        putpixel(x + ty, y + tx, color);
        putpixel(x + ty, y - tx, color);
        putpixel(x - ty, y + tx, color);
        putpixel(x - ty, y - tx, color);

        if(f <= 0)
            f = f + 2 * tx + 1, tx++;
        else
            f = f - 2 * ty + 1, ty--;
    }
}

// 主函数
void main()
{
    initgraph(640, 480);

    // 测试画圆
    Circle_PN(320, 240, 200, RED);
    Circle_PN(320, 240, 101, RED);

    // 按任意键退出
    getch();
    closegraph();
}
  • 画圆(基于 Bresenham 算法)
#include <graphics.h>
#include <conio.h>

// 使用 Bresenham 画圆法
void Circle_Bresenham(int x, int y, int r, int color)
{
    int tx = 0, ty = r, d = 3 - 2 * r;

    while( tx <= ty)
    {
        // 利用圆的八分对称性画点
        putpixel(x + tx, y + ty, color);
        putpixel(x + tx, y - ty, color);
        putpixel(x - tx, y + ty, color);
        putpixel(x - tx, y - ty, color);
        putpixel(x + ty, y + tx, color);
        putpixel(x + ty, y - tx, color);
        putpixel(x - ty, y + tx, color);
        putpixel(x - ty, y - tx, color);

        if (d < 0)      // 取上面的点
            d += 4 * tx + 6;
        else            // 取下面的点
            d += 4 * (tx - ty) + 10, ty--;

        tx++;
    }
}

// 主函数
void main()
{
    initgraph(640, 480);

    // 测试画圆
    Circle_Bresenham(320, 240, 200, RED);
    Circle_Bresenham(320, 240, 101, RED);

    // 按任意键退出
    getch();
    closegraph();
}
  • 画填充圆(基于 Bresenham 算法)
#include <graphics.h>
#include <conio.h>

// 基于 Bresenham 算法画填充圆
void FillCircle_Bresenham(int x, int y, int r, COLORREF color)
{
    int tx = 0, ty = r, d = 3 - 2 * r, i;

    while( tx < ty)
    {
        // 画水平两点连线(<45度)
        for (i = x - ty; i <= x + ty; i++)
        {
            putpixel(i, y - tx, color);
            if (tx != 0)    // 防止水平线重复绘制
                putpixel(i, y + tx, color);
        }

        if (d < 0)          // 取上面的点
            d += 4 * tx + 6;
        else                // 取下面的点
        {
            // 画水平两点连线(>45度)
            for (i = x - tx; i <= x + tx; i++)
            {
                putpixel(i, y - ty, color);
                putpixel(i, y + ty, color);
            }

            d += 4 * (tx - ty) + 10, ty--;
        }

        tx++;
    }

    if (tx == ty)           // 画水平两点连线(=45度)
        for (i = x - ty; i <= x + ty; i++)
        {
            putpixel(i, y - tx, color);
            putpixel(i, y + tx, color);
        }
}

// 主函数
void main()
{
    // 创建绘图窗口
    initgraph(640, 480);

    // 测试画填充圆
    FillCircle_Bresenham(320, 240, 100, GREEN);

    // 按任意键退出
    getch();
    closegraph();
}
版权声明:本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接.

相关文章推荐

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

计算机图形学及OpenGL简介摘记

计算机图形学及OpenGL简介摘记

计算机图形学(二)输出图元_15_字符图元

和其他图元一样,字符的几何描述在世界坐标系中给出,该信息由观察变换映射到屏幕坐标系。位图字符使用矩形网格的二进制值及网格参考位置来描述。该位置随后被映射到帧缓存中的指定位置。轮廓字符由一组用曲线或线段...

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数

给定A, B两个整数,不使用除法和取模运算,求A/B的商和余数。 1.   最基本的算法是,从小到大遍历: for (i = 2 to A -1)          if (i * B > A)...

利用K-means聚类算法根据经纬度坐标对中国省市进行聚类

K-means聚类算法是一种非层次聚类算法,在最小误差的基础上将数据划分了特定的类,类间利用距离作为相似度指标,两个向量之间的距离越小,其相似度就越高。程序读取全国省市经纬度坐标,然后根据经纬度坐标进...

Radon变换理论介绍与matlab实现--经验交流

本人最近在研究Radon变换,在查阅了各种资料之后在此写下个人的理解,希望与各位牛牛进行交流共同进步,也使得理解更加深刻些。 Radon变换的本质是将原来的函数做了一个空间转换,即,将原来的XY平...

CT图像重建技术

由于csdn贴图不方便,并且不能上传附件,我把原文上传到了资源空间CT图像重建技术 1.引言 计算机层析成像(Computed Tomography,CT)是通过对物体进行不同角度的射线投影测量而...

Matlab绘图-很详细,很全面

Matlab绘图强大的绘图功能是Matlab的特点之一,Matlab提供了一系列的绘图函数,用户不需要过多的考虑绘图的细节,只需要给出一些基本参数就能得到所需图形,这类函数称为高层绘图函数。此外,Ma...

linux查找目录下的所有文件中是否含有某个字符串

查找目录下的所有文件中是否含有某个字符串  find .|xargs grep -ri "IBM"  查找目录下的所有文件中是否含有某个字符串,并且只打印出文件名  find .|xargs g...

Radon变换入门matlab CT原理

http://hi.baidu.com/hi9394/blog/item/0d492b8bfd714700c8fc7aa9.html 简介 图像投影,就是说将图像在某一方向上做线性积分(或理解为累...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:计算机图形学课程总结
举报原因:
原因补充:

(最多只允许输入30个字)