1. 程式人生 > >圖形填充演算法(掃描線種子填充演算法)

圖形填充演算法(掃描線種子填充演算法)

好多天沒去上圖形學的課了,今天聽說要交幾個圖形學的演算法實現程式,就花了將近一天的時間終於將程式除錯通過了,可是到了實驗室,才知道老師根本沒時間檢查。哎,白寫了^_^.說笑了,其實不寫怎麼能真正理解演算法的真諦呢。現在將程式貼出來,以備將來有學弟學妹之用。(其實如果只是Copy來的程式,對自己真是沒什麼用,除了有時能瞞過老師,也許對成績有幫助。僅此而已。)

/**
* 作者:老謝
* 最後修改日期:2006.4.14
* Email:[email protected]
* 功能描述:
* 圖形填充演算法之
* 掃描線種子填充演算法;
**/
/**
* 該程式還需要一個儲存 Point (點)結構的一個堆疊
* 和圖形模式的初始化程式
* 這兩個程式的實現程式在後面
**/

/*linescan.c*/

#include "graphics.h"
#include "dos.h"
#include "stdio.h"
#include "PStack.h"

/**
* 初始化掃描線
* (x,y)必須在圖形的內部
**/
void initScan(PointStack *s,int x,int y)
{
 Point p;

 p.X = x;
 p.Y = y;

 push(s,p);

 delay(4000);
}

/**
* 根據種子填充這一行,並且找到上下兩行的種子,入棧
**/
void fillThisLine(PointStack *s,Point seed,color fillColor,color borderColor)
{
 int curx = seed.X;
 int cury = seed.Y;

 int xr = 0;
 int xl = 0;

 int tag = 0; /*分別為區段的左右座標值*/
 Point point;

 curx = seed.X;

 /**
 * 不是邊界 也沒有填充過,一直向右走
 **/
 while(getpixel(curx,cury) != borderColor &&
  getpixel(curx,cury) != fillColor)
 {
  if(curx > 600)
  {
   printf("curx = %d",curx);
   return;
  }

  curx++;
 }

 xr = --curx;

 /**
 * 開始向左填充
 **/
 while(getpixel(curx,cury) != borderColor &&
  getpixel(curx,cury) != fillColor)
 {
  putpixel(curx,cury,fillColor);

  if(curx <= 0)
  {
   /*座標越界*/
   printf("curx = %d /n",curx);
   return;
  }
  curx--;
 }

 xl = ++curx;

 /**
 //從左邊開始檢查y-1這一行,直到遇到邊界或者已經填充過的點,記錄,作為種子
 //繼續檢查直到檢查到Xr;
 **/
 tag = 0;/*初始值必須是0*/
 curx = xl;
 while(curx <= xr)
 {
  /*發現空白並標記(tag = 1)*/
  if(getpixel(curx,cury-1) != borderColor &&
   getpixel(curx,cury-1) != fillColor)
  {
   tag = 1; /*有空白點*/
  }
  else
  {
   /**
   * 有空白點才有種子
   * 空白結束,儲存種子,並清空標記
   **/
   if(tag == 1)
   {
    curx--;
    point.X = curx;
    point.Y = cury-1;
    push(s,point);

    /*一段空白只能有一個種子*/
    tag = 0;
   }
  }
  curx++;
 }
 if(tag == 1)
 {
  curx--;
  point.X = curx;
  point.Y = cury-1;
  push(s,point);
 }
 /**
 //從左邊開始檢查y+1這一行,直到遇到邊界或者已經填充過的點,記錄,作為種子
 //繼續檢查直到檢查到Xr;
 **/
 curx = xl;
 tag = 0;/*初始值必須是0*/
 while(curx <= xr)
 {
  /*發現空白並標記(tag = 1)*/
  if(getpixel(curx,cury+1) != borderColor &&
   getpixel(curx,cury+1) != fillColor)
  {
   tag = 1; /*有空白點*/
  }
  else
  {
   /**
   * 有空白點才有種子
   * 空白結束,儲存種子,並清空標記
   **/
   if(tag == 1)
   {
    curx--;
    point.X = curx;
    point.Y = cury+1;
    push(s,point);

    /*一段空白只能有一個種子*/
    tag = 0;
   }
  }
  curx++;
 }
 if(tag == 1)
 {

  curx--;
  point.X = curx;
  point.Y = cury+1;
  push(s,point);
 }

}

