计算机图形学学习(一)——线的绘制、三角形填充绘制

以下摘抄自本人的计算机图形学上机报告

实验内容及要求:

  1. 理解并掌握中点画线法、Bresenham算法、扫描线法和重心坐标法的基本原理和算法步骤。
  2. 使用编程语言C++实现上述算法,并编写相应的代码。
  3. 对于直线绘制算法,要求能够绘制水平、垂直、斜向等不同方向的直线,并观察绘制结果是否符合预期。
  4. 对于三角形填充绘制算法,要求能够填充任意位置和大小的三角形,并观察填充结果是否完整且没有漏填或重填的情况。
  5. 编写实验报告,包括实验目的、实验原理、实验步骤、实验结果和实验总结等部分,对实验过程和结果进行详细的描述和分析。

算法思想

本次直线的绘制采用的是中点画线法

中点画线法的算法原理:

设为\mathrm{M}=\left(x_{i}+1, y_{i}+0.5\right) P1与P2之中点,Q为理想直线与 x=x_{​{i}}+1 垂线的交点。将Q与M的y坐标进行比较。当M在Q的下方,则P2应为下一个像素点;当M在Q的上方,则P1应为下一个像素点

三角形的绘制采用的是扫描线法重心坐标法

扫描线法的算法原理:

  1. 顶点排序首先,根据 y 坐标对三角形的三个顶点进行排序。确保 ta 是最下面的顶点,tc 是最上面的顶点,而 tb 则位于中间。
  2. 计算总高度:计算三角形在 y 轴上的总高度,即 tc.y - ta.y。
  3. 绘制底部条带:从 ta 到 tb 的 y 坐标范围内,循环遍历每一行(y 值)。对于每一行,计算 A 和 B 两个点的 x 坐标。这两个点位于当前行的扫描线上,并且与三角形的两边相交。然后,从 A 点到 B 点填充像素。如果 A 的 x 坐标大于 B 的 x 坐标,则交换 A 和 B,以确保填充的顺序是正确的。
  4. 绘制顶部条带:从 tb 到 tc 的 y 坐标范围内,重复与底部条带相同的步骤。

中心坐标法的算法原理:

1.确定边界

x_max 和 x_min 是三角形在x轴上的最大和最小坐标。

y_max 和 y_min 是三角形在y轴上的最大和最小坐标。

这些边界坐标用来确定需要遍历的像素范围。

2.遍历像素:

使用两个嵌套的 for 循环遍历从 y_min 到 y_max 的每一行,以及从 x_min 到 x_max 的每一列。

3.计算重心坐标:

对于每一个像素点 (x, y),计算其相对于三角形三个顶点的重心坐标 alpha 和 beta。

4.判断像素点是否在三角形内部:

如果 alpha, beta 和 1 - alpha - beta 都大于0,则说明像素点 (x, y) 位于三角形内部

5.绘制像素:

如果像素点 (x, y) 在三角形内部,则调用 draw_pixel 函数将其绘制为给定的颜色 color。

代码说明及实验结果

中点画线算法:

void draw_line(int x1, int y1, int x2, int y2, const TGAColor& color)
{int a, b, delta1, delta2, d, x, y;a = y1 - y2;b = x2 - x1;d = 2 * a + b;delta1 = 2 * a;delta2 = 2 * (a + b);x = x1;y = y1;draw_pixel(x, y, color);while (x < x2){if (d < 0){x++;y++;d += delta2;}else {x++;d += delta1;}draw_pixel(x, y, color);}}

扫描线算法:

void draw_triange2(vec2i ta, vec2i tb, vec2i tc, const TGAColor& color)
{if (ta.y > tb.y) std::swap(ta, tb);if (ta.y > tc.y) std::swap(ta, tc);if (tb.y > tc.y) std::swap(tb, tc);int total_height = tc.y - ta.y;for (int y = ta.y; y < tb.y; ++y) {int segment_height = tb.y - ta.y;float alpha = (float)(y - ta.y) / total_height;float beta = (float)(y - ta.y) / segment_height;vec2i A = ta + (tc - ta) * alpha;vec2i B = ta + (tb - ta) * beta;if (A.x > B.x) std::swap(A, B);for (int j = A.x; j <= B.x; ++j) {draw_pixel(j, y, color);}}for (int y = tb.y; y <= tc.y; ++y) {int segment_height = tc.y - tb.y;float alpha = (float)(y - ta.y) / total_height;float beta = (float)(y - tb.y) / segment_height;vec2i A = ta + (tc - ta) * alpha;vec2i B = tb + (tc - tb) * beta;if (A.x > B.x) std::swap(A, B);for (int j = A.x; j <= B.x; ++j) {draw_pixel(j, y, color);}}
}

