Home Products Download Order Contacts

comp.graphics.algorithms

Subject: Re: Scan line Seed Fill Algorithm



ergun wrote:
> If it works by scanning line, sure.
>
> Kind Regards
>
Here you are
Best wishes

/********************************************************************
project : aegislib
created : 2003/05/30
created : 6:3:2002 17:35
file base: gl
file ext : h
author: NFR

Copyright (C) GISTEK, All Rights Reserved.
htpp://www.gistek.net

purpose: Graphic lib
*********************************************************************/


#if !defined(AEGISGL_INCLUDED_)
#define AEGISGL_INCLUDED_

#include
//-----------------------------------------------------------------------------------
struct Cglpt
{
Cglpt(int _x=0,int _y=0):
x(_x),
y(_y)
{
}
int x,y;
};

static unsigned char m_mask[] = { 1, 2, 4, 8, 16, 32, 64,128};
static unsigned char m_pat1[] = {127,191,223,239,247,251,253,254};
//HS_BDIAGONAL
static unsigned char m_pat2[] = {247,247,247,247, 0,247,247,247};
//HS_CROSS
static unsigned char m_pat3[] = {126,189,219,231,231,219,189,126};
//HS_DIAGCROSS
static unsigned char m_pat4[] = {254,253,251,247,239,223,191,127};
//HS_FDIAGONAL
static unsigned char m_pat5[] = {255,255,255,255, 0,255,255,255};
//HS_HORIZONTAL
static unsigned char m_pat6[] = {247,247,247,247,247,247,247,247};
//HS_VERTICAL
//this specific of course
static unsigned char m_pat7[] = {170, 85,170, 85,170, 85,170, 85};
static unsigned char m_pat8[] = {238,221,187,119,238,221,187,119};
static unsigned char m_pat9[] = {119,119,119,119,119,119,119,119};
static unsigned char m_pat10[] = {255,255,255,255,238,221,187,119};
static unsigned char m_pat11[] = {252,123,183,207,252,123,183,207};
static unsigned char m_pat12[] = {255,247,251,247,255,191,127,191};
static unsigned char m_pat13[] = {119,119,119, 0,119,119,119, 0};
static unsigned char m_pat14[] = {255,247,255,127,255,247,255,127};
static unsigned char m_pat15[] = { 68,170, 17,170, 68,170, 17,170};
static unsigned char m_pat16[] = {238,119,187,221,238,119,187,221};
static unsigned char m_pat17[] = {255,255, 0,255,255,255, 0,255};
static unsigned char m_pat18[] = {255,255,255,255,119,187,221,238};
static unsigned char m_pat19[] = { 91,252,255,231, 91,252,255,231};
static unsigned char m_pat20[] = {255,127,255,127,255,127,255, 85};
static unsigned char m_pat21[] = {191,191,191,191,191,191, 0,191};
static unsigned char m_pat22[] = {119,255,221,255,119,255,221,255};
static unsigned char m_pat23[] = { 34,136, 34,136, 34,136, 34,136};
static unsigned char m_pat24[] = {204,153, 51,102,204,153, 51,102};
static int m_width = 10000;
static int m_height = 10000;
//////////////////////////////////////////////////////////////////////////

void set_size(int width,int height)
{
m_width = width;
m_height = height;
}
//////////////////////////////////////////////////////////////////////////

