本文實例為大家分享了C++實現基于EASYX庫掃描線算法的具體代碼,供大家參考,具體內容如下
掃描線算法的基本原理

* 作者在掃描線算法的基礎上自己設計的更易于理解的地物填充繪制算法
流程圖

代碼
#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 << "-----------------------------------------地物填充繪制算法--------------------------------------------\n\n";
cout << " 創建人:李景勃\n";
cout << " 時間:2018年10月24日\n";
cout << " 10月24日是全部程序員值得開心的節日,也是自己重要的日子,23號完成,祝福全部程序員們?。?! \n\n\n";
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;
}
實現效果




謝謝閱讀,歡迎來一起交流,一起學習!
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。