Title: "OpenGL implementation of graphics scanning line seed filling algorithm"
date:2018-06-11t19:41:30+08:00
Tags: ["Graphic science"]
Categories: ["C + +"]
First on
Starting seed point of white
Code
#include <GL/glut.h>#include <cmath>#include <set>#include <vector>#include <unistd.h>//sleep function#include <iostream>#include <algorithm>//find function to find elements in vector#include <stack>using namespaceStd//normalized to a multiple of 0.05inlineGldouble Normal (gldouble x) {return(Round (X * -) / -);}typedef structPoint {gldouble x, y; Point (gldouble a =0, gldouble B =0) {x = a, y = b; }//Set automatically sorts the inserted elements, requiring overloaded operators. Defining collations // // requirements for the//overloaded operators //1. If A<b is true, then B<a is false //2. If A<b,b<c-a<c //3. A<a is always false . //Set to determine whether the elements are equal //if (! ( a<b| | B<a) --A=b BOOL operator< (ConstPoint &a)Const{return((x-a.x) <-0.01|| ((x-a.x) <0.01&& (Y-A.Y) <-0.01)); }BOOL operator==(ConstPoint &a)Const{return(ABS (X-A.X) <0.01&& ABS (Y-A.Y) <0.01); }} point;voidDrawGrid ();voidInitgraphborder ();voidDrawgraphices ();voidMydisplay ();voidDDA (Point A, point B);voidInitgraphborder ();p oint first_seed;unsigned LongMStatic intn = +;StaticGlfloat pointsize =12.5;set<point> Graphborder;//Graphics boundary array <set> can quickly find//set can be quickly found, but it will be scrambled, not easy to implement the fill animationVector<point> Graphfill;//Array to populateVector<point> Graphvertex;//Store graphical fixed-point array, in orderStack<point> seed;//Storage seedsGldouble p =float(2.0/n);//size of each lattice//Draw grid coordinatesvoidDrawGrid () {Glcolor3d (1,1,1);//Grid with white representationGllinewidth (1); Glbegin (Gl_lines); for(inti =0; I <= N; i++) {//Draw Vertical LineGlvertex2d (-1+1.0/n + i *2.0N-1); Glvertex2d (-1+1.0/n + i *2.0N1);//Draw horizontal LineGlvertex2d (-1,-1+1.0/n + i *2.0/n); Glvertex2d (1,-1+1.0/n + i *2.0/n); } glend ();}//dda AlgorithmvoidDDA (Point A, point B) {cout <<"Connection ("<< a.x <<','<< A.Y <<") to ("<< b.x <<','<< b.y <<")\ n";if(A.x > b.x) {Swap (A, B); } a.x = Normal (a.x); A.y = Normal (A.Y); b.x = Normal (b.x); B.y = Normal (B.Y);Doubledelta_x = b.x-a.x;Doubledelta_y = B.Y-A.Y;DoubleK = delta_y/delta_x;Doublex = a.x, y = a.y;if(k >-1&& K <1) {//x is the maximum displacement //cout << k << Endl; while(true) {if((x-b.x) >0.01) Break; Graphborder.insert (Point (Normal (X), Normal (Y))); x + = P; Y + = (p * k); } }Else if(k >=1) {//y is the maximum displacement while(true) {if((Y-B.Y) >0.01) Break; Graphborder.insert (Point (Normal (X), Normal (Y))); Y + = p; x + = (p/k); } }Else{ while(true) {if((b.y-y) >0.01) Break; Graphborder.insert (Point (Normal (X), Normal (Y))); Y-= p; X-= (p/k); } }}//Initialize an array of graphic boundariesvoidInitgraphborder () {//Graphvertex The vertex of the storage graph for(Autoit = Graphvertex.begin (); It! = Graphvertex.end (); it++) {if(It = = Graphvertex.end ()-1) {//Last point connect first pointDDA (*it, *graphvertex.begin ()); }Else{//Connect it1 and IT2XRDDA (*it, * (IT +1)); } }}/********************************** 1. Initialize: stack empty, seed seeds (x, y) into the stack* 2. Out of stack: if the stack is empty, otherwise the stack top element out of the stack, with Y as the current scan line* 3. Fill in and determine the region of the new seed point: from the current seed point, fill the left and right direction along the Y-scan line* Until the boundary pixels are encountered. Marks the left and right endpoint coordinates of the current segment as XL, Xr.* 4. Determine the new seed point: Check the [XL-1,XR] and [XL+1,XR] regions, if there are non-boundary, unfilled* pixels, the most right pixel of each interval is used as the seed point pressure stack. Return to step 2nd**********************************///Fill the area along the scan line//Remove seed points from seed stack <stack>seed//Add the points to be filled <vector>graphfillvoidFloodfillset () { while(!seed.empty ()) {Point s = seed.top ();//Current seed pointSeed.pop (); cout <<"Current seed point"<< s.x <<" "<< s.y << Endl;//Fill seed point and left and right continuous areaPoint T = S, xl, XR;//Fill left continuous area and find the leftmost boundary of the region while(true) {//Arrival Border Exit if(T.x <-1) Break; Graphfill.push_back (t); T.x-= p;//Find out if it is populated AutoIt1 = Find (Graphfill.begin (), Graphfill.end (), t);//Find out if it is a boundary AutoIt2 = Graphborder.find (t);if(It1! = graphfill.end () | | It2! = graphborder.end ()) {//filled or reached boundaryXL = t; Xl.x + = p; Break; }} t = S;//Fill right area while(true) {if(T.x >1) Break; Graphfill.push_back (t); T.x + = p;//Find out if it is populated AutoIt1 = Find (Graphfill.begin (), Graphfill.end (), t);//Find out if it is a boundary AutoIt2 = Graphborder.find (t);if(It1! = graphfill.end () | | It2! = graphborder.end ()) {//filled or reached boundaryXR = t; Xr.x-= p; Break; } }//Find the seed point in the next line for(intD: {1,-1}) {//First up and down BOOLStatus =false;//Mark the beginning of a blank areat = XL; T.y + = (p * d);//Move to the next or previous line while((t.x-xr.x) <0.07) {AutoIt1 = Find (Graphfill.begin (), Graphfill.end (), t);AutoIt2 = Graphborder.find (t);//Find a blank area start point //If the current point is an empty area and the blank area does not start S=true if(!status && it1 = = Graphfill.end () && it2 = = Graphborder.end ()) {status =true; }//area starts and encounters a boundary or fill area if(Status && (it1! = graphfill.end () | | It2! = graphborder.end ())) {//reach border or filled color with white space on the leftStatus =false;//Add a point to the left as a seed pointSeed.push (Point (T.x-p, T.y)); }//reach the right interval XR, even if not the boundary, as long as the s=true should also mark the right seed point if(Status && ABS (T.x-xr.x) <0.01) {//Note Floating-point comparison sizeStatus =false; Seed.push (t); } t.x + = P; } } }}//Draw the bounds of the drawing to be filledvoidDrawgraphices () {glcolor3f (0.5,0.5,0.2); Glbegin (gl_points);a new feature of//c++11 that can traverse the vector map list or {a. for(AutoIt:graphborder) {glvertex2d (it.x, IT.Y); } glend ();}//Draw filled pixelsvoidDrawfloodfill (unsigned Longm) {glcolor3f (0.4,0.8,0.1); Glbegin (gl_points); for(unsigned Longi =0; I < m && i < graphfill.size (); i++) {glvertex2d (graphfill[i].x, GRAPHFILL[I].Y);//mydisplay ();} glend ();}//DrawingvoidMydisplay () {Glclearcolor (0.1f,0.3f,0.33f,0.0f); Glclear (Gl_color_buffer_bit);//Draw graphics boundariesDrawgraphices ();//Draw M-filled pixelsDrawfloodfill (m); Glcolor3d (1,0,0); Glpointsize (pointsize);//Add a white dot, start seed pointGlcolor3d (1,1,1); Glbegin (gl_points); Glvertex2d (first_seed.x, FIRST_SEED.Y); Glend ();//Draw gridDrawGrid (); Glflush ();}intMainintargcChar*argv[]) {//Deposit the drawing vertices to be filled 8 //( -0.7,0.6) (0.7,0.6) (0.7,0) (0.3,0) (0.3,-0.5) ( -0.3,-0.5) //( -0.3,0) ( -0.7,0)cout <<"Please enter vertex coordinates, ( -1,1) Enter >1 end\ n";Doublex, y; while(CIN >> X) {if(X >1) Break;ElseCin >> y; Graphvertex.emplace_back (Point (x, y)); } cout <<"Enter the initial seed point\ n"; Cin >> x >> y; first_seed.x = x; First_seed.y = y; Glutinit (&ARGC, argv); Glutinitdisplaymode (Glut_rgb | Glut_single); Glutinitwindowsize ( -, -); Glutinitwindowposition ( -, -);//Initialize boundary setInitgraphborder ();//Scan line seed fillSeed.push (First_seed); Floodfillset (); Glutcreatewindow ("Scan line seed fill"); Glutdisplayfunc (&mydisplay); for(M =0; M < Graphfill.size (); m++) {Usleep (10000); Mydisplay (); } glutmainloop ();return 0;}
Input sample
-0.7 0.7-0.35 0.7-0.35 00.35 00.35 0.70.7 0.70.7 -0.7-0.7 -0.72 0 -0.2
OpenGL-based algorithm for seed filling of graph scanning line