我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C语言如何实现绘制绕线画

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C语言如何实现绘制绕线画

本篇内容介绍了“C语言如何实现绘制绕线画”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

绕线画简介

简单点来说,就是在木板上钉一圈钉子,通过绕线进行构图,最终呈现出一幅图像。

算法简介

可以总结概括一下,

首先需要有一张图,可以是彩色的,但是必须颜色比较分明。

对图像进行灰度处理。

随机生成 n 组数,就是每两个钉子的组合。

计算 n 组数据连线所过图像像素的平均数,求出最小的一组。

连接该组钉子,并对这条线经过的像素值分别加 m。

重复前面步骤 3 到步骤 5 直到绘制 z 条线结束循环。

示例代码

#include<graphics.h>#include<math.h>#include<conio.h>#include<time.h> // 以下数据可以自己调节#define PointNum 288    // 圆圈分的数量(一圈钉子的数量)#define LineNum 3000    // 循环绘制线的数量#define RandNum 120      // 设置每次随机生成连接的数量#define AddColor 52      // 增加的值 0 到 255 值越小越线越集中,越大越分散#define SIZE 800      // 图像大小 // 以下参数不用调节#define PI acos(-1.0)    // 圆周率#define R (SIZE / 2 - 10)    // 半径 struct PointS{  int p;  int x;  int y;}; struct LineS{  int StarP;        // 起点  int EndP;        // 终点}; PointS points[PointNum];LineS lines[RandNum]; // 为了判断两点是否连线定义的一维数组bool LineXY[(1 + PointNum) * PointNum / 2] = { false };bool Line_Rand[(1 + PointNum) * PointNum / 2] = { false }; // 两条线是否连接bool IsLineKed_Rand(int p1, int p2){  if (p1 >= p2)    return Line_Rand[(1 + p1) * p1 / 2 + p2];  else    return Line_Rand[(1 + p2) * p2 / 2 + p1];} // 储存已经绘制过的线void Link_Rand(int p1, int p2){  if (p1 >= p2)    Line_Rand[(1 + p1) * p1 / 2 + p2] = true;  else    Line_Rand[(1 + p2) * p2 / 2 + p1] = true;} // 将随机生成的进行初始化void Line2False(){  for (int i = 0; i < (1 + PointNum) * PointNum / 2; i++)  {    Line_Rand[i] = false;  }} // 判断这两个点是否连线bool IsLinked(int p1, int p2){  if (p1 >= p2)    return LineXY[(1 + p1) * p1 / 2 + p2];  else    return LineXY[(1 + p2) * p2 / 2 + p1];} // 储存已经绘制过的线void Link(int p1, int p2){  if (p1 >= p2)    LineXY[(1 + p1) * p1 / 2 + p2] = true;  else    LineXY[(1 + p2) * p2 / 2 + p1] = true;} int Round(float x);                // 取整void InitPoints();                // 初始化点void ColorToGray(IMAGE *pimg);          // 彩色图像转换为灰度图像void Random();                  // 产生随机数LineS Getline(IMAGE *pimg);            // 获取照片颜色void ToColor(IMAGE *oriPic, IMAGE *linePic);  // 给绕线图赋予颜色 int main(){  initgraph(SIZE, SIZE);  setbkcolor(WHITE);  cleardevice();  IMAGE imgpolt;                  // 加载原图  IMAGE oriPic;                  // 储存原图  IMAGE linePic;                  // 线图  loadimage(&imgpolt, _T("TG.jpeg"), SIZE, SIZE);  // 加载原图  oriPic = imgpolt;                // 原图  ColorToGray(&imgpolt);              // 将图片转换为灰度  InitPoints();                  // 初始化点  srand((unsigned)time(NULL));          // 生成随机种子   for (int i = 0; i < LineNum; i++)  {    Random();                  // 随机生成 80    LineS myline = Getline(&imgpolt);      // 计算 80 组点中平均值最小的    Link(myline.StarP, myline.EndP);      // 记录绘制过的线防止重复绘制    line(points[myline.StarP].x, points[myline.StarP].y, points[myline.EndP].x, points[myline.EndP].y);  }  _getch();   //   // saveimage(_T("test.png"));            // 保存一下绕线图  // loadimage(&linePic, _T("test.png"), SIZE, SIZE); // 重新加载绕线图  // ToColor(&oriPic, &linePic);            // 用原图将绕线图的颜色替换  // putimage(0, 0, &oriPic);  // _getch();  return 0;} // 初始化点(想创新可以生成椭圆的位置坐标)void InitPoints(){  for (int i = 0; i < PointNum; i++)  {    double a = i * PI * 2 / PointNum;    points[i].p = i;    points[i].x = int(SIZE / 2.0 + R * cos(a));    points[i].y = int(SIZE / 2.0 - R * sin(a));    setlinecolor(BLACK);    circle(points[i].x, points[i].y, 3);  }} // 彩色图像转换为灰度图像void ColorToGray(IMAGE *pimg){  DWORD *p = GetImageBuffer(pimg);  // 获取显示缓冲区指针  COLORREF c;  for (int i = pimg->getwidth() * pimg->getheight() - 1; i >= 0; i--)  {    c = BGR(p[i]);    c = (GetRValue(c) * 299 + GetGValue(c) * 587 + GetBValue(c) * 114 + 500) / 1000;    p[i] = RGB(c, c, c);  }} // 随机生成线void Random(){  for (int i = 0; i < RandNum; i++)  {    int starP;    int endP;    while (true)    {      starP = rand() % PointNum;      endP = rand() % PointNum;      if (IsLinked(starP, endP) == false        && IsLineKed_Rand(starP, endP) == false)      {        break;      }    }    lines[i].StarP = starP;    lines[i].EndP = endP;    Link_Rand(starP, endP);    // 记录随机生成的线  }  Line2False();          // 初始化线值} // 四舍五入int Round(float x){  return (int)(x < 0 ? x - 0.5 : x + 0.5);} // 获取颜色最深的那一条线LineS Getline(IMAGE *pimg){  LineS mylines;  mylines.StarP = 0;  mylines.EndP = 0;  DWORD*  p_data = GetImageBuffer(pimg);  int width = pimg->getwidth();  double MaxNum = 255;  int MYsteps;  float X, Y;  float CX, CY;  for (int i = 0; i<RandNum; i++)  {    int SUMDN = 0;    int x1 = points[lines[i].StarP].x;    int y1 = points[lines[i].StarP].y;    int x2 = points[lines[i].EndP].x;    int y2 = points[lines[i].EndP].y;    int steps = abs(x2 - x1) > abs(y2 - y1) ? abs(x2 - x1) : abs(y2 - y1);    float x = (float)x1;    float y = (float)y1;    float cx = (float)(x2 - x1) / steps;    float cy = (float)(y2 - y1) / steps;     for (int j = 0; j < steps; j++)    {      int XIA = width * Round(y) + Round(x);      SUMDN += GetRValue(p_data[XIA]);      x += cx;      y += cy;    }    double Aver = SUMDN / (steps * 1.0);     if (Aver < MaxNum)    {      MaxNum = Aver;      mylines = lines[i];      MYsteps = steps;      X = (float)x1;      Y = (float)y1;      CX = cx;      CY = cy;    }  }  if (MaxNum == 255)  {    return mylines;  }  for (int j = 0; j < MYsteps; j++)  {    int XIA = width* Round(Y) + Round(X);    int c = GetRValue(p_data[XIA]) + AddColor > 255 ? 255 : GetRValue(p_data[XIA]) + AddColor;    p_data[XIA] = RGB(c, c, c);    X += CX;    Y += CY;  }  return mylines;} // 给线图上色void ToColor(IMAGE *oriPic, IMAGE *linePic){  DWORD*  ori_data = GetImageBuffer(oriPic);  DWORD* line_data = GetImageBuffer(linePic);  for (int i = oriPic->getwidth() * oriPic->getheight() - 1; i >= 0; i--)  {    int oriR = GetRValue(ori_data[i]);    int oriG = GetGValue(ori_data[i]);    int oriB = GetBValue(ori_data[i]);    int lineR = GetRValue(line_data[i]);    int lineG = GetGValue(line_data[i]);    int lineB = GetBValue(line_data[i]);    int newPicR = (int)(255 - (255 - lineR)*(255 - oriR) / 255.0);    int newPicG = (int)(255 - (255 - lineG)*(255 - oriG) / 255.0);    int newPicB = (int)(255 - (255 - lineB)*(255 - oriB) / 255.0);    ori_data[i] = RGB(newPicR, newPicG, newPicB);  }}

