七巧板复原之匹配算法之代码实现

因为各种原因,想顺着我的开发思路写,但是现在感觉这么写太啰嗦了,直接写核心代码吧。
算法依然是之前的小文的算法,通过代码验证算法是可行的,并没有太大的疏漏。根据代码吧算法又进行了归纳,流程图如下:
在这里插入图片描述
说明:Box表示盛放七巧板的盒子多边形,part是七巧板部件。上面的算法没有进行优化,例如正方形的部件实际上各边是一样的,不用测试其余边。
代码如下:

       public static bool MatchPolygon(TangramPolygon partPlg, out TangramPolygon outPart, Control ctrl = null)
        {

            //1# get the first vertex of the boxPlg and calculate the angle between xAxis and the first side fo the boxPlg
            double boxAngle, partAngle;

            // from the first point of the boxPlg
            var boxPlg = partPlg.usingBoxPlg;
            outPart = boxPlg;
            int boxIdx = boxPlg.firstPntIdx;
            boxAngle = GetAngleToXaxis(boxPlg.GetVertexPoint(boxIdx), boxPlg.GetNextVertexPoint(boxIdx));
            bool bAllInBox = false;
            int i;
            for (i = partPlg.usingIdx; i < partPlg.Count(); i++)
            {


                TangramPolygon partPlgCpy = new TangramPolygon(partPlg.m_OrgPointArr);
                var pntA = partPlgCpy.GetVertex(i).m_Point;
                var pntB = partPlgCpy.GetNextVertex(i).m_Point;
                partAngle = GetAngleToXaxis(pntA, pntB);
                //partAngle = GetAngleToXaxis(partPlgCpy.GetOrgPoint(i), partPlgCpy.GetNextOrgPoint(i));
                double rotA = boxAngle - partAngle;
                partPlgCpy = CMyPolygonTool.Rotate(partPlgCpy,boxPlg.GetVertexPoint(boxPlg.firstPntIdx), i, rotA);
                //set the first point to i 
                if (ctrl != null)
                {
                    ctrl.Refresh();
                    partPlgCpy.DrawPolygon(ctrl, Color.Red);
                    //MessageBox.Show("Testing ");


                }
                // 

                //check if the part is in the main Box 
                bool bInBox = true;
                int segIdx = 0;
                for (int j = 0; j < partPlgCpy.Count(); j++)
                {
                    PointF pnt1 = partPlgCpy.GetVertexPoint(segIdx);
                    PointF pnt2 = partPlgCpy.GetNextVertexPoint(segIdx);
                    if (ctrl != null)
                    {
                        Graphics g = ctrl.CreateGraphics();
                        SolidBrush brsh = new SolidBrush(Color.Yellow);
                        Pen pen = new Pen(brsh, 3);
                        g.DrawLine(pen, pnt1, pnt2);
                    }
                  
                    if (!boxPlg.SegInsidePlg(new Segment(pnt1, pnt2), boxPlg))
                    {
                        bInBox = false;
                        break;
                    }
                    segIdx = partPlgCpy.GetVertex(segIdx).next_idx;
                }
                if (bInBox)
                {
                    outPart = partPlgCpy;
                    bAllInBox = true;
                    break;
                }

            }
            partPlg.usingIdx = i;
            return bAllInBox;

        }

里面包含了调试代码。
另外这种匹配方式,不能完全匹配所有的可能性,改匹配方式是匹配各自多边形的左下部分,如图示:
在这里插入图片描述

上述方法不能匹配图中红的部分,尽管在匹配的迭代过程中,这过程可能会因为其他形状匹配之后,可以使红色方块出现在上图的位置上,但是算法上并没有保证。
几个子函数的说明:
1、计算指定边到X轴的角度,顺时针为正角度,反正负角度。

GetAngleToXaxis(boxPlg.GetVertexPoint(boxIdx), boxPlg.GetNextVertexPoint(boxIdx));

2、多边形旋转

Rotate(partPlgCpy,boxPlg.GetVertexPoint(boxPlg.firstPntIdx), i, rotA);

3、线段是否在多边形内部(包括边上)

SegInsidePlg(new Segment(pnt1, pnt2), boxPlg))

其余函数是GDI函数。

计算剩余区域的算法和函数,准备在下一文介绍、

MaraSun 2022-05-12 BJFWDQ
南丁格尔节
汶川地震日
中国清零进行中
北京慢慢进入上海状态

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值