基本的十字绣线性生成中提供了判断下一步可以画的位置并且逐步生成的函数。以这些基本函数为基础,可以进行更多变化的图案设计。

为了方便的扩展,可以把线性生成写成一个类,以后的修改继承这个类。

头文件BasicBoard.h

//基本的生成函数,有run和mutiRun两种运行方式。
//run会按照朝着四个方向延伸且不和其他已有图案碰撞的方式生成图像。生成到没有可以画的点就停止
//mutiRun则是在run的基础上,在可以找到新的起点的时候继续画图,直到没有起点 #include <iostream>
#include <set>
#include <list>
#include <ctime>
#include <cstdlib>
#include <string>
#include <windows.h> #define ROW 51 //行数
#define COL 51 //列数
#define seedX ROW/2 //初始行号
#define seedY COL/2 //初始列号
#define random(x) (rand()%x) //随机数 using namespace std; struct point
{
int x;
int y;
};
struct compare //set的排序函数
{
bool operator()(const point &p1,const point &p2)const
{
//return p1.x * COL + p1.y < p2.x * COL + p2.y;
return p1.x==p2.x ? p1.y<p2.y: p1.x<p2.x;
}
}; class BasicBoard
{
public:
void run();//运行并画图
void run(int x, int y); //带种子参数的run
void mutiRun();//运行一次之后找新的起点继续运行,直到没有起点
void init();
void print();
void print(set<point,compare> pl);
bool isNext(int x, int y, char dir);
void findAndErase(point p, set<point,compare> &nextSet);
virtual void setNextSet(point seed, set<point,compare> &nextSet);
set<point,compare>::iterator getNextIter(set<point,compare> &nextSet);
virtual void drawNext(set<point,compare> &nextSet); virtual void generate(point &seed);
virtual bool getSeed(point &seed); //获取可以开始的位置,该位置周围8个格子均为空
void printAs();//输出
protected:
int b[ROW][COL];
};

实现文件BasicBoard.cpp