“C语言如何实现绘制绕线画”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C语言如何实现绘制绕线画

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

C语言如何实现绘制绕线画

本篇内容介绍了“C语言如何实现绘制绕线画”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!绕线画简介简单点来说,就是在木板上钉一圈钉子,通过绕线
2023-07-04

C语言实现绘制绕线画的示例代码

绕线画简单点来说,就是在木板上钉一圈钉子,通过绕线进行构图,最终呈现出一幅图像。本文将用C语言实现这一效果,感兴趣的小伙伴可以尝试一下
2022-11-13

C语言如何实现绘制LoveBeat爱心曲线

这篇文章主要讲解了“C语言如何实现绘制LoveBeat爱心曲线”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言如何实现绘制LoveBeat爱心曲线”吧!心形曲线给出心形曲线参数方程如下:
2023-07-05

C语言实现绘制LoveBeat爱心曲线的示例代码

这篇文章主要为大家详细介绍了如何溧阳C语言实现绘制LoveBeat爱心曲线,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
2023-03-08

C#如何实现chart控件动态曲线绘制

这篇文章将为大家详细讲解有关C#如何实现chart控件动态曲线绘制,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。具体内容如下思想实验室要做一个动态曲线绘制,网上方法很多,但是缺乏完整代码和效果图的整合,往
2023-06-29

