PCB 圆形板切边算法 实现

在工程CAM处理圆形拼板是个头疼的问题,需人工程师自行设计切边 知足能够拼板而且拼板后锣板板边没有内角,否则会影响装配算法

 

1.原始单 PCS圆形板ide

    此外形若是不采用邮票孔链接的话,采V-CUT链接须采用切边处理spa

     

 二.下图为切边处理后的图形 设计

      这个图形就是接下来算法要生成的图形了code

     

 三.下图为拼好的SETorm

      这样是为了拼SET后没有内角,不影响装配blog

         

       再来一张大图拼好后的SETget

        

四.求解思路string

五.代码实现:it

 private void btnAdd_Click(object sender, EventArgs e)
        {
            g.COM("units,type=mm");
            d2 calc2 = new d2();
            d1 calc1 = new d1();
            string layer = "gko";
            string errinfo = "";
            bool isExist = g.Check_Layer_Exist(layer, g.JOB, g.STEP);
            if (!isExist)
            {
                errinfo = "gko层不存成";
                MessageBox.Show(errinfo, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            g.SetWorkLayer(layer);
            double ShaveVal = double.Parse(txtShave.Text);
            double RoutDiVal = double.Parse(txtRoutVal.Text);
            double ConnectWidth = double.Parse(txtConnectWidth.Text);
            double InnerDi = double.Parse(txtInnerDi.Text);
            
            add addCom = new add();
            gLayer layerData = g.getFEATURES(layer, g.STEP, g.JOB);
            List<gA> ACircleList = new List<gA>();
            double CircleRMax = 0;
            if (layerData.Alist.Count > 0)
            {
                List<gA> Alist = layerData.Alist.OrderByDescending(tt => calc2.p2p_di(tt.pc, tt.ps)).ToList();
                ACircleList.Add(Alist[0]);
                CircleRMax = calc2.p2p_di(Alist[0].pc, Alist[0].ps);
                for (int i = 1; i < Alist.Count; i++)
                {
                    double p2p_di = calc2.p2p_di(Alist[i - 1].pc, Alist[i].pc);
                    double CircleRCurrent = calc2.p2p_di(Alist[i].pc, Alist[i].ps);
                    if (p2p_di > 0.01 || Math.Abs(CircleRMax - CircleRCurrent) > 0.01)
                        break;
                    ACircleList.Add(Alist[i]);
                }
            }
            else
            {
                errinfo = "未检测到弧";
                MessageBox.Show(errinfo, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            double LineWidth;
            var StrLineWidth = ACircleList[0].symbols.Replace("r", "");
            if (!(double.TryParse(StrLineWidth, out LineWidth)))
                LineWidth = 151;
            double ShaveDiDirection = CircleRMax - ShaveVal;
            arc_data ShaveArcData = calc1.arc_半径与弓高(CircleRMax, ShaveVal);
            if (ConnectWidth > ShaveArcData.D弦长)
            {
                errinfo = "链接位长度不能大于弦长";
                MessageBox.Show(errinfo, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            bool isArc = true; //默认按头尾倒圆角
            double RoutDiDirection = CircleRMax - (ShaveVal + RoutDiVal * 0.5);
            arc_data RoutArcData = calc1.arc_半径与弓高(CircleRMax, (ShaveVal + RoutDiVal * 0.5));
            for (int i = 0; i < 4; i++)  //{ 0, 90, 180, 270 };
            {
                if (!chkTB.Checked) //1 3
                {
                    if (i == 1 || i == 3)
                        continue;
                }
                if (!chkLR.Checked)//0 2
                {
                    if (i == 0 || i == 2)
                        continue;
                }
                double DirectionAng = g.ang_list[i];
                double P1Di = CircleRMax;
                double P1Ang = ShaveArcData.a圆心角 * 0.5;
                gPoint p1s = calc2.p_val_ang(ACircleList[0].pc, P1Di, DirectionAng - P1Ang);
                gPoint p1e = calc2.p_val_ang(ACircleList[0].pc, P1Di, DirectionAng + P1Ang);
                double P2Di = Math.Sqrt(Math.Pow(ShaveDiDirection, 2) + (Math.Pow((ConnectWidth + RoutDiVal) * 0.5, 2)));
                double P2Ang = calc1.side3_angle(ShaveDiDirection, (ConnectWidth + RoutDiVal) * 0.5, P2Di, 2);
                gPoint p2s = calc2.p_val_ang(ACircleList[0].pc, P2Di, DirectionAng - P2Ang);
                gPoint p2e = calc2.p_val_ang(ACircleList[0].pc, P2Di, DirectionAng + P2Ang);
                double P3Di = Math.Sqrt(Math.Pow(ShaveDiDirection, 2) + (Math.Pow(ConnectWidth * 0.5, 2)));
                double P3Ang = calc1.side3_angle(ShaveDiDirection, ConnectWidth * 0.5, P3Di, 2);
                gPoint p3s = calc2.p_val_ang(ACircleList[0].pc, P3Di, DirectionAng - P3Ang);
                gPoint p3e = calc2.p_val_ang(ACircleList[0].pc, P3Di, DirectionAng + P3Ang);
                double P4Di = CircleRMax;
                double P4Ang = RoutArcData.a圆心角 * 0.5;
                gPoint p4s = calc2.p_val_ang(ACircleList[0].pc, P4Di, DirectionAng - P4Ang);
                gPoint p4e = calc2.p_val_ang(ACircleList[0].pc, P4Di, DirectionAng + P4Ang);
                double P5Di = Math.Sqrt(Math.Pow(RoutDiDirection, 2) + (Math.Pow((ConnectWidth + RoutDiVal) * 0.5, 2)));
                double P5Ang = calc1.side3_angle(RoutDiDirection, (ConnectWidth + RoutDiVal) * 0.5, P5Di, 2);
                gPoint p5s = calc2.p_val_ang(ACircleList[0].pc, P5Di, DirectionAng - P5Ang);
                gPoint p5e = calc2.p_val_ang(ACircleList[0].pc, P5Di, DirectionAng + P5Ang);
                if (calc2.p2p_di(ACircleList[0].pc, p5s) > CircleRMax)
                {
                    p5s = p4s;
                    p5e = p4e;
                }
                List<gSur_Point> polyList = new List<gSur_Point>();
                if (isArc)
                {
                    var arc1 = calc2.l2a__Round(new gL(p4s, p5s, LineWidth), ACircleList[0], InnerDi * 0.5, 0.5, 1);
                    polyList.Add(new gSur_Point(arc1.a.pe, 0));
                    polyList.Add(new gSur_Point(arc1.a.pc, 2));
                    polyList.Add(new gSur_Point(arc1.a.ps, 0));
                }
                else
                {
                    polyList.Add(new gSur_Point(p4s, 0));
                }
                polyList.Add(new gSur_Point(p5s, 0));
                polyList.Add(new gSur_Point(p2s, 1));
                polyList.Add(new gSur_Point(p3s, 0));
                polyList.Add(new gSur_Point(p3e, 0));
                polyList.Add(new gSur_Point(p2e, 1));
                polyList.Add(new gSur_Point(p5e, 0));
                if (isArc)
                {
                    var arc2 = calc2.l2a__Round(new gL(p5e, p4e, LineWidth), ACircleList[0], InnerDi*0.5, 0.5, 2);
                    polyList.Add(new gSur_Point(arc2.a.pe, 0));
                    polyList.Add(new gSur_Point(arc2.a.pc, 2));
                    polyList.Add(new gSur_Point(arc2.a.ps, 0));
                }
                else
                {
                    polyList.Add(new gSur_Point(p4e, 0));
                }
                addCom.line_poly_AL(polyList, LineWidth);
            }
            g.COM("sel_extend_slots,mode=ext_by,size=500,from=center");
            for (int i = 0; i < 2; i++)  //防止重复线,再次执行
            {
                if (chkTB.Checked) //1 3
                {
                    g.COM($"delete_feat, mode = intersect,x={ACircleList[0].pc.x }, y={ACircleList[0].pc.y + CircleRMax}, tol=10", true);
                    g.COM($"delete_feat, mode = intersect,x={ACircleList[0].pc.x }, y={ACircleList[0].pc.y - CircleRMax}, tol=10", true);
                }
                if (chkLR.Checked)//0 2
                {
                    g.COM($"delete_feat, mode = intersect,x={ACircleList[0].pc.x + CircleRMax}, y={ACircleList[0].pc.y}, tol=10", true);
                    g.COM($"delete_feat, mode = intersect,x={ACircleList[0].pc.x - CircleRMax}, y={ACircleList[0].pc.y}, tol=10", true);
                }
            }
            g.COM("sel_extend_slots,mode=ext_by,size=-500,from=center");
            g.COM("sel_design2rout,det_tol=25.4,con_tol=25.4,rad_tol=2.54");
            MessageBox.Show("执行完成", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
            Application.Exit();
        }
View Code

六.脚本界面 

七.切边效果演示