头歌实践教学平台:CG1-v2.0-直线绘制

第4关:直线光栅化-任意斜率的Bresenham画线算法

一.任务描述

1.本关任务

(1)根据直线Bresenham算法补全line函数以绘制白色直线,其中直线斜率为任意情况。 (2)当直线方程恰好经过P(x,y)和T(x,y+1)的中点M时,统一选取直线上方的T点为显示的像素点。

2.输入

代码将自动输入一个OBJ三维人头模型,具体模型如下图:

3.输出

若编写的任意斜率的Bresenham画线算法代码正确,则程序会将模型转换为线条图片,具体结果如下图所示:

二.相关知识

1.绘制点函数

image.set(x, y, color)函数是绘制点的函数,参数包括x、y和color。参数x为绘制点的x坐标,参数y为绘制点的y坐标,参数color为绘制点的颜色。

2.Bresenham算法

Bresenham算法相关知识点,请参考教材与课件或有关资料。

三.操作说明

(1)按要求补全line函数; (2)点击窗口右下角"测评"按钮,等待测评结果,如果通过后可进行下一关任务。


开始你的任务吧,祝你成功!

四、实验代码

复制代码
#include "tgaimage.h"
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include "model.h"
#include "geometry.h"

const TGAColor white = TGAColor(255, 255, 255, 255);
const TGAColor red = TGAColor(255, 0, 0, 255);
Model *model = NULL;
const int width = 800;
const int height = 800;

void line(int x0, int y0, int x1, int y1, TGAImage& image, TGAColor color)
{
    // Please add the code here
    /********** Begin ********/
    bool steep = false;
    if (abs(x0 - x1) < abs(y0 - y1))//k>1情况,如果正确就做对称变换
    {
        std::swap(x0, y0);
        std::swap(x1, y1);
        steep = true;
    }
    if (x0 > x1)//如果x0大于x1,就交换坐标
    {
        std::swap(x0, x1);
        std::swap(y0, y1);
    }
    int dx = x1 - x0;
    int dy = abs(y1 - y0);
    int y = y0;
    int d = -dx;
    for (int x = x0; x <= x1; x++)
    {
        if (steep)
            image.set(y, x, color);//k>1情况,如果正确就做对称变换,即x和y交换
        else
            image.set(x, y, color);
        d = d + 2 * dy;
        if (d >= 0)
        {
            y += (y1 > y0 ? 1 : -1);
            d = d - 2 * dx;
        }
    }
    /********** End *********/
}

int main(int argc, char** argv)
{
	model = new Model("african_head.obj");
	TGAImage image(width, height, TGAImage::RGB);
	for (int i = 0; i < model->nfaces(); i++) {
		std::vector<int> face = model->face(i);
		for (int j = 0; j < 3; j++) {
			Vec3f v0 = model->vert(face[j]);
			Vec3f v1 = model->vert(face[(j + 1) % 3]);
			int x0 = (v0.x + 1.)*width / 2.;
			int y0 = (v0.y + 1.)*height / 2.;
			int x1 = (v1.x + 1.)*width / 2.;
			int y1 = (v1.y + 1.)*height / 2.;
			line(x0, y0, x1, y1, image, white);
		}
	}
	image.flip_vertically(); // i want to have the origin at the left bottom corner of the image
	image.write_tga_file("../img_step3/test.tga");
	delete model;
	return 0;
}
相关推荐
壕壕6 天前
Re: 0x03. 从零开始的光线追踪实现-多球体着色
macos·计算机图形学
web像素之境12 天前
实时光线追踪加速硬件结构(详细版)
游戏·gpu·计算机图形学
唯道行22 天前
计算机图形学·9 几何学
人工智能·线性代数·计算机视觉·矩阵·几何学·计算机图形学
唯道行25 天前
计算机图形学·6 OpenGL编程3 谢尔宾斯基垫与三维编程
人工智能·算法·计算机视觉·计算机图形学·三维·谢尔宾斯基垫
charlie1145141911 个月前
2D 计算机图形学基础速建——2
笔记·学习·线性代数·教程·计算机图形学
charlie1145141911 个月前
2D 计算机图形学基础速建——1
笔记·学习·教程·计算机图形学·基础
ObjectX前端实验室2 个月前
【图形编辑器架构】节点树与渲染树的双向绑定原理
前端·计算机图形学·图形学
ObjectX前端实验室2 个月前
【图形编辑器架构】渲染层篇 — 从 React 到 Canvas 的声明式渲染实现
前端·计算机图形学·图形学
ObjectX前端实验室2 个月前
【图形编辑器架构】节点树篇 — 从零构建你的编辑器数据中枢
前端·计算机图形学·图形学
壕壕2 个月前
Re: 0x02. 从零开始的光线追踪实现-射线跟球的相交
macos·计算机图形学