C语言如何实现弹跳小球动画

这篇文章主要介绍了C语言如何实现弹跳小球动画的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言如何实现弹跳小球动画文章都会有所收获,下面我们一起来看看吧。一、项目描述和最终成果展示项目描述: 一个球来回的跳
2023-06-30

如何进行R语言绘制尺子的实现

如何进行R语言绘制尺子的实现,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。下面使用基本的绘图命令plot、rect、segments、text绘制一把长10厘米
2023-06-26

C语言如何实现位段机制

这篇文章主要为大家展示了“C语言如何实现位段机制”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“C语言如何实现位段机制”这篇文章吧。概念什么是位段?位段又称为位域,C语言允许在一个结构体中以位为单
2023-06-29

C语言实现绘制可爱的橘子钟表

这篇文章主要为大家详细介绍了如何利用C语言实现绘制可爱的橘子钟表,文中的示例代码讲解详细,具有一定的学习价值,感兴趣的可以了解一下
2022-12-28

C语言如何实现文件复制

本篇内容主要讲解“C语言如何实现文件复制”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言如何实现文件复制”吧!C语言文件复制实例详解文件复制,在Linux中,将生成的read.o 重新文件拷
2023-06-16

C语言线性顺序表如何实现

这篇“C语言线性顺序表如何实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C语言线性顺序表如何实现”文章吧。线性表是最常用
2023-07-02

c语言如何实现字符串复制

在C语言中,可以使用strcpy()函数来实现字符串复制。具体实现方法如下:#include #include int main() {char str1[50] = "Hello, World!"
c语言如何实现字符串复制
2024-04-09

如何通过python-turtle库实现绘制图画

这篇文章给大家分享的是有关如何通过python-turtle库实现绘制图画的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1 图1第一个图是蚊香,感兴趣的小伙伴可以自己尝试在python中用turtle库绘制一下。
2023-06-22

C语言如何绘制简单时钟小程序

本篇内容介绍了“C语言如何绘制简单时钟小程序”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!先贴效果图给大家先看看基本机制是通过获取系统的时钟
2023-07-02

C++ opencv如何实现几何图形绘制

这篇“C++ opencv如何实现几何图形绘制”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C++ opencv如何实现几何
2023-06-30

C语言如何实现常见进制转换

这篇文章主要介绍“C语言如何实现常见进制转换”,在日常操作中,相信很多人在C语言如何实现常见进制转换问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言如何实现常见进制转换”的疑惑有所帮助!接下来,请跟着小编
2023-07-05

C语言如何用EasyX绘制小企鹅表情包

这篇“C语言如何用EasyX绘制小企鹅表情包”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“C语言如何用EasyX绘制小企鹅表
2023-07-04

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录