class pattern_t {
public :
pattern_t ()
{
init();
}
void init()
{
for (int i=0;i<8;++i)
m_pat[i]=255;
}
void init(unsigned char pat[])
{
for(int i=0;i<8;++i)
m_pat[i]= pat[i];
}
pattern_t(int stdpat)
{
switch(stdpat)
{
case 1: init(m_pat1);break;
case 2: init(m_pat2);break;
case 3: init(m_pat3);break;
case 4: init(m_pat4);break;
case 5: init(m_pat5);break;
case 6: init(m_pat6);break;
case 7: init(m_pat7);break;
case 8: init(m_pat8);break;
case 9: init(m_pat9);break;
case 10: init(m_pat10);break;
case 11: init(m_pat11);break;
case 12: init(m_pat12);break;
case 13: init(m_pat13);break;
case 14: init(m_pat14);break;
case 15: init(m_pat15);break;
case 16: init(m_pat16);break;
case 17: init(m_pat17);break;
case 18: init(m_pat18);break;
case 19: init(m_pat19);break;
case 20: init(m_pat20);break;
case 21: init(m_pat21);break;
case 22: init(m_pat22);break;
case 23: init(m_pat23);break;
case 24: init(m_pat24);break;
default : init();
}
}
void write(char *path)
{FILE *fid = fopen(path,"w");
if (fid == NULL) return;
fprintf(fid,"{");
for(int i=0;i<7;++i)
fprintf(fid,"%3d,",m_pat[i]);
fprintf(fid,"%3d};",m_pat[7]);
fclose(fid);
}
unsigned char m_pat[8];
};

template
class Cglfiller : public T {

struct edge_info {
edge_info(double x,double y,double dx,double dy,bool passive):
m_x(x),
m_y(y),
m_dx(dx),
m_dy(dy),
m_nxt(0),
m_passive(passive)
{
}
double m_x,
m_y,
m_dx,
m_dy;
edge_info *m_nxt;
bool m_passive;
};

struct active_elem{
active_elem(edge_info *ed=0):
m_edge(ed),
m_nxt(0)
{
}
active_elem *m_nxt;
edge_info *m_edge;
};

private :
double m_y_max;
edge_info *m_cur_elem;
edge_info *m_passive_list;
active_elem *m_active_list;
int m_px,m_py;

inline int _round(double x)
{
return int(floor(x + 0.5));
}
/****************************** PASSIVE LIST
**********************************/
void push(const double x1,const double y1,const double x2,const double y2)
{double dx,dy;
edge_info * elem;

if (y1 > m_y_max) m_y_max = y1;
dx = x2-x1;
dy = y2 -y1;
elem = new edge_info(x1,y1,dx,dy,true);
ATLASSERT(elem != NULL);
if (m_passive_list == NULL)
{m_passive_list = elem;
m_cur_elem = m_passive_list;
}
else
{m_cur_elem->m_nxt = elem;
m_cur_elem = elem;
}
}

void choose_point(const double x1,const double y1,const double x2,const
double y2)
{if (y2> y1) push(x2,y2,x1,y1);
else if (y2 < y1) push(x1,y1,x2,y2);
else if (x2 > x1) push(x2,y2,x1,y1);
}

void in_elem(active_elem * &l,active_elem * elem)
{ elem->m_nxt = l;
l = elem;
}

void sort_active(active_elem * &l,active_elem * elem)
{ if (!l)
{l = elem;
elem->m_nxt = NULL;
}
else if (elem->m_edge->m_x > l->m_edge->m_x)
sort_active(l->m_nxt,elem);
else if (elem->m_edge->m_x < l->m_edge->m_x)
in_elem(l,elem);
else if (elem->m_edge->m_dx > l->m_edge->m_dx)
sort_active(l->m_nxt,elem);
else
in_elem(l,elem);
}

void active(edge_info * cc)
{
active_elem * loc = new active_elem(cc);
ATLASSERT(loc != NULL);
sort_active(m_active_list,loc);
cc->m_passive = false;
}

void remove_from_active(edge_info * cc)
{active_elem * cur,*prec;
cur = prec = m_active_list;
while (cur->m_edge != cc)
{
prec = cur;
cur = cur->m_nxt;
}
if (cur == m_active_list)
m_active_list = m_active_list->m_nxt;
else
prec->m_nxt = cur->m_nxt;
delete cur;
cur = NULL;
}

void process_active(const int y)
{active_elem * cc;
bool toggle(false);

cc = m_active_list;
while (cc != NULL)
{
if (!toggle)
{toggle = true;
_moveto(_round(cc->m_edge->m_x),y);
}
else
{toggle = false;
_lineto(_round(cc->m_edge->m_x),y);
}
cc->m_edge->m_x = cc->m_edge->m_x -
(cc->m_edge->m_dx/cc->m_edge->m_dy);
cc = cc->m_nxt;
}
}

void mark_active(const int y_scan)
{edge_info * cur,*cur_nxt,*prec;

cur = prec = m_passive_list;
while (cur)
{ cur_nxt = cur->m_nxt;
if (cur->m_y >= y_scan && cur->m_y+cur->m_dy < y_scan)
{if (cur->m_passive )
active(cur);
prec = cur;
}
else if ((cur->m_y+cur->m_dy) >= y_scan)
{if (cur == m_passive_list)
{m_passive_list = cur_nxt;
prec = m_passive_list;}
else prec->m_nxt = cur->m_nxt;
if (!cur->m_passive)
remove_from_active(cur);
delete cur;
cur = NULL;
}
else prec = cur;
cur = cur_nxt;
}
}

void process()
{int y_scan = _round(m_y_max);
while (m_passive_list != NULL)
{
mark_active(y_scan);
if (y_scan >= 0 && y_scan < m_height)
process_active(y_scan);
y_scan-- ;
}
}

///////////////////////////////////////////////////////////////////////////////////
public :

Cglfiller():
m_y_max(-10e20),
m_cur_elem(0),
m_passive_list(0),
m_active_list(0),
m_px(0),
m_py(0)
{
}

void moveto(const int x,const int y)
{
m_px = x;
m_py = y;
}


void lineto(const int x,const int y)
{
choose_point(x,y,m_px,m_py);
m_px = x;
m_py = y;
}


virtual ~Cglfiller()
{
process();
ATLASSERT (m_active_list == NULL);
ATLASSERT (m_passive_list == NULL);
}
};
////////////////////////////////////////////////////////////////////////////////////
class WndFiller {
public :
WndFiller():m_dc(0){
}
void Set(HDC dc,COLORREF c)
{
m_dc = dc;
m_c = c;
}


void _moveto(int x,int y)
{
m_p[0].x = x;
m_p[0].y = y;
}
void _lineto(int x,int y)
{
m_p[1].x = x;
m_p[1].y = y;
Polyline(m_dc,(LPPOINT)m_p,2);
}
protected :
HDC m_dc;
COLORREF m_c;
Cglpt m_p[2];
};
//////////////////////////////////////////////////////////////////////////

