| void CCGPainterView::ScanLineFillConvert(CDC* pDC, CPoint startPoint, COLORREF fillCol, COLORREF boundaryCol) |
| { |
| |
| typedef struct XET |
| { |
| double x; |
| double dx, ymax; |
| XET* next; |
| }AET, NET; |
| |
| int vertNum = ThePolygon.m_VerticeNumber; |
| |
| int MaxY = ThePolygon.m_Vertex[0].y; |
| int MinY = ThePolygon.m_Vertex[0].y; |
| int i; |
| for (i = 1; i < vertNum; i++) { |
| if (ThePolygon.m_Vertex[i].y > MaxY) |
| MaxY = ThePolygon.m_Vertex[i].y; |
| |
| if (MinY > ThePolygon.m_Vertex[i].y) |
| MinY = ThePolygon.m_Vertex[i].y; |
| } |
| |
| AET* pAET = new AET; |
| pAET->next = NULL; |
| |
| NET* pNET[1024]; |
| for (i = 0; i <= MaxY; i++) { |
| pNET[i] = new NET; |
| pNET[i]->dx = 0; |
| pNET[i]->x = 0; |
| pNET[i]->ymax = 0; |
| pNET[i]->next = NULL; |
| } |
| |
| for (i = MinY; i <= MaxY; i++) { |
| |
| for (int j = 0; j < vertNum; j++) |
| |
| * 如果在上方,就记录在边表中,并且是头插法记录,结点并没有按照 x 值进行排序,毕竟在更新 AET 的时候还要重新排一次 |
| * 所以 NET 表可以暂时不排序 |
| */ |
| if (ThePolygon.m_Vertex[j].y == i) { |
| |
| if (ThePolygon.m_Vertex[(j - 1 + vertNum) % vertNum].y > ThePolygon.m_Vertex[j].y) { |
| NET* p = new NET; |
| p->x = ThePolygon.m_Vertex[j].x; |
| p->ymax = ThePolygon.m_Vertex[(j - 1 + vertNum) % vertNum].y; |
| p->dx = double((ThePolygon.m_Vertex[(j - 1 + vertNum) % vertNum].x - ThePolygon.m_Vertex[j].x)) / double((ThePolygon.m_Vertex[(j - 1 + vertNum) % vertNum].y - ThePolygon.m_Vertex[j].y)); |
| p->next = pNET[i]->next; |
| pNET[i]->next = p; |
| } |
| |
| if (ThePolygon.m_Vertex[(j + 1 + vertNum) % vertNum].y > ThePolygon.m_Vertex[j].y) { |
| NET* p = new NET; |
| p->x = ThePolygon.m_Vertex[j].x; |
| p->ymax = ThePolygon.m_Vertex[(j + 1 + vertNum) % vertNum].y; |
| p->dx = double((ThePolygon.m_Vertex[(j + 1 + vertNum) % vertNum].x - ThePolygon.m_Vertex[j].x)) / double((ThePolygon.m_Vertex[(j + 1 + vertNum) % vertNum].y - ThePolygon.m_Vertex[j].y)); |
| p->next = pNET[i]->next; |
| pNET[i]->next = p; |
| } |
| } |
| } |
| |
| for (i = MinY; i <= MaxY; i++) { |
| |
| NET* p = pAET->next; |
| while (p) { |
| p->x = p->x + p->dx; |
| p = p->next; |
| } |
| |
| AET* tq = pAET; |
| p = pAET->next; |
| tq->next = NULL; |
| while (p) { |
| while (tq->next && p->x >= tq->next->x) |
| tq = tq->next; |
| NET* s = p->next; |
| p->next = tq->next; |
| tq->next = p; |
| p = s; |
| tq = pAET; |
| } |
| |
| AET* q = pAET; |
| p = q->next; |
| while (p) { |
| if (p->ymax == i) { |
| q->next = p->next; |
| delete p; |
| p = q->next; |
| } |
| else { |
| q = q->next; |
| p = q->next; |
| } |
| } |
| |
| p = pNET[i]->next; |
| q = pAET; |
| while (p) { |
| while (q->next && p->x >= q->next->x) |
| q = q->next; |
| NET* s = p->next; |
| p->next = q->next; |
| q->next = p; |
| p = s; |
| q = pAET; |
| } |
| |
| |
| p = pAET->next; |
| while (p && p->next) { |
| for (float j = p->x; j <= p->next->x; j++) { |
| pDC->SetPixel(static_cast<int>(j), i, fillCol); |
| } |
| p = p->next->next; |
| } |
| } |
| } |