弱弱的求助一个

linqunyan 2007-05-18 02:13:39

POINT Point[1000000];
int count=100000;
int I=0;
void CSMXView::OnRButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

CView::OnRButtonDown(nFlags, point);
CClientDC dc(this);
Point[I] = point;
if(I == 0)
dc.MoveTo(Point[I]);
else
dc.MoveTo(Point[I-1]);
dc.LineTo(Point[I]);
I++;

}



void CSMXView::OnLButtonDown(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default

CView::OnLButtonDown(nFlags, point);
CClientDC dc(this);
dc.MoveTo(Point[I-1]);
dc.LineTo(Point[0]);
}

void DrawLine(int x,int i,int y,int j,CDC* pDC,int nColor)
{
pDC->MoveTo(Point[i]);
pDC->LineTo(Point[i]);
}

// 参数:
// lpPoints: 指向顶点坐标数组的指针,数组类型为POINT,多边形由它们顺次封闭连接得到
// nCount: 顶点的个数
// nColor: 填充的颜色 默认为黑色
// pDC: 设备句柄指针
//////////////////////////////////////////////////////////////////////////////////////////////////
void FillPolygon(LPPOINT lpPoints,int nCount, CDC *pDC, int nColor/*=0*/)
{
// 检查参数合法性
//ASSERT_VALID( CDC*pDC);
ASSERT(lpPoints);
ASSERT(nCount>2);
ASSERT(nColor>=0);

// 边结构数据类型
typedef struct Edge{
int ymax; // 边的最大y坐标
float x; // 与当前扫描线的交点x坐标
float dx; // 边所在直线斜率的倒数
struct Edge * pNext; // 指向下一条边
}Edge, * LPEdge;

int i=0,j=0,k=0;
int y0=0,y1=0; // 扫描线的最大和最小y坐标
LPEdge pAET=NULL; // 活化边表头指针
LPEdge * pET=NULL; // 边表头指针

pAET=new Edge; // 初始化表头指针,第一个元素不用
pAET->pNext=NULL;

// 获取y方向扫描线边界
y0=y1=lpPoints[0].y;
for(i=1;i<nCount;i++)
{
if(lpPoints[i].y<y0)
y0=lpPoints[i].y;
else if(lpPoints[i].y>y1)
y1=lpPoints[i].y;
}
if(y0>=y1) return;

// 初始化边表,第一个元素不用
pET=new LPEdge[y1-y0+1];
for(i=0;i<=y1-y0;i++)
{
pET[i]= new Edge;
pET[i]->pNext=NULL;
}

for(i=0;i<nCount;i++)
{
j=(i+1)%nCount; // 组成边的下一点
if(lpPoints[i].y != lpPoints[j].y)// 如果该边不是水平的则加入边表
{
LPEdge peg; // 指向该边的指针
LPEdge ppeg; // 指向边指针的指针

// 构造边
peg =new Edge;
k=(lpPoints[i].y>lpPoints[j].y)?i:j;
peg->ymax=lpPoints[k].y; // 该边最大y坐标
k=(k==j)?i:j;
peg->x=(float)lpPoints[k].x; // 该边与扫描线焦点x坐标
if(lpPoints[i].y != lpPoints[j].y)
peg->dx=(float)(lpPoints[i].x-lpPoints[j].x)/(lpPoints[i].y-lpPoints[j].y);// 该边斜率的倒数
peg->pNext=NULL;

// 插入边
ppeg=pET[lpPoints[k].y-y0];
while(ppeg->pNext)
ppeg=ppeg->pNext;
ppeg->pNext=peg;
}// end if
}// end for i

// 扫描
for(i=y0;i<=y1;i++)
{
LPEdge peg0=pET[i-y0]->pNext;
LPEdge peg1=pET[i-y0];
if(peg0)// 有新边加入
{
while(peg1->pNext)
peg1=peg1->pNext;
peg1->pNext=pAET->pNext;
pAET->pNext=peg0;
}

// 按照x递增排序pAET
peg0=pAET;
while(peg0->pNext)
{
LPEdge pegmax=peg0;
LPEdge peg1=peg0;
LPEdge pegi=NULL;

while(peg1->pNext)
{
if(peg1->pNext->x>pegmax->pNext->x)
pegmax=peg1;
peg1=peg1->pNext;
}
pegi=pegmax->pNext;
pegmax->pNext=pegi->pNext;
pegi->pNext=pAET->pNext;
pAET->pNext=pegi;
if(peg0 == pAET)
peg0=pegi;
}

// 遍历活边表,画线
peg0=pAET;
while(peg0->pNext)
{
if(peg0->pNext->pNext)
{
DrawLine((int)peg0->pNext->x,i,(int)peg0->pNext->pNext->x,i,pDC,nColor);
peg0=peg0->pNext->pNext;
}
else
break;
}

// 把ymax=i的节点从活边表删除并把每个节点的x值递增dx
peg0=pAET;
while(peg0->pNext)
{
if(peg0->pNext->ymax < i+2)
{
peg1=peg0->pNext;
peg0->pNext=peg0->pNext->pNext; //删除
delete peg1;
continue;
}
peg0->pNext->x+=peg0->pNext->dx; //把每个节点的x值递增dx
peg0=peg0->pNext;
}
}

// 删除边表
for(i=0;i<y1-y0;i++)
if(pET[i])
delete pET[i];
if(pAET)
delete pAET;
if(pET)
delete[] pET;
}



void CSMXView::Onsaomiao()
{
// TODO: Add your command handler code here
CDC *pDC;
LPPOINT P=Point;
FillPolygon(P, 1000000, pDC, 23);

}

构件出.exe文件后可以花出一个多边形
当时不能对多边形画线
好像是指针有错误
哪位达人给看看
...全文
296 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
zottff 2007-05-18
  • 打赏
  • 举报
回复
void CSMXView::Onsaomiao()
{
// TODO: Add your command handler code here
CDC *pDC; //<------这个变量没有初始化
LPPOINT P=Point;
FillPolygon(P, 1000000, pDC, 23);

}
shawnwan 2007-05-18
  • 打赏
  • 举报
回复
学习下
linqunyan 2007-05-18
  • 打赏
  • 举报
回复
这个是图形学里面
扫描线填充算法

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