重心坐标算法:

void draw_triange1(vec2i ta, vec2i tb, vec2i tc, const TGAColor& color)
{float x,y,alpha, beta;int x_max = max(ta.x, max(tb.x, tc.x));int x_min = min(ta.x, min(tb.x, tc.x));int y_max = max(ta.y, max(tb.y, tc.y));int y_min = min(ta.y, min(tb.y, tc.y));for (y = y_min; y <= y_max; y++) {for (x = x_min; x <= x_max; x++){alpha = (-(x - tb.x) * (tc.y - tb.y) + (y - tb.y) * (tc.x - tb.x)) / (-(ta.x - tb.x) * (tc.y - tb.y) + (ta.y - tb.y) * (tc.x - tb.x));beta = (-(x - tc.x) * (ta.y - tc.y) + (y - tc.y) * (ta.x - tc.x)) / (-(tb.x - tc.x) * (ta.y - tc.y) + (tb.y - tc. y) * (ta.x - tc.x));if (alpha > 0 && beta >0 && 1 - alpha - beta >0){draw_pixel(x, y, color);}}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/747324.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【消息队列开发】 实现内存加载

文章目录 &#x1f343;前言&#x1f333;实现思路&#x1f6a9;读取消息长度&#x1f6a9;读取相应长度的消息&#x1f6a9;进行反序列化&#x1f6a9;判定是否有效&#x1f6a9;加入有效消息&#x1f6a9;收尾工作&#x1f6a9;代码实现 ⭕总结 &#x1f343;前言 本次开发目…

未解决的问题:字符数组中元素的个数

情形1&#xff1a; #include<stdio.h> int main() {int arr_int1[10];int arr_int2[]{1,2,3,4,5};char arr_char1[10];char arr_char2[]"world";char arr_char3[]{h,e,l,l,o};int i;i0;while(arr_char2[i]!\0){i;}printf("%d\n",i);i0;while(arr_ch…

lwip优化任务优先级

在lwIP中&#xff0c;ethernetif_input线程负责接收和处理从以太网接口接收到的数据包&#xff0c;而tcpip主线程则负责处理lwIP协议栈中的各种事件和数据包。一般情况下&#xff0c;ethernetif_input线程的优先级应该设置为低于tcpip主线程的优先级。 这是因为在实时操作系统…

HarmonyOS ArkUI入门—HarmonyOS ArkUI来开发一个健康饮食应用

本文演示如果在DevEco Studio 3里面&#xff0c;用HarmonyOS的ArkUI来开发一个健康饮食应用。体验HarmonyOS 3最新API 9&#xff01; 获取HarmonyOS应用 HarmonyOS的ArkUI来开发一个健康饮食的ArkUI程序“ArkUIHealthyDiet”&#xff0c;基础代码已经有了[1]&#xff0c;个人…

20 OpenCV像素重映

文章目录 像素重映remap 重映算子代码示例 像素重映 简单点说就是把输入图像中各个像素按照一定的规则映射到另外一张图像的对应位置上去&#xff0c;形成一张新的图像。 g(x,y)是重映射之后的图像&#xff0c;h(x,y)是功能函数&#xff0c;f是源图像 remap 重映算子 Remap…

Java项目:52 springboot基于SpringBoot的旅游网站的设计与实现013

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 旅游网站主要功能如下&#xff1a; 1.用户管理&#xff1a;注册、登录、退出、修改密码&#xff1b; 2.分类显示&#xff1a;显示旅游路线的分类&am…

MD5算法:密码学中的传奇

title: MD5算法&#xff1a;密码学中的传奇 date: 2024/3/15 20:08:07 updated: 2024/3/15 20:08:07 tags: MD5起源算法原理安全分析优缺点比较技术改进示例代码应用趋势 MD5算法起源&#xff1a; MD5&#xff08;Message Digest Algorithm 5&#xff09;算法是由MIT的计算机…

OpenHarmony教程指南—ArkTS时钟

简单时钟 介绍 本示例通过使用ohos.display 接口以及Canvas组件来实现一个简单的时钟应用。 效果预览 使用说明 1.界面通过setInterval实现周期性实时刷新时间&#xff0c;使用Canvas绘制时钟&#xff0c;指针旋转角度通过计算得出。 例如&#xff1a;"2 * Math.PI /…

Python QT 之PySide6简单入门

目录 1.开发环境配置 1.1 下载PySide6 2.2 配置pycharm相关快捷方式 PySide6_Designer - QT Designer 设计UI PySide6_UIC - 将QT Designer生成的UI文件转换为python文件 PySide6_RCC - 将RCC文件转换为python文件 2.第一个开发实例 2.1 QT desiger设计界面 2.2 将ui文…

一篇普通的生活周记

学习进度汇报&#xff1a; 这周主要是参考着视频敲完了一个vue2后台项目&#xff0c;主要是vue2element-ui,因为之前写项目的时候用过lay-ui&#xff0c;虽然是结合着node.js写的&#xff0c;但是大差不差&#xff0c;所以上手也很快。同时&#xff0c;学长发给我们了ruoyi项目…

关于如何重燃学习的激情

3月1日是我回学校的第一天。经历了长达8个月在家的昏暗时刻&#xff0c;我这10天的感觉和在家的感觉发生了翻天覆地的变化&#xff0c;最明显的莫过于学习状态的改变。 倒不是说在家学的不好&#xff0c;而是说在学校&#xff0c;我对学习的整体感觉&#xff0c;以及专注程度&…

【Leetcode每日一题】 递归 - 反转链表(难度⭐)(35)

1. 题目解析 题目链接&#xff1a;206. 反转链表 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 一、递归函数的核心任务 递归函数的主要职责是接受一个链表的头指针&#xff0c;并返回该链表逆序后的新头结点。递归…

【LeetCode热题100】160. 相交链表(链表)

一.题目要求 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数…

获取淘宝商品详情API数据指南(item_get-获得淘宝商品详情)

获取淘宝商品详情API数据是一个复杂的过程&#xff0c;涉及到多个步骤和可能的权限问题。以下是一个基本的指南&#xff0c;帮助你了解如何使用item_get接口获取淘宝商品详情。 1. 注册淘宝开放平台账号 首先&#xff0c;你需要在淘宝开放平台注册一个账号。这是获取API权限和…

稀碎从零算法笔记Day18-LeetCode:移除链表元素

前言&#xff1a;接近20day的时间&#xff0c;终于来到了链表。 题型&#xff1a;指针、链表 链接&#xff1a;203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你…

使用 Docker Compose 快速搭建监控网站 uptime-kuma

有时候需要监控自己搭建的一些网站、服务是否正常运行&#xff0c; 这时候可以考虑使用一个监控网站&#xff0c; 定时的进行检测&#xff0c; 记录网站、服务的运行状态&#xff0c; 在这推荐使用 uptime-kuma。 博主博客 https://blog.uso6.comhttps://blog.csdn.net/dxk539…

精读《精通 console.log》

1 引言 本周精读的文章是 Mastering JS console.log like a Pro&#xff0c;一起来更全面的认识 console 吧&#xff01; 2 概述 & 精读 console 的功能主要在于控制台打印&#xff0c;它可以打印任何字符、对象、甚至 DOM 元素和系统信息&#xff0c;下面一一介绍。 c…

【机器学习】机器学习创建算法第2篇:K-近邻算法【附代码文档】

机器学习&#xff08;算法篇&#xff09;完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;机器学习算法课程定位、目标&#xff0c;K-近邻算法&#xff0c;1.1 K-近邻算法简介&#xff0c;1.2 k近邻算法api初步使用定位,目标,学习目标,1 什么是K-近邻算法,…

Docker-数据卷、网络、dockerfile、挂载

目录 一、数据卷 二、MySQL数据 三、具名和匿名挂载 1、匿名挂载 2、具名挂载 3、指定挂载 四、Dockerfile 1、数据卷容器 2、dockerfile构建步骤 五、数据卷容器 1、实现多个容器之间数据共享 2、多个mysql之间共享数据库 六、Docker网络 1、Docker0 1、查看容器…

一些不重要的概念

QPS&#xff1a;Queries Per Second是衡量信息检索系统&#xff08;例如搜索引擎或数据库&#xff09;在一秒钟内接收到的搜索流量的一种常见度量。该术语在任何请求-响应系统中都得到更广泛的使用&#xff0c;更正确地称为每秒请求数&#xff08;RPS&#xff1a;Request Per S…