class WndTransPatFiller : public WndFiller {
public :
void Set(HDC dc,pattern_t &pat,COLORREF c,bool _xor = false)
{
m_dc = dc;
m_pattern = pat;
m_c = c;
m_xor =_xor;
}

void _lineto(int x,int y)
{
if (y < 0)
return;
int pat_y = y % 8;
if (m_xor)
for(int i=m_p[0].x< 0?0:m_p[0].x;i< ((x>m_width)?m_width:x);++i)
{int pat_x = i%8;
if ((m_pattern.m_pat[pat_y] & m_mask[pat_x])!=m_mask[pat_x])
SetPixel(m_dc,i,y,m_c^GetPixel(m_dc,i,y));
}
else
for(int i=m_p[0].x< 0?0:m_p[0].x;i< ((x>m_width)?m_width:x);++i)
{int pat_x = i%8;
if ((m_pattern.m_pat[pat_y] & m_mask[pat_x])!=m_mask[pat_x])
SetPixel(m_dc,i,y,m_c);
}
}
pattern_t m_pattern;

bool m_xor;
};

class WndPatFiller : public WndTransPatFiller {
public :
void Set(HDC dc,pattern_t &pat,COLORREF c,COLORREF b)
{
m_dc = dc;
m_pattern = pat;
m_c = c;
m_b = b;
}

void _lineto(int x,int y)
{
if (y < 0)
return;
int pat_y = y % 8;
for(int i=m_p[0].x< 0?0:m_p[0].x;i < ((x>m_width)?m_width:x);++i)
{int pat_x = i%8;
if ((m_pattern.m_pat[pat_y] & m_mask[pat_x])!=m_mask[pat_x])
SetPixel(m_dc,i,y,m_c);
else
SetPixel(m_dc,i,y,m_b);
}
}
COLORREF m_b;

};
///////////////////////////////////////////////////////////////////////////////////////
void h2stdfillpolygon(HDC dc,Cglpt pts[],int si,int stdpat,COLORREF
c,COLORREF b)
{ Cglfiller filler;
pattern_t pat(stdpat);
filler.Set(dc,pat,c,b);
filler.moveto(pts[0].x,pts[0].y);
for (int i=1;i< si;++i)
filler.lineto(pts[i].x,pts[i].y);
filler.lineto(pts[0].x,pts[0].y);
}