#include "BasicBoard.h"
void BasicBoard::run()
{
init();
point seed;
seed.x = seedX;
seed.y = seedY;
generate(seed);
printAs();
}
void BasicBoard::run(int x, int y)
{
init();
point seed;
seed.x = x;
seed.y = y;
generate(seed);
printAs();
}
void BasicBoard::mutiRun()
{
init();
point seed;
while(getSeed(seed))
{
generate(seed);
}
printAs();
}
void BasicBoard::init() //初始化,全部置0
{
for(int i=0;i<ROW;i++)
{
for(int j=0;j<COL;j++)
{
b[i][j]=0;
}
}
} void BasicBoard::print() //打印画布01序列
{
for(int i=0;i<ROW;i++)
{
for(int j=0;j<COL;j++)
{
cout<<b[i][j];
}
cout<<endl;
}
}
void BasicBoard::printAs() //以方块形式打印图案
{
string b2[ROW][COL];
int count = 0;
for(int i=0; i<ROW; i++)
{
for(int j=0; j<COL; j++)
{
if(b[i][j])
{
b2[i][j]="■";
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0xF1);
/*输出颜色说明。导入windows.h,使用SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0x71)。参数中的16进制数字第一位表示背景颜色,第二位表示文字颜色,代码含义为
0 = 黑色 8 = 灰色
1 = 蓝色 9 = 淡蓝色
2 = 绿色 A = 淡绿色
3 = 湖蓝色 B = 淡浅绿
4 = 红色 C = 淡红色
5 = 紫色 D = 淡紫色
6 = 黄色 E = 淡黄色
7 = 白色 F = 亮白色
如果背景为“白色”,会显示cmd默认的颜色
*/ count++;
}
else
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),0xF9);
b2[i][j]="□";
}
cout<<b2[i][j];
} cout<<count<<endl;
} }
void BasicBoard::print(set<point,compare> pl) //测试函数,打印set中的值
{
set<point,compare>::iterator iter = pl.begin();
for(; iter!=pl.end(); iter++)
{
cout<<iter->x<<","<<iter->y<<" - ";
}
cout<<endl;
} bool BasicBoard::isNext(int x, int y, char dir) //判断某个位置是不是可以画下一笔 {
if(0<x && ROW-1>x && 0<y && COL-1>y)
{
int temp = 0;
switch(dir)
{
case 'U':
{ temp = b[x-1][y-1]+b[x-1][y]+b[x-1][y+1]+b[x][y-1]+b[x][y]+b[x][y+1]; break;
}
case 'D':
{
temp = b[x][y-1]+b[x][y]+b[x][y+1]+b[x+1][y-1]+b[x+1][y]+b[x+1][y+1];
break;
}
case 'L':
{
temp = b[x-1][y-1]+b[x-1][y]+b[x][y-1]+b[x][y]+b[x+1][y-1]+b[x+1][y];
break;
}
case 'R':
{
temp = b[x-1][y]+b[x-1][y+1]+b[x][y]+b[x][y+1]+b[x+1][y]+b[x+1][y+1];
break;
}
}
if(temp==0)
return true;
}
return false;
}
void BasicBoard::findAndErase(point p, set<point,compare> &nextSet) //新添加点之后,删除候选列表中不能继续画的点
{
set<point,compare>::iterator iterErase;
iterErase = nextSet.find(p);
if(iterErase != nextSet.end())
{
nextSet.erase(iterErase);
}
}
void BasicBoard::setNextSet(point seed, set<point,compare> &nextSet) //设置候选列表
{
int x = seed.x;//x为行,y为列
int y = seed.y; point p;
p.x = x-1;
p.y = y;
if(isNext(x-1,y,'U'))
{
nextSet.insert(p);
}
else
{
findAndErase(p,nextSet);
}
p.x = x+1;
p.y = y;
if(isNext(x+1,y,'D'))
{ nextSet.insert(p);
}
else
{
findAndErase(p,nextSet);
}
p.x = x;
p.y = y-1;
if(isNext(x,y-1,'L'))
{
nextSet.insert(p);
}
else
{
findAndErase(p,nextSet);
}
p.x = x;
p.y = y+1;
if(isNext(x,y+1,'R'))
{
nextSet.insert(p);
}
else
{
findAndErase(p,nextSet);
}
p.x = x-1;
p.y = y-1;
findAndErase(p,nextSet); //角上相邻的
p.x = x+1;
p.y = y-1;
findAndErase(p,nextSet);
p.x = x-1;
p.y = y+1;
findAndErase(p,nextSet);
p.x = x+1;
p.y = y+1;
findAndErase(p,nextSet); } //通过随机数获取下一步的位置。种子在main中生成
set<point,compare>::iterator BasicBoard::getNextIter(set<point,compare> &nextSet)
{
int count = nextSet.size();
set<point,compare>::iterator iterNext = nextSet.begin();
int pos = int(random(count)); for(int i = 0; i<pos; i++)
{
iterNext++;
}
return iterNext;
}
//画下一格:从候选里面选出一个;更改b的值;判断它四个正方向的候选,如果是候选加入,不是候选尝试查找删除;判断它四个斜方向,从候选列表删除。
void BasicBoard::drawNext(set<point,compare> &nextSet)
{ set<point,compare>::iterator iterNext;
iterNext = getNextIter(nextSet);
point next;
next.x = iterNext->x;
next.y = iterNext->y;
b[next.x][next.y]=1;
nextSet.erase(iterNext);
setNextSet(next, nextSet);
} void BasicBoard::generate(point &seed)
{
b[seed.x][seed.y]=1;
set<point,compare> nextSet; setNextSet(seed,nextSet);
while(!nextSet.empty())
{
drawNext(nextSet);
}
} //生成新的种子。方法是找到所有可以做种子的点然后随机选一个。
bool BasicBoard::getSeed(point &seed)
{ list<point> seedList;
int count = 0;
for(int x = 1; x<ROW-1; x++)
{
for(int y = 1; y<COL-1; y++)
{
if(b[x-1][y-1]+b[x-1][y]+b[x-1][y+1]+b[x][y-1]+b[x][y]+b[x][y+1]+b[x+1][y-1]+b[x+1][y]+b[x+1][y+1]==0)
{
seed.x = x;
seed.y = y;
seedList.push_back(seed);
count++;
}
}
}
if(count==0)
{ return false;}
list<point>::iterator iter = seedList.begin();
int pos = int(random(count)); for(int i = 0; i<pos; i++)
{
iter++;
}
seed.x = iter->x;
seed.y = iter->y;
return true;
}

main函数

#include "BasicBoard.h"

void main()
{
srand(unsigned(time(0)));
BasicBoard b;
b.run();
}

