μ΄ ν¬μ€ν μ μΏ ν‘ ννΈλμ€ νλμ μΌνμΌλ‘, μ΄μ λ°λ₯Έ μΌμ μ‘μ μμλ£λ₯Ό μ 곡λ°μ μ μμ΅λλ€.
νκ΅ κ³Όμ λ‘ μ μΆνλ μ€μΊλΌμΈ ν΄λ¦¬κ³€ ν λ° λ°μ΄λ리 4-μ¨μ΄ ν΄λ¦¬κ³€ ν ^.^
λ€κ°νμ±μ°κΈ°!!
μ£Όμ μμ€ μ½λ
void boundary_fill(int x, int y, BYTE* byBoundaryColor) cout << x << " " << y << endl; boundary_fill(x+1, y, byBoundaryColor); boundary_fill(x-1, y, byBoundaryColor); } }
// μ체 μ€νμ μ΄μ©ν version2 - λνμ ν¬κΈ°κ° 컀λ μ λμ !! :) void boundary_fill(int x, int y, BYTE* byBoundaryColor) { stack< CGLPoints > stackStoreCoords; stackStoreCoords.push(*(new CGLPoints(x,y))); cout << x << " " << y << endl; //νμ¬ν½μ μ΄ ν λ리μμ΄λ κ°μΌλ©΄ μ€λ¨. BYTE byCurrerntColor[3]; do { int nX = stackStoreCoords.top().GetX(); int nY = stackStoreCoords.top().GetY(); glReadPixels(nX ,WINSIZEY-(nY),1,1,GL_RGB,GL_UNSIGNED_BYTE,byCurrerntColor); if((byBoundaryColor[0] == byCurrerntColor[0] && byBoundaryColor[1] == byCurrerntColor[1] && byBoundaryColor[2] == byCurrerntColor[2] ) )// || nX<=0 \ ||WINSIZEY<=nY \ ||WINSIZEX<=nX \ ||WINSIZEY<=WINSIZEY-nY \ || matrix[nX][WINSIZEY-nY] == true ) { stackStoreCoords.pop(); } else { // matrix[nX][WINSIZEY-nY]=true; glColor3f(1.0, 1.0, 0.0); setPixel(nX,WINSIZEY-nY); //μ μ μ°κ³ μ€νμλ€ 4λ°©ν₯μ μλλ€. stackStoreCoords.push(*(new CGLPoints(nX+1,nY))); stackStoreCoords.push(*(new CGLPoints(nX,nY-1))); stackStoreCoords.push(*(new CGLPoints(nX-1,nY))); stackStoreCoords.push(*(new CGLPoints(nX,nY+1))); } } while(!stackStoreCoords.empty()); //μ€νμ΄ λΉλ©΄ 루νλ₯Ό λΉ μ Έλμ¨λ€. } //CGLPointsν΄λμ€λ₯Ό yμ’ν κΈ°μ€μΌλ‘ μ λ ¬ν λ λΉκ΅ν¨μ. bool LessByY(CGLPoints pt1, CGLPoints pt2) { return (pt1.GetY()<pt2.GetY()); } //βββββββββββββββββββββββββ // ββ λ©μΈ μμ ββ //βββββββββββββββββββββββββ void main(int argc, char** argv) { } //βββββββββββββββββββββββββ // ββ ν¨μλ€ μ μ ββ //βββββββββββββββββββββββββ //μ΄κΈ°ν void init(void) { //μλ΅ } //μ μ°κΈ° void setPixel(GLint x, GLint y) { } //μ κΈκΈ° void setLine(GLint x, GLint y, GLint x2, GLint y2) { } //λ€κ°ν μ κΈκΈ° (μ λ€μ μΈμλ‘ λ°λλ€) void setPolyLine(vector<CGLPoints>& vecGLPoints) { int nNumOfvertice = vecGLPoints.size(); int i; for(i = 1 ; i < nNumOfvertice ; i++) { setLine(vecGLPoints[i-1].GetX(), vecGLPoints[i-1].GetY(), vecGLPoints[i].GetX(), vecGLPoints[i].GetY()); } setLine(vecGLPoints[nNumOfvertice-1].GetX(), vecGLPoints[nNumOfvertice-1].GetY(), vecGLPoints[0].GetX(), vecGLPoints[0].GetY()); } //μ€μΊλΌμΈ λ°©μμΌλ‘ λ€κ°ν λ΄λΆ μΉ νκΈ°(μ λ€μ μΈμλ‘ λ°λλ€) void scanLine(vector<CGLPoints>& vecGLPoints) { int i,j; int color; int minY, maxY; //Xμ’νμ© //yμ’νλ₯Ό ν€μ΄λ©° xμ’νλ₯Ό valueλ‘ νλ 맡 vector<int>* vecScanLineYCoord = new vector<int>[WINSIZEY]; CGLPoints* temp = new CGLPoints(0,0); //λ€κ°νμ yμ μ΅λκ°κ³Ό μ΅μκ°μ μ°Ύλλ€. temp = min_element(vecGLPoints.begin(),vecGLPoints.end(),LessByY); //μ΅μκ° minY = temp->GetY(); temp = max_element(vecGLPoints.begin(),vecGLPoints.end(),LessByY); //μ΅λκ° maxY = temp->GetY(); //μ΅μμ΅λκ° μ½μμΆλ ₯(ν μ€νΈμ©) cout << minY << " "<< maxY << endl; int nLenth = vecGLPoints.size(); //μ λ€μ κ°―μ for(i = 1 ; i <= nLenth ; i++) { //λμ μ κΈ°μΈκΈ°λ₯Ό ꡬν¨. float fSlope = float(vecGLPoints[i-1].GetY() - vecGLPoints[i%nLenth].GetY()) / float(vecGLPoints[i-1].GetX() - vecGLPoints[i%nLenth].GetX()); //λμ μ μ§μ μ λ°©μ μμ yμ νΈ // y-y2 == (y2-y1)/(x2-x1) * (x-x2) where x == 0 float yInterCept = fSlope*(-vecGLPoints[i-1].GetX())+vecGLPoints[i-1].GetY(); //forλ¬Έμ μ¬λ°λ‘ λ리기 μν΄ λ vertexμ yμ’ν λμλΉκ΅νλ€. int minimum, maximum; if(vecGLPoints[i-1].GetY()<vecGLPoints[i%nLenth].GetY()) { minimum = vecGLPoints[i-1].GetY(); maximum = vecGLPoints[i%nLenth].GetY(); } else { minimum = vecGLPoints[i%nLenth].GetY(); maximum = vecGLPoints[i-1].GetY(); } for(j = minimum ; j < maximum ; j++ ) { // jλ yμ’νμ΄λ©° xμ’νλ yμ’νμ μ νΈμ λΊκ°μ (1/κΈ°μΈκΈ°)λ₯Ό κ³±ν΄μ£Όλ©΄ λμ¨λ€. (y = mx + b μμλμΆ) vecScanLineYCoord[j].push_back((j-yInterCept)*(1.0f/fSlope)); } } //κ° scanLine yμ’νμμ μ μ₯λ xμ’νλ€μ μ€λ¦μ°¨μμΌλ‘ μ λ ¬νλ€. for(i = minY ; i <= maxY ; i++) sort(vecScanLineYCoord[i].begin(),vecScanLineYCoord[i].end()); //μ€μΊλΌμΈμ μ΅μκ°μμ μ΅λκ°κΉμ§ for(i = minY ; i < maxY ; i++) { //μ λ ¬λ Xμ’νλ€μ PAIRλ€μ μ μ κ·Έμ΄ ν΄λ¦¬κ³€μ μμ μ±μ΄λ€. int nSize = vecScanLineYCoord[i].size(); for(j = 0 ; j < nSize ; j+=2) { //μ½μ ν μ€νΈ μΆλ ₯ // cout << "scanLine Y : " << i << "Xμ’ν Pair : " \ <<vecScanLineYCoord[i][j%nSize] << " "<< vecScanLineYCoord[i][(j+1)%nSize] << endl; setLine(vecScanLineYCoord[i][j%nSize],i,vecScanLineYCoord[i][(j+1)%nSize],i);//μ κΈκΈ° } } } void displayFunc(void) { int i; glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 0.0); // (x,y)ννλ€μ κ°μ§μ μλ 벑ν°μ μΈ vector<CGLPoints> vecPtVertice; //λλ€λν srand(GetTickCount()); // for(i = 0 ; i < 100 ; i++) // vecPtVertice.push_back(*(new CGLPoints(rand()%WINSIZEX, rand()%WINSIZEY) )); //ν°λν vecPtVertice.push_back(*(new CGLPoints(100,400))); vecPtVertice.push_back(*(new CGLPoints(300,200))); vecPtVertice.push_back(*(new CGLPoints(500,100))); vecPtVertice.push_back(*(new CGLPoints(700,300))); vecPtVertice.push_back(*(new CGLPoints(500,500))); vecPtVertice.push_back(*(new CGLPoints(400,350))); vecPtVertice.push_back(*(new CGLPoints(300,600))); //μμλν /* vecPtVertice.push_back(*(new CGLPoints(226, 143))); vecPtVertice.push_back(*(new CGLPoints(216, 174))); vecPtVertice.push_back(*(new CGLPoints(270, 184))); vecPtVertice.push_back(*(new CGLPoints(287, 139))); vecPtVertice.push_back(*(new CGLPoints(247, 132))); */ //ν λ리 setPolyLine(vecPtVertice); if(g_MouseState.rightButton == true) scanLine(vecPtVertice); //μ€μΊλΌμΈμΌλ‘ λ€κ°νμ μ±μ΄λ€. (μΈμλ‘ verticeλκΉ) //λ§μ°μ€λ₯Ό ν΄λ¦νλ©΄ ν΄λΉμμλΆν° Boundary_fill μμ. if(g_MouseState.leftButton==true) { glColor3f(1.0, 1.0, 0.0); BYTE byBoundaryColor[3]={255,255,0}; DWORD dwBegin = GetTickCount(); boundary_fill(g_MouseState.x,g_MouseState.y,byBoundaryColor); DWORD dwEnd = GetTickCount(); cout << "Boundary_FILL μμμκ° : " << float((dwEnd - dwBegin)/1000.0f) << endl; } glFlush(); } void HandleMouseState(int button, int state, int x, int y) { //μλ΅ } |
μ€ ν ν λ©΄
Boundary Fillμ μ΄μ©
μ¬κ·ν¨μλ₯Ό μ΄μ©ν Boundary_fill
κ·Έλ¦Ό1) μ΄ μ λ ν¬κΈ°λ λ¬Έμ μλ€
κ·Έλ¦Ό2) νλ‘κ·Έλ¨μ΄ λ©μ΄λ²λ¦°λ€.
κ·Έλ¬λ μ΄ μ¬κ·ν¨μμ λ¬Έμ μ μ ν΄λ¦¬κ³€μ ν¬κΈ°κ° μμ€ν
μ€νμ΄ μ μ₯ν μ μλ μκ³κ°μ λμΌλ©΄ Stack Overflowκ° λμ
λ μ΄μ μ§νμ λͺ»νκ³ νλ‘κ·Έλ¨ μμ²΄κ° μ£½μ΄λ²λ¦°λ€.
κ·Έλμ μ체μ μΈ μ€νμ ꡬνν΄μΌνλλ° (ν λ©λͺ¨λ¦¬λ₯Ό μ¨μ νκ³κ°μ΄ ν¨μ¬ νΌ) STLμ stackμ μΌλ€.
κ·Έλ¦Ό3> μ체μ μΈ μ€νμ μ΄μ©ν λΉκ΅μ ν° μ¬μ΄μ¦μ λν μμ±μ°κΈ°.
Scanline μ΄μ©νμ¬ μ±μ°κΈ°.
κ°μ λνμΌλ‘ μ€ννμλ λκ°μ΄ μ±μμ‘λ€.
μ°¨μ΄μ μ΄λΌλ©΄ μνμλλ 0μ΄μ κ°κΉκ² ν¨μ¬ λΉ λ₯΄κ² μ±μμ‘λ€.
μ λ°±κ°λ₯Ό λλ€μΌλ‘ μ°μ΄ μ¬λ°λ₯΄κ² μννλμ§ ν μ€νΈ νλ€.
λνμ λ΄λΆ μΈλΆλ₯Ό μ ꡬλΆνμ¬ μ¬λ°λ₯΄κ² μμΉ μ΄ λμλ€.
Discussion
λκ°μ λνμ λ€λ₯Έ λ λ°©μμΌλ‘ μ±μ μλ μνμκ°
λ λ°©μμ μμμκ°μμ μμ²λ μ°¨μ΄κ° λλ€.
Scanline_fill κ°μ κ²½μ°λ μ§μ μ λ°©μ μμ μ΄μ©ν coherence νΉμ§μ μ΄μ©ν΄μ κ±°μ 0μ΄μ κ°κΉκ² λμμ§λ§
Boundary_fill κ°μ κ²½μ°λ ν½μ
νλμ© μ°μλ λ§λ€ glReadPixelsλ₯Ό νΈμΆνκΈ° λλ¬Έμ κ·Έμ λ°λ₯Έ μ€λ²ν€λ λ° νμ νμ μ²λ¦¬λ₯Ό νκΈ° λλ¬Έμ 21~24μ΄μ κ°κΉμ΄ μκ°μ΄ κ±Έλ Έλ€.(μ€ννλ©΄μ μλ ν° λνμ κ²½μ°)
ꡬνμ μ΄λ €μ λ μ μ glReadPixelsμ yμΈμλ₯Ό μ°½μ Yν¬κΈ°μμ λΊ κ°μ λ£μ΄μ€μΌ μ¬λ°λ₯΄κ² μλνλ κ²μ΄μλ€.
μ΄ κ² λλ¬Έμ μ ꡬνμ μ λ§μ μνμ°©μ€λ₯Ό κ²ͺμλ€.
OPENGLμμλ 맨 μλκ° yμ’ν 0μΈ λ°λ©΄ μλμ°μμμ μ€μ λ‘ λμ€νλ μ΄ λ λλ 맨 μμͺ½μ΄ 0μΌλ‘ μ°νλ€.
Scanline_fill ꡬν μ ,λ μ μ μ§μ μ λ°©μ μμ μ΄μ© y-y1 = (y2-y1)/(x2-x1)(x-x1)
λ μ μ¬μ΄μμ μ€μΊλΌμΈκ°μ 1μ¦κ° νΉμ κ°μ μν¬λ xκ°μ μΆμ ν κ·Έ xκ°μ yμΈλ±μ€μ xμ λ°Έλ₯λ₯Ό λ£μ΄μ£Όκ³
λ€λ₯Έμ λ€μ λν΄μλ μ΄μ κ°μ΄ λ°λ³΅ν μ€μΊλΌμΈμ νΉμ vectorλ₯Ό sortνν pairλ₯Ό μ΄λ£¨κ² νμ¬ μ μ κ·Έμ΄μ£Όμλ€.
μλ μ’ λ μ§κ΄μ μΈ λ°©λ²μΈ μλμμ λΆν° ν½μ
νλνλ κ²μ¬νλ©° μ μ λ§λλ©΄ 그리기 μμνκ³ λ€μ λ§λλ©΄ 그리기λ₯Ό μ€λ¨νλ μμΌλ‘ ν λ €κ³ νμΌλ μκ°λ λ§μ΄ κ±Έλ¦¬κ³ μμΈμ¬νμ΄ λ무 λ§μ΄ λμμ "μ§κ΄μ "μ΄κΈ΄ νμ§λ§ ꡬνμμλ
coherence λ₯Ό μ΄μ©ν λ°©λ²λ³΄λ€ λ λ§μ μκ³ λ‘μμ΄ νμνλ€. (μ€μ λ‘ OPENGLμ μ΄μ©νμ¬ μ μ κ·ΈμΌλ©΄ xμ’νμ κ°λμ λ°λΌ 2κ°μ΄μμ μ μ΄ μ°νλ κ²½μ°κ° μκΈ°λλ¬Έμ μ±
μμ λμ¨ μμΈμ¬ν μΈμλ μκ°ν κ±°λ¦¬κ° λ§λ€.)
Boundary fill μ΄ λνν¬κΈ°μ λ°λΌ μκ°μ΄ λ¬λ¦¬ μμλκΈ΄ νμ§λ§ μμ μ€νμμ 23μ΄μ―μ 걸리λκ²μ λ³΄κ³ μ½κ° μλ¬Έμ μ΄ λλκ²μ΄ , ν¬ν΅ Graphic ν΄μμλ Boundary_fill μ΄λ μμ μ λμ€μ§ μμ Flood_fill κ°μ λ°©λ² λν μ¬μ©ν ν
λ°
μ΄λ»κ² κ·Έλ κ² μ§§μ μκ°μ λ€κ°νμ μΉ ν μ μλμ§ κΆκΈν΄μ‘λ€.
μ΄λ² κ³Όμ λ₯Ό ν΅ν΄ 보λμ€λ‘ STLμμ μ 곡νλ vector λ° stackμ λν΄μ μ’ λ μΉμν΄μ§ μ μμκ³ μμΌ μμ©κ·Έλν½ν΄μ μλν¨μ λλΌκ² λμλ€.