void h2stdtranspolygon(HDC dc,Cglpt pts[],int si,int stdpat,COLORREF
c,bool xor = false)
{ Cglfiller filler;
pattern_t pat(stdpat);
filler.Set(dc,pat,c,xor);
filler.moveto(pts[0].x,pts[0].y);
for (int i=1;i< si;++i)
filler.lineto(pts[i].x,pts[i].y);
filler.lineto(pts[0].x,pts[0].y);
}



void h2transpolygon(HDC dc,Cglpt pts[],int si,pattern_t &pat,COLORREF c)
{
Cglfiller filler;
filler.Set(dc,pat,c);
filler.moveto(pts[0].x,pts[0].y);
for (int i=1;i< si;++i)
filler.lineto(pts[i].x,pts[i].y);
filler.lineto(pts[0].x,pts[0].y);
}


void h2fillpolygon(HDC dc,Cglpt pts[],int si,COLORREF c)
{ Cglfiller filler;
filler.Set(dc,c);
filler.moveto(pts[0].x,pts[0].y);
for (int i=1;i< si;++i)
filler.lineto(pts[i].x,pts[i].y);
filler.lineto(pts[0].x,pts[0].y);
}


void h2fillpolygon(HDC dc,Cglpt pts[],int si,pattern_t &pat,COLORREF
c,COLORREF b)
{ Cglfiller filler;
filler.Set(dc,pat,c,b);
filler.moveto(pts[0].x,pts[0].y);
for (int i=1;i< si;++i)
filler.lineto(pts[i].x,pts[i].y);
filler.lineto(pts[0].x,pts[0].y);
}

void h2polypolygon(HDC dc,Cglpt pts[],int vertex[],int nb,pattern_t
&pat,COLORREF c,COLORREF b, bool transp=false )
{
Cglfiller filler;
filler.Set(dc,pat,c,b);
int k(0);
int l;
for( int i = 0;i {
filler.moveto(pts[k].x,pts[k].y);
l = k;
k++;
{for (int i=1;i< vertex[i];++i)
filler.lineto(pts[k].x,pts[k].y);
k++;
}
filler.lineto(pts[l].x,pts[l].y);
k++;
}
}


void h2rectangle(HDC dc,Cglpt min,Cglpt max,int stdpat,COLORREF
c,COLORREF b,bool transp=false)
{
pattern_t pat(stdpat);
if (min.x < 0) min.x = 0;
if (max.x > m_width) max.x = m_width;
if (min.y < 0) min.y = 0;
if (max.y > m_height) max.y = m_height;
if (transp)
for (int y = min.y;y< max.y;++y)
{
int pat_y = y % 8;
for(int i=min.x;i< max.x;++i)
{int pat_x = i%8;
if ((pat.m_pat[pat_y] & m_mask[pat_x])!=m_mask[pat_x])
SetPixel(dc,i,y,c);
}
}
else
for (int y = min.y;y< max.y;++y)
{
int pat_y = y % 8;
for(int i=min.x;i< max.x;++i)
{int pat_x = i%8;
if ((pat.m_pat[pat_y] & m_mask[pat_x])!=m_mask[pat_x])
SetPixel(dc,i,y,c);
else
SetPixel(dc,i,y,b);
}
}
}


//---------------------------------------------------------------------------------------


#endif

Reply


View All Messages in comp.graphics.algorithms

path:
Scan line Seed Fill Algorithm =>Re: Scan line Seed Fill Algorithm =>Re: Scan line Seed Fill Algorithm =>

Replies:
Re: Scan line Seed Fill Algorithm
Re: Scan line Seed Fill Algorithm

Copyright 2006 WatermarkFactory.com. All Rights Reserved.