zoukankan      html  css  js  c++  java
  • directdraw的图形填充 冷夜

    多边形可以分解为多个三角形,所以只用实现三角形的填充即可实现多边形的填充,三角形主要分为3类:A左边长B右边长C平底或平顶。

    平底或平顶三角形比较简单,填充他们只要分别根据两边的斜率求出Y坐标每增加一个单位相应的X坐标,这样就能求出相应的一对一对左右坐标,然后连接这连个坐标,最后就能实现三角形的填充。

    具体的分析过程请查阅:Windows游戏编程大师技巧 第八章

    效果图:

     

    代码并未经过优化,可能存在很多BUG,只用于演示用

    代码:

    //画平底或平顶填充三角形
    bool CEnginApp::DrawSolidPloygon(ScPoint spoint[],int lenth,UNINT *vb_start, int lpitch)
    {
        if (!vb_start||!spoint||lpitch<=0||lenth<3)
            return false;
        if(lenth==3)
        {
            //将点从小到大排序
            for (int i=0;i<lenth;i++)
            {
                for (int k=i+1;k<lenth;k++)
                {
                    if (spoint[i].x>spoint[k].x)
                    {
                        int temp=spoint[k].x;
                        spoint[k].x=spoint[i].x;
                        spoint[i].x=temp;
    
                        temp=spoint[k].y;
                        spoint[k].y=spoint[i].y;
                        spoint[i].y=temp;
                    }
                }
            }
            if (spoint[0].y!=spoint[2].y)
            {
                if (spoint[0].y==spoint[1].y)//顶点在最右边
                {
                    int temp=spoint[1].x;
                    spoint[1].x=spoint[2].x;
                    spoint[2].x=temp;
    
                    temp=spoint[1].y;
                    spoint[1].y=spoint[2].y;
                    spoint[2].y=temp;
                }
                else if (spoint[1].y==spoint[2].y)//顶点在最左边
                {
                    int temp=spoint[1].x;
                    spoint[1].x=spoint[0].x;
                    spoint[0].x=temp;
    
                    temp=spoint[1].y;
                    spoint[1].y=spoint[0].y;
                    spoint[0].y=temp;
                }
    
            }
            //判断是否是平底或者平顶三角形
            double x0,y0,x1,y1,x2,y2;
            x0=spoint[0].x;
            y0=spoint[0].y;
            x1=spoint[1].x;
            y1=spoint[1].y;
            x2=spoint[2].x;
            y2=spoint[2].y;
    
            double dleft=(x0-x1)/(y0-y1);
            double dright=(x2-x1)/(y2-y1);
    
            if (y0==y2)
            {
                if (y1<y0)//平底
                {
                    int start_y=y1,nowy=y1;
                    int start_x=x1;
                    int addy=y2-y1;
                    int left_x=0,right_x=0;
                    ScPoint point1,point2;
    
                    Plot_Pixel_32(x1,y1,0,255,0,0,vb_start,lpitch);
                    
                    for (int i=1;i<=addy;i++)
                    {
                        nowy++;
                        left_x=start_x+dleft*i;
                        right_x=start_x+dright*i;
                        point1.x=left_x;
                        point1.y=point2.y=nowy;
                        point2.x=right_x;
    
                        Draw_Line2(point1,point2,RGB(0,255,0),vb_start,lpitch);
                    }
                }
                else if (y1>y0)//平顶
                {
                    int start_y=y1,nowy=y1;
                    int start_x=x1;
                    int addy=y1-y0;
                    int left_x=0,right_x=0;
                    ScPoint point1,point2;
    
                    Plot_Pixel_32(x1,y1,0,255,0,0,vb_start,lpitch);
    
                    for (int i=1;i<=addy;i++)
                    {
                        nowy--;
                        left_x=start_x-dleft*i;
                        right_x=start_x-dright*i;
                        point1.x=left_x;
                        point1.y=point2.y=nowy;
                        point2.x=right_x;
    
                        Draw_Line2(point1,point2,RGB(0,255,0),vb_start,lpitch);
                    }
                }
            }
    
    
        }
    
        return true;
    }
    ////画右边长或左边长三角形填充图形
    bool CEnginApp::DrawNotFlatPloygon(ScPoint spoint[],int lenth,UNINT *vb_start, int lpitch)
    {
        if (!vb_start||!spoint||lpitch<=0||lenth<3)
            return false;
    
        if(lenth==3)
        {
            //将点从小到大排序
            for (int i=0;i<lenth;i++)
            {
                for (int k=i+1;k<lenth;k++)
                {
                    if (spoint[i].x>spoint[k].x)
                    {
                        int temp=spoint[k].x;
                        spoint[k].x=spoint[i].x;
                        spoint[i].x=temp;
    
                        temp=spoint[k].y;
                        spoint[k].y=spoint[i].y;
                        spoint[i].y=temp;
                    }
                }
            }
            //判断是否是平底或者平顶三角形
            double x0,y0,x1,y1,x2,y2;
            x0=spoint[0].x;
            y0=spoint[0].y;
            x1=spoint[1].x;
            y1=spoint[1].y;
            x2=spoint[2].x;
            y2=spoint[2].y;
    
            if (y0==y2)//是平底或者平顶
            {
                DrawSolidPloygon(spoint,lenth,vb_start,lpitch);
            }else//左边长或右边长
            {
                float k,b,dx,dy;
                ScPoint jPoint;
                if (y2>y0)//右边长
                {
                    dy=y2-y1;
                    dx=x2-x1;
                    k=dx/dy;
                    b=(y1+y2-k*(x1+x2))/2;
                    jPoint.y=y0;
                    jPoint.x=(jPoint.y-b)/k;
    
                    ScPoint dpoint[3];
                    dpoint[0].x=spoint[0].x;
                    dpoint[0].y=spoint[0].y;
                    dpoint[1].x=spoint[1].x;
                    dpoint[1].y=spoint[1].y;
                    dpoint[2].x=jPoint.x;
                    dpoint[2].y=jPoint.y;
                    DrawSolidPloygon(dpoint,3,vb_start,lpitch);
    
                    dpoint[0].x=spoint[0].x;
                    dpoint[0].y=spoint[0].y;
                    dpoint[2].x=spoint[2].x;
                    dpoint[2].y=spoint[2].y;
                    dpoint[1].x=jPoint.x;
                    dpoint[1].y=jPoint.y;
                    DrawSolidPloygon(dpoint,3,vb_start,lpitch);
                }else//左边长
                {
                    dy=y1-y0;
                    dx=x1-x0;
                    k=dx/dy;
                    b=(y1+y0-k*(x1+x0))/2;
                    jPoint.y=y2;
                    jPoint.x=(jPoint.y-b)/k;
    
                    ScPoint dpoint[3];
                    dpoint[2].x=spoint[2].x;
                    dpoint[2].y=spoint[2].y;
                    dpoint[1].x=spoint[1].x;
                    dpoint[1].y=spoint[1].y;
                    dpoint[0].x=jPoint.x;
                    dpoint[0].y=jPoint.y;
                    DrawSolidPloygon(dpoint,3,vb_start,lpitch);
    
                    dpoint[0].x=spoint[0].x;
                    dpoint[0].y=spoint[0].y;
                    dpoint[2].x=spoint[2].x;
                    dpoint[2].y=spoint[2].y;
                    dpoint[1].x=jPoint.x;
                    dpoint[1].y=jPoint.y;
                    DrawSolidPloygon(dpoint,3,vb_start,lpitch);
                }
    
    
            }
        }
        return true;
    }
  • 相关阅读:
    命令行程序如何获取HINSTANCE?
    解决C++项目使用sqlite中文乱码问题
    第三章 CLR如何解析引用类型
    第二章 生成、打包、部署和管理应用程序及类型
    第一章 CLR执行模型
    如何快速提升自己硬实力
    前端优化
    Eureka的工作原理以及它与ZooKeeper的区别
    单链表反转
    链表中head->next = p;和p=head->next;之间的区别
  • 原文地址:https://www.cnblogs.com/gamesky/p/2673118.html
Copyright © 2011-2022 走看看