计算机图形学DDA画线法+中点画线法+Bresenham画线法
#include <cstdio>
#include <cstring>
#include <conio.h>
#include <graphics.h>
void line1(){
line(100, 100, 200, 400);
line(100, 400, 200, 100);
line(0, 200, 300, 300);
line(0, 300, 300, 200);
} void lineDDA(int x0, int y0, int x1, int y1, int color){
int x;
float dy, dx, y, m;
dx = x1 - x0;
dy = y1 - y0;
m = dy / dx;
y = y0;
for (x = x0; x <= x1; x++){
putpixel(x, (int)(y + 0.5), color);
y += m;
}
} void lineDDA(){
lineDDA(100, 100, 200, 400, RED);
lineDDA(100, 400, 200, 100, RED);
lineDDA(0, 200, 300, 300, RED);
lineDDA(0, 300, 300, 200, RED);
} void lineMidPoint(int x0, int y0, int x1, int y1, int color){
int x = x0, y = y0;
int a = y0 - y1, b = x1 - x0;
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 != x1)
{
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 != y1)
{
if (d < 0)
d += d1;
else
x += cx, d += d2;
y += cy;
putpixel(x, y, color);
}
}
} void lineMidPoint(){
lineMidPoint(100, 100, 200, 400, GREEN);
lineMidPoint(100, 400, 200, 100, GREEN);
lineMidPoint(0, 200, 300, 300, GREEN);
lineMidPoint(0, 300, 300, 200, GREEN);
} void lineBresenham(int x0, int y0, int x1, int y1, int color)
{
int dx = x1 - x0;
int dy = y1 - y0;
int ux = dx >0 ? 1 : -1;//x伸展方向
int uy = dy >0 ? 1 : -1;//y伸展方向
int dx2 = dx << 1;//x偏移量乘2
int dy2 = dy << 1;//y偏移量乘2
if (abs(dx)>abs(dy))
{//以x为增量方向计算
int e = -dx; //e = -0.5 * 2 * dx,把e 用2 * dx* e替换
int x = x0;
int y = y0;//起点y坐标
for (x = x0; x < x1; x += ux)
{
putpixel(x, y, color);
e = e + dy2;//来自 2*e*dx= 2*e*dx + 2dy (原来是 e = e + k)
if (e > 0)//e是整数且大于0时表示要取右上的点(否则是右下的点)
{
y += uy;
e = e - dx2;//2*e*dx = 2*e*dx - 2*dx (原来是 e = e -1)
}
}
}
else
{//以y为增量方向计算
int e = -dy; //e = -0.5 * 2 * dy,把e 用2 * dy* e替换
int x = x0;
int y = y0;
for (y = y0; y < y1; y += uy)
{
putpixel(x, y, color);
e = e + dx2;//来自 2*e*dy= 2*e*dy + 2dy (原来是 e = e + k)
if (e > 0)//e是整数且大于0时表示要取右上的点(否则是右下的点)
{
x += ux;
e = e - dy2;//2*e*dy = 2*e*dy - 2*dy (原来是 e = e -1)
}
}
}
} void lineBresenham1(int x0, int y0, int x1, int y1, long color)
{
int dx = abs(x1 - x0);
int dy = abs(y1 - y0);
int x = x0;
int y = y0;
int stepX = 1;
int stepY = 1;
if (x0 > x1) //从右向左画
stepX = -1;
if (y0 > y1)
stepY = -1; if (dx > dy) //沿着最长的那个轴前进
{
int e = dy * 2 - dx;
for (int i = 0; i <= dx; i++)
{
putpixel(x, y, color);
x += stepX;
e += dy;
if (e >= 0)
{
y += stepY;
e -= dx;
}
}
}
else
{
int e = 2 * dx - dy;
for (int i = 0; i <= dy; i++)
{
putpixel(x, y, color);
y += stepY;
e += dx;
if (e >= 0)
{
x += stepX;
e -= dy;
}
}
}
} void lineBresenham(){
lineBresenham1(100, 100, 200, 400, YELLOW);
lineBresenham1(100, 400, 200, 100, YELLOW);
lineBresenham1(0, 200, 300, 300, YELLOW);
lineBresenham1(0, 300, 300, 200, YELLOW);
} void showWord(int code){
outtextxy(200, 30, "单击右键退出");
switch (code){
case 1://原画
outtextxy(200, 10, "easyX系统画线算法");
break;
case 2://DDA算法
outtextxy(200, 10, "DDA算法");
break;
case 3://中点画线算法
outtextxy(200, 10, "中点画线算法");
break;
case 4://Bresenham算法
outtextxy(200, 10, "Bresenham算法");
break;
default:
line1();
break;
}
} void drawLine(int code){
switch (code){
case 1://原画
line1();
break;
case 2://DDA算法
lineDDA();
break;
case 3://中点画线算法
lineMidPoint();
break;
case 4://Bresenham算法
lineBresenham();
break;
default:
line1();
break;
}
} void drawLine(int x0,int y0,int x1,int y1,int code){
showWord(code);
switch (code){
case 1://原画
line(x0,y0,x1,y1);
break;
case 2://DDA算法
lineDDA(x0, y0, x1, y1,WHITE);
break;
case 3://中点画线算法
lineMidPoint(x0, y0, x1, y1, WHITE);
break;
case 4://Bresenham算法
lineBresenham1(x0, y0, x1, y1, WHITE);
break;
default:
line1();
break;
}
} void showWORDXY(int x, int y, int showX, int showY,int flag){
char dintX[5] = { 0 };
char dintY[5] = { 0 };
_itoa_s(showX, dintX, 10);//把整数showX转成字符串dintX
_itoa_s(showY, dintY, 10);//把整数showY转成字符串dintY
char str1[100] = "第一个点的坐标:(";//此时数组没有定义长度 元素的个数应该为strlen +1 因为字符串末尾有 '\0'结束
char str2[100] = "第二个点的坐标:(";
if (flag == 1){
// _countof(dintX)能够获取到数组中元素的个数 含‘\0’
strcat_s(str1, strlen(str1) + strlen(dintX)+1, dintX);
strcat_s(str1, strlen(str1) + strlen(",")+1, ",");
strcat_s(str1, strlen(str1) + strlen(dintY)+1, dintY);
strcat_s(str1, strlen(str1) + strlen(")")+1, ")");
outtextxy(x, y, str1);
}
else if (flag == 2){
strcat_s(str2, strlen(str2) + strlen(dintX)+1, dintX);
strcat_s(str2, strlen(str2) + strlen(",")+1, ",");
strcat_s(str2, strlen(str2) + strlen(dintY)+1, dintY);
strcat_s(str2, strlen(str2) + strlen(")")+1, ")");
outtextxy(x, y, str2);
}
} //调用easyX
void easyX(int code){
initgraph(640, 480); //初始化
showWord(code);
MOUSEMSG m; // 定义鼠标消息
int n=0;//读取两个点
int exit = false;
int x0=0, y0=0,x1=0,y1=0;
while (n<2 && !exit)
{
m = GetMouseMsg();
switch (m.uMsg)
{
case WM_RBUTTONDOWN:
outtextxy(200, 300, "再次点击键退出");
exit = true;
break; // 按鼠标右键退出程序
}
while (m.uMsg != WM_LBUTTONDOWN){
m = GetMouseMsg();
switch (m.uMsg)
{
case WM_RBUTTONDOWN:
outtextxy(200, 300, "再次点击键退出");
exit = true;
break; // 按鼠标右键退出程序
} }
while (m.uMsg != WM_LBUTTONUP){
m = GetMouseMsg(); cleardevice();
showWord(code);
if (n == 0){
showWORDXY(200, 430, x0, y0,1);
x0 = m.x;
y0 = m.y;
}
else{
showWORDXY(200, 430, x0, y0, 1);
showWORDXY(200, 450, x1, y1, 2);
x1 = m.x;
y1 = m.y;
}
}
n++;
if (n == 2){
//画线
drawLine(x0, y0, x1, y1, code);
//重置
n = 0;
}
}
//_getch(); //等待用户操作
closegraph(); //关闭图形
} int main(){
int n = 1;
printf("请选择画线算法画线:\n");
printf("1.easyX系统画线函数.\n");
printf("2.DDA画线算法函数.\n");
printf("3.中点画线算法函数.\n");
printf("4.Bresenham画线算法函数.\n");
printf("0.退出.\n");
while (n != 0){
scanf_s("%d", &n);
if (n == 0){
exit(0);
}
easyX(n);
}
return 0;
}
效果图:
计算机图形学DDA画线法+中点画线法+Bresenham画线法的更多相关文章
- 计算机图形学之扫描转换直线-DDA,Bresenham,中点画线算法
1.DDA算法 DDA(Digital Differential Analyer):数字微分法 DDA算法思想:增量思想 公式推导: 效率:采用了浮点加法和浮点显示是需要取整 代码: void lin ...
- 扫描转换算法——DDA、中点画线画圆、椭圆
我的理解:在光栅图形学中,由于每一个点的表示都只能是整数值,所以光栅图形学实际只是对对实际图形的近似表示. 数值微分法(DDA):以下PPT截图来自北京化工大学李辉老师 代码实现: import ma ...
- 计算机图形学(二)输出图元_6_OpenGL曲线函数_2_中点画圆算法
中点画圆算法 如同光栅画线算法,我们在每一个步中以单位间隔取样并确定离指定圆近期的像素位置.对于给定半径r和屏幕中心(xc,yc),能够先使用算法计算圆心在坐标原点(0, 0)的圆的像素 ...
- Mathematics for Computer Graphics数学在计算机图形学中的应用 [转]
最近严重感觉到数学知识的不足! http://bbs.gameres.com/showthread.asp?threadid=10509 [译]Mathematics for Computer Gra ...
- 计算机图形学 opengl版本 第三版------胡事民 第四章 图形学中的向量工具
计算机图形学 opengl版本 第三版------胡事民 第四章 图形学中的向量工具 一 基础 1:向量分析和变换 两个工具 可以设计出各种几何对象 点和向量基于坐标系定义 拇指指向z轴正 ...
- 关于opengl中的矩阵平移,矩阵旋转,推导过程理解 OpenGL计算机图形学的一些必要矩阵运算知识
原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/12166896.html 为什么引入齐次坐标的变换矩阵可以表示平移呢? - Yu Mao的回答 ...
- 计算机图形学 opengl版本 第三版------胡事民 第三章更多的绘图工具
opengl 计算机图形学 第三版 第二部分 第三章更多的绘图工具 3.1 概述 第2章中 我们绘图使用的是屏幕窗口的基础坐标系 以像素为单位 屏幕坐标从左下角x从0延伸到scr ...
- 学习shader之前必须知道的东西之计算机图形学-渲染管线
引言 shader到底是干什么用的?shader的工作原理是什么? 其实当我们对这个问题还很懵懂的时候,就已经开始急不可耐的要四处搜寻有关shader的资料,恨不得立刻上手写一个出来.但看了一些资料甚 ...
- 学习shader之前必须知道的东西之计算机图形学(一)渲染管线
引言 shader到底是干什么用的?shader的工作原理是什么? 其实当我们对这个问题还很懵懂的时候,就已经开始急不可耐的要四处搜寻有关shader的资料,恨不得立刻上手写一个出来.但看了一些资料甚 ...
随机推荐
- java开发之随笔记录
1.java 保留两位小数 DecimalFormat df = new DecimalFormat("#.##"); System.out.println(df.format(1 ...
- [网页游戏开发]Morn简介及使用教程
网页游戏开发利器,morn系列教程之Morn简介及使用教程 网页游戏开发的一大部分工作是在和UI制作上,一个好的工具及框架能使开发事半功倍,Adobe自带flash IDE和Flex各有不足. Mor ...
- c# vs2010 连接access数据库
第一次在博客园写博文,由于文采不怎么好,即使是自己很熟悉的东西,写起来也会感觉到不知从何讲起,我想写的多了就好了. 这篇文章主要是介绍怎么用c# 语言 vs2010连接access数据库的,连接字符串 ...
- React深入源码--了解Redux用法之Provider
在Redux中最核心的自然是组件,以及组件相关的事件与数据流方式.但是我们在Redux中并没有采用传统的方式在getInitialState()中去初始化数据,而是采用Provider统一处理,省去了 ...
- 剑指Offer:树的子结构【26】
剑指Offer:树的子结构[26] 题目描述 输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 解题思路 分为两步: 第一步:在树A中找到和树B的根节点的值一 ...
- Vue.js的动态组件模板
组件并不总是具有相同的结构.有时需要管理许多不同的状态.异步执行此操作会很有帮助. 实例: 组件模板某些网页中用于多个位置,例如通知,注释和附件.让我们来一起看一下评论,看一下我表达的意思是什么.评论 ...
- Android中点击事件的处理解析及常见问题
当我们手指按下时,Android采用层层传递-冒泡的方式处理点击事件.例如,现在公司来了个小项目,老板一看分配给经理做,经理一看分配给小组长,小组长一看好简单,分配给组员.如果在这个传递过 ...
- hdu1015 Safecracker —— 回溯
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1015 代码1: #include<stdio.h>//hdu1015 #include&l ...
- PICT实现组合测试用例
成功安装后,在命令行中输入命令pict: 可以看到pict命令的一些选项: /o:N 组合数,默认值为2,即pict生成的测试用例集中每条测试数据会有两个值与其他测试集是不同的: /d:C 值 ...
- Partition算法及Partition算法用于快速排序
JavaScript简单方便,所以用JavaScript实现,可以在Chrome控制台下观察运行结果.主要实现Partition算法,比如输入为 var array = [4, 2, 1, 3, ...