在工程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(); }
六.腳本界面
七.切邊效果演示