C++生成十字绣图案(二) 面向对象的更多相关文章

  1. 2018-2019-2 20175306实验二面向对象程序设计《Java开发环境的熟悉》实验报告

    2018-2019-2 20175306实验二面向对象程序设计<Java开发环境的熟悉>实验报告 面向对象程序设计-1 实验要求: 参考:> http://www.cnblogs.c ...

  2. 2018-2019-20175205实验二面向对象程序设计《Java开发环境的熟悉》实验报告

    2018-2019-20175205实验二面向对象程序设计<Java开发环境的熟悉>实验报告 实验要求 没有Linux基础的同学建议先学习<Linux基础入门(新版)>< ...

  3. 20175212童皓桢 Java实验二-面向对象程序设计实验报告

    20175212童皓桢 Java实验二-面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设 ...

  4. #2019-2020-4 实验二面向对象程序设计《Java开发环境的熟悉》实验报告

    2019-2020-4 实验二面向对象程序设计<Java开发环境的熟悉>实验报告 一.面向对象程序设计-1 ①实验要求: 1.参考 http://www.cnblogs.com/roced ...

  5. 20165317JAVA实验二-面向对象程序设计

    JAVA实验二-面向对象程序设计 提交点一 参考Intellj IDEA 简易教程-单元测试完成单元测试的学习 在IDEA中建立名为MyUtil5317的project,并在其src文件夹中创建名为M ...

  6. Java生成与解析二维码

    1.下载支持二维码的jar包qrcode.jar和qrcode_swetake.jar, 其中qrcode_swetake.jar用于生成二维码,rcode.jar用于解析二维码,jar包下载地址(免 ...

  7. asp.net.web如何简单生成和保存二维码图片的例子

    首先,要有生成二维码图片,需要二维码生成的类库,到官网下载thoughtWorks.QRCode.dll 例子的步骤: 1.创建项目QRCodeTest1,选择asp.net.web窗体应用程序

  8. python实现树莓派生成并识别二维码

    python实现树莓派生成并识别二维码 参考来源:http://blog.csdn.net/Burgess_Liu/article/details/40397803 设备及环境 树莓派2代 官方系统R ...

  9. ZXing 生成、解析二维码图片的小示例

    概述 ZXing 是一个开源 Java 类库用于解析多种格式的 1D/2D 条形码.目标是能够对QR编码.Data Matrix.UPC的1D条形码进行解码. 其提供了多种平台下的客户端包括:J2ME ...

随机推荐

  1. Nodejs线上日志部署

    Nodejs 被越来越多的使用到线上系统中,但线上系统没有日志怎么行呢. 一.forever记录日志 我的线上系统使用forever来启动服务,最开始就直接使用了forever来记录 forever ...

  2. CDOJ 42/BZOJ 2753 滑雪与时间胶囊 kruskal

    2753: [SCOI2012]滑雪与时间胶囊 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 1376  Solved: 487[Submit][St ...

  3. 简单的文件上传html+ashx

    前台页面:<form action="upload.ashx" method="post" enctype="multipart/form-da ...

  4. HDU 4727 The Number Off of FFF (水题)

    The Number Off of FFF Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  5. Android 手机 无线 ADB

    要用网络调试Android需要设备已经获取root权限 如果手机没有命令行工具,请先在手机端安装终端模拟器,然后在终端输入: $su #stop adbd #setprop service.adb.t ...

  6. HTML5 vs FLASH vs SILVERLIGHT

    Introduction HTML5 kills off flash; HTML5 kills off Silverlight; HTML5 makes the dinner and does the ...

  7. DevExpress Components16.2.6 Source Code 编译

    DevExpress 是一个比较有名的界面控件套件,提供了一系列优秀的界面控件.这篇文章将展示如何在拥有源代码的情况下,对 DevExpress 的程序集进行重新编译. 特别提示:重编译后,已安装好的 ...

  8. easyui-datetimebox设置默认时分秒00:00:00

    datetimebox默认打开面板显示的是当前的时间,有个需求就是当打开面板时显示固定的”00:00:00”时间, 它本身有个方法spinner方法可以获得时间微调器对象,它所依赖的组件combo有个 ...

  9. 使用Jenkins和Jmeter搭建性能测试平台

    参考文档:http://blog.csdn.net/liuchunming033/article/details/52186157 jenkins的性能测试结果展现插件:https://wiki.je ...

  10. 【BZOJ】【1089】【SCOI2003】严格n元树

    高精度/递推 Orz Hzwer…… 然而我想多了…… 理解以后感觉黄学长的递推好精妙啊 顺便学到了一份高精度的板子= =233 引用下题解: f[i]=f[i-1]^n+1 ans=f[d]-f[d ...