光栅扫描图像显示的简单编程实现

    大家知道CRT图像显示器吗?其实它就是人们常说的光栅扫描的图像显示器,今天yogurt就来跟大家分享一下光栅扫描器显示图案的编程实现方法。哇,听起来是不是好高大上啊!在yogurt的老师在课堂上讲了这个方法之前,yogurt也觉得这是一个十分有技术含量的存在!好像很复杂的样子!不过,当yogurt认真听完课并编程实现之后,觉得其实也就是数学计算而已,也不过如此嘛~~(让yogurt小傲娇一下,嘿嘿嘿)

    首先我们来介绍一下光栅扫描吧~~

=================================yogurt的小课堂开课啦=====================================

    首先是光栅图像,也就是通过一个一个的像素来显示的图像,因为像素是方方正正的一个单位量,所以当对图像进行放大显示时会存在走样现象,就像我们平时把一幅图像不断地放大到一定程度之后,眼里看到的就是马赛克了一样。因此,无论是用像素来表示直线还是表示圆,它们在光栅中只能用离散的小方块组合来表示,所以都会存在一定的走样!(锯齿状或者阶梯状)

    在光栅扫描系统中,电子束依照固定的扫描线和规定的扫描顺序(一般是横向扫描屏幕,一次一行,从上到下的顺序)进行扫描。即电子束先从荧光屏左上角开始,向右扫一条水平线,然后回扫到下一排的左边,再扫第二条水平线,就这样一直扫啊扫,直到扫完最后一排为止。在电子束横向沿每一行移动的过程中,电子束的强度会通过不断变化来建立亮点的图案。(其实还有垂直回扫、逐行扫描和隔行扫描的扫描系统哦,不要以为只可以水平回扫)