/**
* 用指定顏色填充指定區域(並且指定所用的 stack)
**/
void fill(PointStack *s,color fillColor,color borderColor)
{
 Point seed;

 while(s->length > 0)
 {
  seed = pop(s);
  fillThisLine(s,seed,fillColor,borderColor);
 }
}

/**
* 應用例項
**/
int main()
{
 Point p;

 PointStack s;

 initstack(&s);
 init();

 printf("Start!");
 getch();
 circle(200,200,100);
 circle(200,200,30);
 circle(200,150,25);
 circle(200,170,20);
 rectangle(150,210,250,250);

 getch();

 initScan(&s,245,201);
 fill(&s,RED,WHITE);
 destroy(&s);

 initScan(&s,201,199);
 fill(&s,GREEN,WHITE);
 destroy(&s);

 initScan(&s,201,151);
 fill(&s,3,WHITE);
 destroy(&s);

 initScan(&s,201,139);
 fill(&s,9,WHITE);
 destroy(&s);

 initScan(&s,249,249);
 fill(&s,13,WHITE);
 destroy(&s);

 printf("Length of stackt:%d/n",s.length);
 printf("Capacity of stackt:%d/n",s.capacity);

 getch();
 closegraph();
}

/*PStack.H*/
/*******************堆疊的宣告******************************/
/**
* 定義一個存放Piont 結構的堆疊(動態陣列實現)
**/
#ifndef POINTSTACK_H
#define POINTSTACK_H

#include "stdio.h"
#include "stdlib.h"

/**
* define the Point struct
**/
typedef struct
{
 int X;
 int Y;
}Point;
/**
*stack
**/
typedef struct
{
 Point * head;
 int length;
 int capacity;
}PointStack;

/*========================*/
bool initstack(PointStack *s);
void destroy(PointStack *s);
void push(PointStack *s,Point p);
Point pop(PointStack *s);

#endif

/*PStack.c*/
/**
* 定義一個存放Piont 結構的堆疊(動態陣列實現)
**/
#include "myhead.h"
#include "PStack.h"

/*當堆疊空時返回*/
Point NPoint;

/*初始化堆疊*/
bool initstack(PointStack * s)
{
 NPoint.X = -1;
 NPoint.Y = -1;
 
 s->length = 0;
 s->capacity = 20;

 /*Capacity*/
 s->head = (Point *)malloc(sizeof(Point)*20);
 if(s->head == null)
 {
  printf("malloc error!");
  exit(0);
 }
 return true;
}

void destroy(PointStack *s)
{
 free(s->head);
 s->length = 0;
 s->capacity = 0;
}

void push(PointStack *s,Point p)
{
 Point * temp;
 int i;

 if(s->length >= s->capacity)
 {
  temp = (Point *)malloc(sizeof(Point)*(s->capacity + 20));
  if(temp != null)
  {
   /*success*/
   for(i = 0;i < s->length;i++)
   {
    temp[i] = s->head[i];
   }

   s->capacity += 20;
   free(s->head);
   s->head = temp;
  }
  else
  {
   printf("malloc error!=n");
   exit(0);
  }
 }

 /*push*/
 s->head[s->length] = p;
 s->length++;
}

Point pop(PointStack *s)
{
 Point temp;

 if(s->length == 0)
 {
  return 0;
 }
 else
 {
  s->length--;
  temp = s->head[s->length];
  return temp;
 }
}

