C++实现基于EASYX库扫描线算法

本文实例为大家分享了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;
}

实现效果

谢谢阅读,欢迎来一起交流,一起学习!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • OpenGL扫描线填充算法详解

    本文实例为大家分享了OpenGL扫描线填充算法,供大家参考,具体内容如下 说明 把最近一系列的图形学经典算法实现了一下.课业繁忙,关于该系列的推导随后再写.但是在注释里已经有较为充分的分析. 分情况讨论 注意对于横线需要特别讨论,但是对于垂直线却不必特别讨论.想一想为什么? 代码 #include <iostream> #include <GLUT/GLUT.h> #include <map> #include <vector> #include <l

  • python扫描线填充算法详解

    本文实例为大家分享了python扫描线填充算法,供大家参考,具体内容如下 介绍 1.用水平扫描线从上到下扫描由点线段构成的多段构成的多边形. 2.每根扫描线与多边形各边产生一系列交点.将这些交点按照x坐标进行分类,将分类后的交点成对取出,作为两个端点,以所填的色彩画水平直线. 3.多边形被扫描完毕后,填色也就完成. 数据结构 活性边表: 新边表: 代码(使用数组) import numpy as np from PIL import Image from PIL import ImageDraw

  • C++实现基于EASYX库扫描线算法

    本文实例为大家分享了C++实现基于EASYX库扫描线算法的具体代码,供大家参考,具体内容如下 扫描线算法的基本原理 * 作者在扫描线算法的基础上自己设计的更易于理解的地物填充绘制算法 流程图 代码 #include<graphics.h> //#include<conio.h> #include<iostream> using namespace std; //-----------------------------草图形-----------------------

  • C语言基于EasyX库实现有颜色弹跳小球

    本文实例为大家分享了基于EasyX库实现有颜色弹跳小球的具体代码,供大家参考,具体内容如下 1.目标要求 1.实现一个有颜色小球在窗口中弹跳2.遇到边界弹跳 2.C语言代码 #include<graphics.h>  #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<conio.h> #define High 480 #define Width 640//画布尺寸

  • C语言基于EasyX库实现有图形界面钟表

    本文实例为大家分享了C语言基于EasyX库实现有图形界面钟表的具体代码,供大家参考,具体内容如下 1.目标要求: 实现一个显示图像的时钟 2.C语言代码: #include<graphics.h> //需要提前下载EasyX库哦 #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<conio.h> #include<math.h> #define High

  • C语言基于EasyX库实现有图形界面时钟

    本文实例为大家分享了C语言基于EasyX库实现有图形界面时钟的具体代码,供大家参考,具体内容如下 1.目标要求: 1.实现一个显示图像的时钟2.时间与本地时间一致 2.C语言代码: #include<graphics.h> //需要提前安装库函数EasyX,网上官网下载 #include<stdio.h> #include<stdlib.h> #include<windows.h> #include<conio.h> #include<ma

  • C++基于EasyX库实现拼图小游戏

    用C++的EasyX库做的拼图小游戏,供大家参考,具体内容如下   记录一下自己做的第一个项目,还有一些改进空间QWQ,可以支持难度升级,但是通关判断似乎有点小问题肯定不是我菜通不了关 . #pragma once #include <iostream> #include <graphics.h> #include <Windows.h> #include <algorithm> #include <easyx.h> #include <c

  • C++使用easyX库实现三星环绕效果流程详解

    目录 1,项目描述 2,解决思路 3,关键代码 4,项目运行截图 5,具体代码实现 1,项目描述 功能1:使用图形化的方式描述地球围绕着太阳转动,月球围绕着地球转动 功能2:在转动的过程中当用户按下1,2,3,4,5,6,7时它可以变换出7种不同的颜色,当用户按下8时它可以变换从1-7的颜色依次变换当用户再次按下8键时停止变换颜色 功能3:当用户按下上键时,地球会围绕太阳反转,当再次按下上键时地球会恢复到正转 功能4:当用户按下空格键的时候,所有动画暂停,当再次按下空格键的时候所有动画继续进行.

  • 基于代数方程库Algebra.js解二元一次方程功能示例

    本文实例讲述了基于代数方程库Algebra.js解二元一次方程功能.分享给大家供大家参考,具体如下: 假设二元一次方程如下: x + y = 11 x - y = 5 解方程如下: <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" cont

  • PHP基于GD库实现的生成图片缩略图函数示例

    本文实例讲述了PHP基于GD库实现的生成图片缩略图函数.分享给大家供大家参考,具体如下: <?php /** * 生成缩略图函数(支持图片格式:gif.jpeg.png和bmp) * @author ruxing.li * @param string $src 源图片路径 * @param int $width 缩略图宽度(只指定高度时进行等比缩放) * @param int $width 缩略图高度(只指定宽度时进行等比缩放) * @param string $filename 保存路径(不指

  • Python基于identicon库创建类似Github上用的头像功能

    本文实例讲述了Python基于identicon库创建类似Github上用的头像功能.分享给大家供大家参考,具体如下: Identicon在很多大型IT网站上可以见到,比如Github,Sourceforge,Stackoveflow等等, 刚刚注册的账号的个人信息的默认图标​都​是​一​些​看​上​去​像​七​巧​板​拼​凑​的​图​案​,​对​称​又​变​化​多​端​. 本​人​也​是​因​为​好​奇​才​在​网​上​搜​了​这​个​算​法​,​主​要​是​哈​希​算​法​,​把​邮​箱​或

  • python基于pyDes库实现des加密的方法

    本文实例讲述了python基于pyDes库实现des加密的方法.分享给大家供大家参考,具体如下: 下载及简介地址:https://twhiteman.netfirms.com/des.html 如需要在python中使用des加密,可以直接使用pyDes库加密,该库提供了CBC和ECB两种加密方式. 1.Windows下安装 下载后pyDes-x.x.x.zip并解压后,里面有setup.py文件,使用命令 setup.py --help可查看详细使用. 你可以使用命令python setup.

随机推荐