本文实例为大家分享了C++实现基于EASYX库扫描线算法的具体代码,供大家参考,具体内容如下
扫描线算法的基本原理
* 作者在扫描线算法的基础上自己设计的更易于理解的地物填充绘制算法
流程图
代码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236#include<graphics.h> //#include<conio.h> #include<iostream> using namespace std; //-----------------------------草图形-----------------------------// void Grass(double x, double y, double hight, double width) { setlinecolor(GREEN); line(x, y, x - hight / 2, y - width); line(x, y, x, y - width); line(x, y, x + hight / 2, y - width); } //-----------------------------林图形-----------------------------// void Tree(double x, double y, double hight, double width) { setlinecolor(GREEN); line(x, y, x - hight / 2, y - width); line(x, y, x + hight / 2, y - width); line(x, y - width, x, y + width); } //------------------求解方程的k,b值---------------------// void function_line(double x1, double y1, double x2, double y2, double &k, double &b) { if (x2 - x1 == 0) { k = -9999; b = x1; return; } k = (y2 - y1) / (x2 - x1); b = y1 - k * x1; } //------------------返回直线的y----------------------// double solve_y(double k, double b, double x) { return k * x + b; } //------------------返回直线的x----------------------// double solve_x(double k, double b, double y) { if (k == -9999) return b; return (y - b) / k; } //-------------------找出扫描线与边界相交的点,并储存在suitable_x[]中,把相交的点数储存在n中--------------// //x[]-----------顶点x坐标 //y[]-----------顶点y坐标 //N-------------顶点的个数 //now_y---------当前的扫描线y //suitable_x[]--扫描线与边界相交的点的x坐标 //n-------------相交的点数 void Suitable_x(double x[], double y[],int N, double now_y, double suitable_x[], int &n) { n = 0; int t = 0; double k, b; for (int i = 0; i < N; i++) { if (i == N - 1) { if (y[i] < now_y&& now_y <= y[0] || y[0] < now_y&& now_y <= y[i])//判断直线是否过最后一条直线 { function_line(x[0], y[0], x[i], y[i], k, b); suitable_x[t++] = solve_x(k, b, now_y); } } else { if (y[i] < now_y&& now_y <= y[i + 1] || y[i + 1] < now_y&& now_y <= y[i]) //判断扫描线过哪条直线的范围 { function_line(x[i], y[i], x[i + 1], y[i + 1], k, b); suitable_x[t++] = solve_x(k, b, now_y);//把交点的x储存在suitable_x[]中 } } } n = t; } void sort_min_to_max(double suitable_x[],int n) //排序----从小到大排序 { double temp; for (int i = 0; i < n - 1; i++) { for (int j = i + 1; j < n; j++) { if (suitable_x[i] > suitable_x[j]) { double temp = suitable_x[i]; suitable_x[i] = suitable_x[j]; suitable_x[j] = temp; } } } } double find_max(double elem[],int N) //输出最大的元素值 { double max = elem[0]; for (int i = 0; i < N; i++) { if (elem[i] > max) { max = elem[i]; } } return max; } double find_min(double elem[],int N) //输出最小的元素值 { double min = elem[0]; for (int i = 0; i < N; i++) { if (elem[i] < min) { min = elem[i]; } } return min; } int main() { cout << "-----------------------------------------地物填充绘制算法--------------------------------------------nn"; cout << " 创建人:李景勃n"; cout << " 时间:2018年10月24日n"; cout << " 10月24日是全部程序员值得开心的节日,也是自己重要的日子,23号完成,祝福全部程序员们!!! nnn"; int N,ch; char color; double x[50],y[50]; cout << "输入填充的多边形的顶点数:"; cin >> N; cout << "依次输入地物的顶点坐标:"; for (int i = 0; i < N; i++) { cout << "输入第" << i+1 << "个顶点的坐标:" << endl; cout << "x,y:"; scanf_s("%lf,%lf",&x[i],&y[i]); /*cout << "x = "; cin >> x[i]; cout << "y = "; cin >> y[i];*/ } cout << "选择您填充的地物: 整个区域单颜色充填---请按0;草地---请按 1;林地---请按 2 ; "; cin >> ch; if (ch == 0) { cout << "请选择颜色:BLACK 黑,DARKGRAY 深灰绿色 BLUE 蓝 LIGHTBLUE 亮蓝:GREEN 绿 CYAN 青 RED 红 MAGENTA 紫 BROWN 棕 YELLOW 黄 LIGHTGRAY 浅灰---注意是大写的英文n "; cout << "如果想让颜色变亮请在颜色的前面加上LIGHT n"; cout << "请输入颜色:"; cin >> color; } initgraph(find_max(x, N)+100, find_max(y, N)+100); //int N = 9; //double x[50] = { 200,100,150,170,400,350,300,250,270 }; //double y[50] = { 200,300,400,250,350,300,250,100,270 }; double new_y[50] = { 0 }; int n = 0; double suitable_x[10]; //草的参数 int hight = 12, width = 6; int space = 4; //草之间的间隔 setbkcolor(WHITE); //设置背景色 cleardevice(); //用背景色填充屏幕 setlinecolor(BLACK); //多边形的线条颜色 for (int i = 0; i < N; i++) //逆时针顶点相连构成闭合多边形 { if (i == N - 1) { line(x[i], y[i], x[0], y[0]); } else { line(x[i], y[i], x[i + 1], y[i + 1]); } } double min_y = find_min(y,N), max_y = find_max(y,N); switch (ch) { case 0: //-------------------------像素填充面积-------------------------// for (int now_y = min_y; now_y <= max_y; now_y++) { Suitable_x(x, y, N, now_y, suitable_x, n); sort_min_to_max(suitable_x, n); //从小到大排序 for (int i = 0; i < n; i += 2) { for (int now_x = suitable_x[i]; now_x < suitable_x[i + 1]; now_x++)//确定在扫描线上,要填充的范围 { putpixel(now_x, now_y, color); } } } break; case 1: //-------------------------草填充-------------------------// for (int now_y = min_y + width + space; now_y <= max_y; now_y += width + space) { Suitable_x(x, y, N, now_y, suitable_x, n); sort_min_to_max(suitable_x, n); //从小到大排序 for (int i = 0; i < n; i += 2) { for (int now_x = suitable_x[i] + hight / 2 + space + space; now_x < suitable_x[i + 1] - hight / 2; now_x += hight + space)//确定在扫描线上,要填充的范围 { Grass(now_x, now_y, hight, width); Sleep(60); } } } break; case 2: //-------------------------树填充-------------------------// for (int now_y = min_y + width + space; now_y <= max_y; now_y += 2 * width + space) { Suitable_x(x, y, N, now_y, suitable_x, n); sort_min_to_max(suitable_x, n); //从小到大排序 for (int i = 0; i < n; i += 2) { double longth = suitable_x[i + 1] - suitable_x[i]-space; int num = longth / (hight+space); //double space_tmp = longth - num * (hight + space); //double space_ = space + space / num; for (int now_x = suitable_x[i] + hight / 2 +space+space; now_x < suitable_x[i + 1] - hight / 2&&num--; now_x += hight + space)//确定在扫描线上,要填充的范围 { Tree(now_x, now_y, hight, width); Sleep(60); } } } break; default: cout << "填充失败!!!" << endl; break; } //closegraph();//关闭画框 system("pause"); return 0; }
实现效果
谢谢阅读,欢迎来一起交流,一起学习!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。
最后
以上就是娇气星星最近收集整理的关于C++实现基于EASYX库扫描线算法的全部内容,更多相关C++实现基于EASYX库扫描线算法内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复