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

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

头文件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);  //带种子参数的runvoid 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. 20175212童皓桢 Java实验二-面向对象程序设计实验报告

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

  2. 【基础入门详解】程序员的二维码也要玩出不同色彩,用Python生成动态彩色二维码

    一.前言 常见的二维码为QR CodeCode,QR全称是Quick Response,是一个近几年来移动设备上超流行的一种编码方式.它的结构如下: 主要有以下特点: 符号规格从版本1(21×21)到 ...

  3. python画树叶-Python如何生成树形图案

    本文实例为大家分享了Python生成树形图案的具体代码,供大家参考,具体内容如下 先看一下效果,见下图. 上面这颗大树是使用Python + Tkinter绘制的,主要原理为使用分形画树干.树枝,最终 ...

  4. python生成动态二维码实例_python生成动态个性二维码(示例代码)

    1 安装工具 2 生成普通二维码 3 带图片的二维码 4 动态 GIF 二维码 5 在Python程序中使用 一.安装 首先在python环境下运行, 打开cmd进入python27 进入script ...

  5. 微信公众平台开发(83) 生成带参数二维码

    本文介绍在微信公众平台上如何使用高级接口开发生成带参数二维码的功能. 一.场景二维码 为了满足用户渠道推广分析的需要,公众平台提供了生成带参数二维码的接口.使用该接口可以获得多个带不同场景值的二维码, ...

  6. java生成和识别二维码

    全栈工程师开发手册 (作者:栾鹏) java教程全解 本文使用两种方式生成和识别二维码. 方法1:使用日本公司的qrcode 需要引入的包 qrcode_swetake.jar qrcode.jar ...

  7. 【微信小程序】接口生成自定义首页二维码

    1.背景 在原有小程序上开发了一个新的功能,需要整合首页.但是为了不影响原有业务,且能测试新功能.所以需要新生成一个二维码,用户扫描该二维码可以跳转到新功能的页面. 2.方法 2.1生成二维码的接口: ...

  8. 生成和扫描二维码(ZXing库)

    生成和扫描二维码(ZXing库) 一.ZXing概述 ZXing是谷歌自己推出的一个开源源码的二维码框架,可以实现使用手机的摄像头完成条形码的扫描和解码. 二.整合ZXing框架 将预先获取的core ...

  9. vue + 生成 下载 成 二维码

    二维码   <div class='box' v-for="(item,index) in this.num" :key="item.key "> ...

最新文章

  1. Structs2实现文件上传功能
  2. 零基础编程入门python视频-编程零基础应当如何开始学习 Python?
  3. 编程语言python特点-Python语言的特点有哪些?九大特点介绍!
  4. PAT甲题题解-1050. String Subtraction (20)-水题
  5. 云服务器的操作系统是什么,服务器操作系统是什么?云服务器的操作系统怎么选择...
  6. 宝塔LNMP使用步骤nginx+php 7.2
  7. Scala入门系列(十):函数式编程之集合操作
  8. 【转】如何理解NPV与IRR的区别??
  9. ARM-linux开发板网线连接电脑访问外网
  10. 关于信息学奥赛一本通(C++版)在线评测系统 1153 绝对素数
  11. 考研英语语法_Day03_名词性从句
  12. [生存志] 第145节 班固著汉书
  13. u盘格式化了怎么恢复数据
  14. nginx之allow、deny
  15. Broekett定理):
  16. centos8代理上网_centos设置代理上网
  17. 【无标题】元宇宙背后的安全隐患
  18. mysql8.0安装设置密码_mysql8.0.11安装配置方法图文教程 MySQL8.0新密码认证方式
  19. kubernetes test-infra
  20. SQL学习_常用语法2

热门文章

  1. domino 启动方式更改
  2. 基于ABB工业机器人的基本实训系统
  3. js 中文转成拼音字母 并A-Z排序 索引功能
  4. Web前端学习笔记——HTML5与CSS3之QQ TIM案例
  5. 【对讲机的那点事】公网集群对讲机在电力系统中的应用
  6. 高端时尚婚礼PPT模板
  7. 电路与电子3.3.4共射放大电路的阻抗与密勒效应
  8. 叉车安全的重要性不容忽视,浅谈叉车安全要求
  9. android手机上gmail的配置
  10. 风力发电控制系统的matlab,基于MATLAB的风机控制系统仿真