/*myhead.c*/
/*圖形模式初始化*/
int init()
{
 int  driver = DETECT,mode = 0;
 initgraph(&driver,&mode,"E://tc//tc2");
 return 1;
}

相關推薦

圖形填充演算法掃描線種子填充演算法

好多天沒去上圖形學的課了,今天聽說要交幾個圖形學的演算法實現程式,就花了將近一天的時間終於將程式除錯通過了,可是到了實驗室,才知道老師根本沒時間檢查。哎,白寫了^_^.說笑了,其實不寫怎麼能真正理解演算法的真諦呢。現在將程式貼出來,以備將來有學弟學妹之用。(其實如果只是Cop

多邊形區域填充演算法--掃描線填充演算法有序邊表法

二、掃描線演算法(Scan-Line Filling)         掃描線演算法適合對向量圖形進行區域填充,只需要直到多邊形區域的幾何位置,不需要指定種子點,適合計算機自動進行圖形處理的場合使用,比如電腦遊戲和三維CAD軟體的渲染等等。         對向量多

算法系列之十二:多邊形區域填充演算法--掃描線填充演算法有序邊表法

、掃描線演算法(Scan-Line Filling)         掃描線演算法適合對向量圖形進行區域填充,只需要直到多邊形區域的幾何位置,不需要指定種子點,適合計算機自動進行圖形處理的場合使用,比如電腦遊戲和三維CAD軟體的渲染等等。         對向量多邊形區域

算法系列之十二:多邊形區域填充演算法--掃描線種子填充演算法

1.3掃描線種子填充演算法        1.1和1.2節介紹的兩種種子填充演算法的優點是非常簡單,缺點是使用了遞迴演算法,這不但需要大量棧空間來儲存相鄰的點,而且效率不高。為了減少演算法中的遞迴呼叫,節省棧空間的使用,人們提出了很多改進演算法,其中一種就是掃描線種子填充演算

【區域填充】中的種子填充演算法

假定:①邊界畫素給定 ②內部一個畫素(種子)給定–適合互動 (1)四連通法(4-connected) 向四個方向檢查,填色,擴散。遍歷區域內所有畫素。 (2)八連通法(8-connected) 向四個方向檢查,填色,擴散。遍歷區域內所有畫素。

BZOJ4837:[Lydsy1704月賽]LRU演算法雙指標&模擬

Description 小Q同學在學習作業系統中記憶體管理的一種頁面置換演算法,LRU(LeastRecentlyUsed)演算法。 為了幫助小Q同學理解這種演算法,你需要在這道題中實現這種演算法,接下來簡要地介紹這種演算法的原理: 1.初始化時,你有一個最大長度為n

整合演算法Bagging,隨機森林

引言(關於整合學習) 整合演算法包括很多種包括Bagging,隨機森林,Boosting 以及其他更加高效的整合演算法。在這篇部落格上只介紹Bagging演算法及隨機森林,Boosting提升演算法及其他高效的演算法在下一篇詳細講解。 整合演算法就是通過構建多個學習器來完成學習任務,是由

為什麼我要放棄javaScript資料結構與演算法第十一章—— 演算法模式

本章將會學習遞迴、動態規劃和貪心演算法。 第十一章 演算法模式 遞迴 遞迴是一種解決問題的方法,它解決問題的各個小部分,直到解決最初的大問題。遞迴通常涉及函式呼叫自身。 遞迴函式是像下面能夠直接呼叫自身的方式或函式 function recursiveFunction(someParam){

買什麼資料結構與演算法,這裡有:動態圖解十大經典排序演算法含JAVA程式碼實現

上篇的動圖資料結構反響不錯,這次來個動圖排序演算法大全。資料結構與演算法,齊了。 幾張動態圖捋清Java常用資料結構及其設計原理 本文將採取動態圖+文字描述+正確的java程式碼實現來講解以下十大排序演算法: 氣泡排序 選擇排序 插入排序 希爾排序

PHP無限級樹形結構演算法遞迴和引用

測試陣列 $array = [ ['id' => 1, 'pid' => 0, 'name' => '這是主類'], ['id' => 2, 'pid' => 0, 'name' => '這是主類'], ['id' =>

匈牙利演算法二分圖匹配問題

匈牙利演算法(二分圖匹配問題) 問題連結(杭電2063題):http://acm.hdu.edu.cn/showproblem.php?pid=2063 參考部落格:https://blog.csdn.net/cillyb/article/details/55511666 找伴侶是個遞迴

訓練過程--梯度下降演算法SGD、adam等

SGD系列 1)Batch gradient descent(批量梯度下降)   在整個資料集上   每更新一次權重,要遍歷所有的樣本,由於樣本集過大,無法儲存在記憶體中,無法線上更新模型。對於損失函式的凸曲面,可以收斂到全域性最小值,對於非凸曲面,收斂到區域性最小值。   隨機梯度

樹及其衍生演算法Trees and tree algorithms

1,二叉樹(Binary tree)     二叉樹:每一個節點最多兩個子節點,如下圖所示:            相關概念:節點Node,路徑path,根節點root,邊edge,子節點 children,父節點parent,兄弟節點sibling, 子樹subtree,葉子節點leaf node,

匈牙利演算法最小點覆蓋poj3041

題目意思是一次可以毀掉一行或者一列,要求至少毀多少次才能將圖上的x都消滅掉。 簡單的解釋一下最小點覆蓋:在圖中用最少的點,覆蓋圖中所有的邊 將每一行或者列想象成點,每個x想象成一條邊,於是此題很自然的轉換成為了最小點覆蓋問題。 而二分圖的最小點覆蓋數 = 二分圖的最大匹

共識演算法POW,POS,DPOS,PBFT

POW:Proof of Work,工作證明。 比特幣在Block的生成過程中使用了POW機制,一個符合要求的Block Hash由N個前導零構成,零的個數取決於網路的難度值。要得到合理的Block Hash需要經過大量嘗試計算,計

ELFhash 字串雜湊演算法以ELFHash詳解

字串雜湊演算法(以ELFHash詳解)   更多字串雜湊演算法請參考:http://blog.csdn.net/AlburtHoffman/article/details/19641123 先來了解一下何為雜湊: 雜湊表是根據設定的雜湊函式H(key)和處

一致性 Hash 演算法分散式或均衡演算法

簡介: 一致性雜湊演算法在1997年由麻省理工學院提出的一種分散式雜湊(DHT)實現演算法,設計目標是為了解決因特網中的熱點(Hot spot)問題,初衷和CARP十分類似。一致性雜湊修正了CARP使用的簡單雜湊演算法帶來的問題,使得分散式雜湊(DHT)可以在P

區域性搜尋演算法求解八皇后問題

區域性搜尋演算法是一種簡單的貪心搜尋演算法,是解決最優化問題的一種啟發式演算法,該演算法每次從當前解的臨近解空間中根據啟發函式選擇一個最優解(也不一定是最優解)作為當前解,直到達到一個區域性最優解。本文以求解八皇后問題來描述爬山法,模擬退火法以及遺傳演算法。 目錄 一、

圖及其衍生演算法Graphs and graph algorithms

1. 圖的相關概念     樹是一種的圖,相比樹,圖更能用來表示現實世界中的的實體,如路線圖,網路節點圖,課程體系圖等,一旦能用圖來描述實體,能模擬和解決一些非常複雜的任務。圖的相關概念和詞彙如下:       頂點vertex:圖的節點       邊Edge:頂點間的連線,若邊具有方向時,組成有向圖

擴充套件歐幾里得演算法求乘法逆元

eg:求5關於模14的乘法逆元 15 = 5*2+1 5 = 4*1+1 說明5與14互素,存在5關於14的乘法逆元 1 = 5-4 = 5-(14-5*2)= 5*3-14 因此5關於模14的乘法逆元為3  a存在模b的乘法逆元的充要條件是gcd(a,b)= 1 互質