欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言實(shí)現(xiàn)繪制繞線畫(huà)的示例代碼

 更新時(shí)間:2022年11月06日 08:21:26   作者:編程小魚(yú)六六六  
繞線畫(huà)簡(jiǎn)單點(diǎn)來(lái)說(shuō),就是在木板上釘一圈釘子,通過(guò)繞線進(jìn)行構(gòu)圖,最終呈現(xiàn)出一幅圖像。本文將用C語(yǔ)言實(shí)現(xiàn)這一效果,感興趣的小伙伴可以嘗試一下

繞線畫(huà)簡(jiǎn)介

簡(jiǎn)單點(diǎn)來(lái)說(shuō),就是在木板上釘一圈釘子,通過(guò)繞線進(jìn)行構(gòu)圖,最終呈現(xiàn)出一幅圖像。

算法簡(jiǎn)介

可以總結(jié)概括一下,

首先需要有一張圖,可以是彩色的,但是必須顏色比較分明。

對(duì)圖像進(jìn)行灰度處理。

隨機(jī)生成 n 組數(shù),就是每?jī)蓚€(gè)釘子的組合。

計(jì)算 n 組數(shù)據(jù)連線所過(guò)圖像像素的平均數(shù),求出最小的一組。

連接該組釘子,并對(duì)這條線經(jīng)過(guò)的像素值分別加 m。

重復(fù)前面步驟 3 到步驟 5 直到繪制 z 條線結(jié)束循環(huán)。

示例

#include<graphics.h>
#include<math.h>
#include<conio.h>
#include<time.h>
 
// 以下數(shù)據(jù)可以自己調(diào)節(jié)
#define PointNum 288    // 圓圈分的數(shù)量(一圈釘子的數(shù)量)
#define LineNum 3000    // 循環(huán)繪制線的數(shù)量
#define RandNum 120      // 設(shè)置每次隨機(jī)生成連接的數(shù)量
#define AddColor 52      // 增加的值 0 到 255 值越小越線越集中,越大越分散
#define SIZE 800      // 圖像大小
 
// 以下參數(shù)不用調(diào)節(jié)
#define PI acos(-1.0)    // 圓周率
#define R (SIZE / 2 - 10)    // 半徑
 
struct PointS
{
  int p;
  int x;
  int y;
};
 
struct LineS
{
  int StarP;        // 起點(diǎn)
  int EndP;        // 終點(diǎn)
};
 
PointS points[PointNum];
LineS lines[RandNum];
 
// 為了判斷兩點(diǎn)是否連線定義的一維數(shù)組
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];
}
 
// 儲(chǔ)存已經(jīng)繪制過(guò)的線
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;
}
 
// 將隨機(jī)生成的進(jìn)行初始化
void Line2False()
{
  for (int i = 0; i < (1 + PointNum) * PointNum / 2; i++)
  {
    Line_Rand[i] = false;
  }
}
 
// 判斷這兩個(gè)點(diǎn)是否連線
bool IsLinked(int p1, int p2)
{
  if (p1 >= p2)
    return LineXY[(1 + p1) * p1 / 2 + p2];
  else
    return LineXY[(1 + p2) * p2 / 2 + p1];
}
 
// 儲(chǔ)存已經(jīng)繪制過(guò)的線
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();                // 初始化點(diǎn)
void ColorToGray(IMAGE *pimg);          // 彩色圖像轉(zhuǎn)換為灰度圖像
void Random();                  // 產(chǎn)生隨機(jī)數(shù)
LineS Getline(IMAGE *pimg);            // 獲取照片顏色
void ToColor(IMAGE *oriPic, IMAGE *linePic);  // 給繞線圖賦予顏色
 
int main()
{
  initgraph(SIZE, SIZE);
  setbkcolor(WHITE);
  cleardevice();
  IMAGE imgpolt;                  // 加載原圖
  IMAGE oriPic;                  // 儲(chǔ)存原圖
  IMAGE linePic;                  // 線圖
  loadimage(&imgpolt, _T("TG.jpeg"), SIZE, SIZE);  // 加載原圖
  oriPic = imgpolt;                // 原圖
  ColorToGray(&imgpolt);              // 將圖片轉(zhuǎn)換為灰度
  InitPoints();                  // 初始化點(diǎn)
  srand((unsigned)time(NULL));          // 生成隨機(jī)種子
 
  for (int i = 0; i < LineNum; i++)
  {
    Random();                  // 隨機(jī)生成 80
    LineS myline = Getline(&imgpolt);      // 計(jì)算 80 組點(diǎn)中平均值最小的
    Link(myline.StarP, myline.EndP);      // 記錄繪制過(guò)的線防止重復(fù)繪制
    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;
}
 
// 初始化點(diǎn)(想創(chuàng)新可以生成橢圓的位置坐標(biāo))
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);
  }
}
 
// 彩色圖像轉(zhuǎn)換為灰度圖像
void ColorToGray(IMAGE *pimg)
{
  DWORD *p = GetImageBuffer(pimg);  // 獲取顯示緩沖區(qū)指針
  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);
  }
}
 