==========================嗷,其实百度百科比Yogurt的介绍更好一些,(⊙﹏⊙)==========================

    果然直接放代码的部分还是yogurt最喜欢的部分!终于体会到了当yogurt追着别人问十万个为什么时,别人那“只可意会不可言传”的心情了,讲名词解释还是度娘牛13!

    接下来的代码,可能需要大家先了解一下中点Bresenham算法(用来画直线和1/8部分的圆弧)以及八分法(对圆弧剩余部分的画法),具体的还是见代码吧!

  1 // 光栅化.cpp : 定义控制台应用程序的入口点。
  2 //
  3 
  4 #include"stdafx.h"
  5 #include"Graph.h"
  6 
  7 typedef struct POINT
  8 {
  9     int x, y;
 10 }point;
 11 
 12 void DrawLine(point p1, point p2);
 13 void DrawCircle(int r);
 14 
 15 int _tmain(int argc, _TCHAR* argv[])
 16 {
 17     for (int i = -20; i<20; i++)
 18     {
 19         for (int j = -25; j<25; j++)    //把10*10当做一个像素
 20         {
 21             if ((i + j) % 2 == 0)
 22             for (int m = 0; m<10; m++)
 23             for (int n = 0; n<10; n++)
 24                 setPixel(j * 10 + n, i * 10 + m, RED);
 25             else
 26             for (int m = 0; m<10; m++)
 27             for (int n = 0; n<10; n++)
 28                 setPixel(j * 10 + n, i * 10 + m, WHITE);
 29         }
 30     }
 31 
 32     point p1, p2;
 33     printf("Please enter point one:");
 34     scanf("%d,%d", &(p1.x), &(p1.y));
 35     printf("Please enter point two:");
 36     scanf("%d,%d", &(p2.x), &(p2.y));
 37 
 38     DrawLine(p1, p2);
 39 
 40     int r;
 41     printf("Please enter the radio of a circle:");
 42     scanf("%d", &r);
 43 
 44     DrawCircle(r);
 45 
 46     return 0;
 47 }
 48 
 49 void DrawLine(point p1,point p2)
 50 {
 51     int x, y, dx, dy, d, k;
 52 
 53     int x1 = p1.x, y1 = p1.y;
 54     int x2 = p2.x, y2 = p2.y;
 55 
 56     if (x1>x2)  //确保从左往右画(点1在左,点2在右)
 57     {
 58         int t = x1, w = y1;
 59         x1 = x2;
 60         y1 = y2;
 61         x2 = t;
 62         y2 = w;
 63     }
 64 
 65     dx = x2 - x1;
 66     dy = y2 - y1;
 67     k = dy / dx;
 68 
 69     //确保0<=k<=1
 70     if (k >= 0 && k <= 1)
 71     {
 72         x = x1;
 73         y = y1;
 74         dx = x2 - x1;
 75         dy = y2 - y1;
 76         d = dx - 2 * dy;
 77     }
 78     else if (k > 1)//做关于Y=X对称:(x,y)-->(y,x)
 79     {
 80         x = y1;
 81         y = x1;
 82         dx = y2 - y1;
 83         dy = x2 - x1;
 84         d = dx - 2 * dy;
 85         x2 = y2;  //判断终止的条件
 86     }
 87     else if (k < -1)//关于Y轴对称后还要再关于Y=X对称:(x,y)-->(-x,y)-->(y,-x)
 88     {
 89         x = y2;
 90         y = -x2;
 91         dx = y1 - y2;
 92         dy = x2 - x1;
 93         d = dx - 2 * dy;
 94         x2 = y1;  //判断终止的条件
 95     }
 96     else  //做关于Y轴的对称:(x,y)-->(-x,y)
 97     {
 98         x = -x2;
 99         y = y2;
100         dx = x2 - x1;
101         dy = y1 - y2;
102         d = dx - 2 * dy;
103         x2 = -x1;  //判断终止的条件
104     }
105 
106 
107     //终点bresenham算法画直线
108     do
109     {   //画点(x,y)
110         int i = x * 10, j = y * 10;   //坐标点(i,j)
111         for (int p = 0; p < 10; p++)  //
112         {
113             for (int q = 0; q < 10; q++)  //
114             {
115                 if (k >= 0 && k <= 1)
116                     setPixel(i + q, j + p, GREEN);
117                 else if (k>1)
118                     setPixel(j + p, i + q, GREEN);
119                 else if (k < -1)
120                     setPixel(-(j + p), i + q, GREEN);
121                 else
122                     setPixel(-(i + q), j + p, GREEN);
123             }
124         }
125         if (d < 0)  //取右上方的栅格
126         {
127             x += 1;
128             y += 1;
129             d += 2 * dx - 2 * dy;
130         }
131         else  //取正右方的栅格
132         {
133             x += 1;
134             d += -2 * dy;
135         }
136     } while (x <= x2);
137 
138 }
139 
140 void DrawCircle(int r)
141 {
142     int d, x, y;
143 
144     x = 0;
145     y = r;
146     d = 1 - r;
147 
148     do{
149         for (int m = 0; m < 10; m++)
150         for (int n = 0; n < 10; n++)
151         {
152             setPixel(x * 10 + m, y * 10 + n, GREEN);
153             setPixel(y * 10 + m, x * 10 + n, GREEN);
154             setPixel(y * 10 + m, -x * 10 + n, GREEN);
155             setPixel(x * 10 + m, -y * 10 + n, GREEN);
156             setPixel(-x * 10 + m, -y * 10 + n, GREEN);
157             setPixel(-y * 10 + m, -x * 10 + n, GREEN);
158             setPixel(-y * 10 + m, x * 10 + n, GREEN);
159             setPixel(-x * 10 + m, y * 10 + n, GREEN);
160         }
161 
162         if (d<0)  //在圆内,取正右方
163         {
164             d += 2 * x + 3;
165             x += 1;
166         }
167         else
168         {
169             d += 2 * (x - y) + 5;
170             x += 1;
171             y += -1;
172         }
173     } while (x<y);
174 
175     setPixel(x, y, GREEN);
176     setPixel(x, -y, GREEN);
177     setPixel(-x, y, GREEN);
178     setPixel(-x, -y, GREEN);
179 }
View Code

    接下来就是见证奇迹的时刻了!yogurt给大家画了一个小苹果,估计是yogurt自己饿了=.=。yogurt先在像素的基础上为大家画了一个红白相间的网格(一个格子10*10像素哦),可以看到即使超出网格部分还是和网格内每一格一样的大小,相信这样大家能够更加好的了解像素这个概念啦~\(≧▽≦)/~。好了,yogurt要去写作业了~~~~(>_<)~~~~哭!一大堆作业等着yogurt呢,生无可恋脸。。。

   

   

转载于:https://www.cnblogs.com/to-sunshine/p/6001759.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值