扫描线填充算法,单链表实现

扫描线填充算法

合并NET至AET

typedef struct ET
{
    float x;
    float dx;
    float ymax;
    ET* next;
}NET,AET;

建立NET表

//等间距且为i=1的扫描线
    for (int i = 0; i < Ymax; i++)
    {
        //pNET[i] ->next = NULL;
        for (int j = 0; j < numofpoint; j++)
        {
            if (polypoint[j].y == i)
            {
                NET *rear = pNET[i];                //设置尾指针
                if (polypoint[(j - 1 + numofpoint) % numofpoint].y>polypoint[j].y)
                {
                    NET *p1 = new NET;
                    p1->x = polypoint[j].x;         //
                    p1->dx = (polypoint[(j - 1 + numofpoint) % numofpoint].x - polypoint[j].x) / (polypoint[(j - 1 + numofpoint) % numofpoint].y - polypoint[j].y);     
                    p1->ymax = polypoint[(j - 1 + numofpoint)%numofpoint].y;
                    //表头插入法
                    //p1->next = pNET[i]->next;     //将将待插入的节点的后置节点指向头结点后的节点
                    //pNET[i]->next = p1;           //将头结点的后置节点指向新节点,即新节点连到表头
                    //表尾插入法
                    rear->next = p1;                //将新节点连到链尾
                    rear = p1;                      //尾指针后移
                    rear->next = NULL;              //链表最后的尾节点的后继指针置空
                }
                if (polypoint[(j + 1 + numofpoint) % numofpoint].y>polypoint[j].y)
                {
                    NET *p2 = new NET;
                    p2->x = polypoint[j].x;
                    p2->dx = (polypoint[j].x - polypoint[(j + 1 + numofpoint) % numofpoint].x) / (polypoint[j].y - polypoint[(j + 1 + numofpoint) % numofpoint].y);
                    p2->ymax = polypoint[(j + 1 + numofpoint) % numofpoint].y;
                    //表头法
                    //p2->next = pNET[i]->next;
                    //pNET[i]->next = p2;
                    //表尾法
                    rear->next = p2;
                    rear = p2;
                    rear->next = NULL;
                }
            }

        }
    }

建立AET表

    //标记NETYmin,并使得AET从这开始。
    for (int i = 0; i <= Ymax; i++)
    {
        if (pNET[i]->next!=NULL)
        {
            Ymin = i;
            break;
        }

    }
    //NET转换为AET
    for (int i = Ymin; i <= Ymax; i++)
    {

        NET *np = pNET[i]->next;

        //AET* ap = new AET;
        //ap->next = NULL;
        //把NET表中y类结点非空的数据移入AET
        while (np)
        {
            AET *p = new AET;
            p->x = np->x;
            p->dx = np->dx;
            p->ymax = np->ymax;
            p->next = pAET[i]->next;
            pAET[i]->next= p;
            np = np->next;
        }
        //首先考虑是否有与多边形的新交点,通过前射线的x+dx判断。
        AET *ap = pAET[i-1]->next;
        while (ap)
        {
            AET *p = new AET;
            p->x = ap->x + ap->dx;
            p->dx = ap->dx;
            p->ymax = ap->ymax;
            if (p->ymax == i)   //当ymax == Y时,舍去这个点。因为每条边被看作下闭上开的
            {
                delete p;
            }
            else
            {
                p->next = pAET[i]->next;
                pAET[i]->next = p;
            }
            ap = ap->next;
        }

AET表还未排序

AET* InsertSort(AET*& head)
{
    if (head ==NULL)
    {
        return head;
    }

    AET* pmax = head;
    //第一次指向第二个元素  
    AET* work = head->next;
    while (work)
    {
        // 将work插入到head位置  
        if (work->x < head->x)
        {
            pmax->next = work->next;
            work->next = head;
            head = work;
        }
        else if (work->x == head->x)
        {
            if (work->dx < head->dx)
            {
                pmax->next = work->next;
                work->next = head;
                head = work;
            }
        }
        // 将数据插入到中间  
        else if (work->x > head->x && work->x < pmax->x)
        {
            AET* bg = head;
            AET* pre = NULL;
            while (bg && bg->x < work->x )
            {
                pre = bg;
                bg = bg->next;
            }
            if (bg->x == work->x)
            {
                pre = bg;
                bg = bg->next;
            }
            pmax->next = work->next;
            work->next = bg;
            pre->next = work;
        }
        else
            pmax = work;                    //直接前移  
        work = pmax->next;
    }
    return head;
}

【1】:维基百科介绍
【2】:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值