// 隨機(jī)生成線
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);    // 記錄隨機(jī)生成的線
  }
  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);
  }
}

到此這篇關(guān)于C語(yǔ)言實(shí)現(xiàn)繪制繞線畫(huà)的示例代碼的文章就介紹到這了,更多相關(guān)C語(yǔ)言繞線畫(huà)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++使用new和delete進(jìn)行動(dòng)態(tài)內(nèi)存分配與數(shù)組封裝

    C++使用new和delete進(jìn)行動(dòng)態(tài)內(nèi)存分配與數(shù)組封裝

    這篇文章主要介紹了C++使用new和delete進(jìn)行動(dòng)態(tài)內(nèi)存分配與數(shù)組封裝,運(yùn)行期間才能確定所需內(nèi)存大小,此時(shí)應(yīng)該使用new申請(qǐng)內(nèi)存,下面我們就進(jìn)入文章學(xué)習(xí)具體的操作方法,需要的小伙伴可以參考一下
    2022-03-03
  • c++實(shí)現(xiàn)通用參數(shù)解析類示例

    c++實(shí)現(xiàn)通用參數(shù)解析類示例

    使用命令行執(zhí)行程序的時(shí)候在程序后可跟多個(gè)參數(shù)列表,而main函數(shù)的argc和argv分別存儲(chǔ)了相關(guān)的參數(shù)個(gè)數(shù)和參數(shù)內(nèi)容,而循環(huán)輸入相關(guān)的時(shí)候就需要用戶自己來(lái)解析相關(guān)參數(shù)。以下代碼用c++的方式實(shí)現(xiàn)了相關(guān)解析的封裝,使用起來(lái)非常方便
    2014-03-03
  • C語(yǔ)言函數(shù)調(diào)用約定和返回值詳情

    C語(yǔ)言函數(shù)調(diào)用約定和返回值詳情

    這篇文章主要介紹了C語(yǔ)言函數(shù)調(diào)用約定和返回值詳情,函數(shù)調(diào)用約定不同,會(huì)影響函數(shù)生成的符號(hào)名,函數(shù)入?yún)㈨樞颍螀?nèi)存的清理者,更多相關(guān)需要的小伙伴可以參考下文詳情介紹
    2022-07-07
  • C語(yǔ)言fgetc和fputc函數(shù)用法詳解(以字符形式讀寫(xiě)文件)

    C語(yǔ)言fgetc和fputc函數(shù)用法詳解(以字符形式讀寫(xiě)文件)

    這篇文章主要介紹了C語(yǔ)言fgetc和fputc函數(shù)用法詳解(以字符形式讀寫(xiě)文件),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之vector底層實(shí)現(xiàn)機(jī)制解析

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)之vector底層實(shí)現(xiàn)機(jī)制解析

    向量(Vector)是一個(gè)封裝了動(dòng)態(tài)大小數(shù)組的順序容器(Sequence?Container)。跟任意其它類型容器一樣,它能夠存放各種類型的對(duì)象??梢院?jiǎn)單的認(rèn)為,向量是一個(gè)能夠存放任意類型的動(dòng)態(tài)數(shù)組
    2021-11-11
  • C++中變量進(jìn)行初始化的3種方法

    C++中變量進(jìn)行初始化的3種方法

    本文主要介紹了C++中變量進(jìn)行初始化的3種方法,包括用"=",構(gòu)造函數(shù)初始化以及統(tǒng)一初始化這三種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-02-02
  • C++利用兩個(gè)棧實(shí)現(xiàn)隊(duì)列的方法

    C++利用兩個(gè)棧實(shí)現(xiàn)隊(duì)列的方法

    這篇文章主要給大家介紹了關(guān)于C++利用兩個(gè)棧實(shí)現(xiàn)隊(duì)列的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C++具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • 詳解如何利用C++實(shí)現(xiàn)Mystring類

    詳解如何利用C++實(shí)現(xiàn)Mystring類

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)MyString的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • C語(yǔ)言深入探究水仙花數(shù)與變種水仙花數(shù)代碼

    C語(yǔ)言深入探究水仙花數(shù)與變種水仙花數(shù)代碼

    求水仙花數(shù)和變種水仙花數(shù)是非常適合初學(xué)者學(xué)習(xí)的代碼,其中包含的循環(huán)和邏輯方式等知識(shí)點(diǎn)。這既能起到對(duì)以往知識(shí)的復(fù)習(xí),也可以學(xué)習(xí)到一種不同的邏輯思考方式
    2022-05-05
  • C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)順序表中的增刪改(頭插頭刪)教程示例詳解

    C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)順序表中的增刪改(頭插頭刪)教程示例詳解

    這篇文章主要為大家介紹了C語(yǔ)言數(shù)據(jù)結(jié)構(gòu)順序表中增刪改關(guān)于頭插頭刪的教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-02-02

最新評(píng)論