计算机图形学课程总结

原创 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();
}
版权声明: 举报

相关文章推荐

清华大学计算机图形学课程

教学大纲 课堂讲授的主要的知识点: 第一章 图形学简介 1.1 计算机图形学的研究内容 1.2 发展的历史回顾 1.3 应用及研究前沿 1...

【计算机图形学课程】一.MFC基本绘图函数使用方法

这是最近我《计算机图形学》课程实践编程课介绍的相关知识,主要是想通过MFC C++绘图,让学生体会下图形学相关的编程及简单的图形绘制,同时非常佩服学生的想象力,他们做得真的不错。希望这篇基础文章对你有...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

【计算机图形学课程】二.MFC鼠标响应函数模拟画图软件

上一篇文章我们讲述MFC绘制图形的基本函数,包括绘制直线、绘制矩形、绘制椭圆及绘制文字,同时通过绕圆旋转和矩形平移简单的理解了图形学知识。这篇文章我将介绍鼠标响应和键盘响应,通过这些事件让学生实现一个...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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