PCB 圆形板切边算法 实现
在工程CAM处理圆形拼板是个头疼的问题,需人工程师自行设计切边 满足可以拼板并且拼板后锣板板边没有内角,不然会影响装配
1.原始单 PCS圆形板
此外形如果不采用邮票孔连接的话,采V-CUT连接须采用切边处理

二.下图为切边处理后的图形
这个图形就是接下来算法要生成的图形了

三.下图为拼好的SET
这样是为了拼SET后没有内角,不影响装配

再来一张大图拼好后的SET

四.求解思路

五.代码实现:
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 = ;
if (layerData.Alist.Count > )
{
List<gA> Alist = layerData.Alist.OrderByDescending(tt => calc2.p2p_di(tt.pc, tt.ps)).ToList();
ACircleList.Add(Alist[]);
CircleRMax = calc2.p2p_di(Alist[].pc, Alist[].ps);
for (int i = ; i < Alist.Count; i++)
{
double p2p_di = calc2.p2p_di(Alist[i - ].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[].symbols.Replace("r", "");
if (!(double.TryParse(StrLineWidth, out LineWidth)))
LineWidth = ;
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 = ; i < ; i++) //{ 0, 90, 180, 270 };
{
if (!chkTB.Checked) //1 3
{
if (i == || i == )
continue;
}
if (!chkLR.Checked)//0 2
{
if (i == || i == )
continue;
}
double DirectionAng = g.ang_list[i];
double P1Di = CircleRMax;
double P1Ang = ShaveArcData.a圆心角 * 0.5;
gPoint p1s = calc2.p_val_ang(ACircleList[].pc, P1Di, DirectionAng - P1Ang);
gPoint p1e = calc2.p_val_ang(ACircleList[].pc, P1Di, DirectionAng + P1Ang);
double P2Di = Math.Sqrt(Math.Pow(ShaveDiDirection, ) + (Math.Pow((ConnectWidth + RoutDiVal) * 0.5, )));
double P2Ang = calc1.side3_angle(ShaveDiDirection, (ConnectWidth + RoutDiVal) * 0.5, P2Di, );
gPoint p2s = calc2.p_val_ang(ACircleList[].pc, P2Di, DirectionAng - P2Ang);
gPoint p2e = calc2.p_val_ang(ACircleList[].pc, P2Di, DirectionAng + P2Ang);
double P3Di = Math.Sqrt(Math.Pow(ShaveDiDirection, ) + (Math.Pow(ConnectWidth * 0.5, )));
double P3Ang = calc1.side3_angle(ShaveDiDirection, ConnectWidth * 0.5, P3Di, );
gPoint p3s = calc2.p_val_ang(ACircleList[].pc, P3Di, DirectionAng - P3Ang);
gPoint p3e = calc2.p_val_ang(ACircleList[].pc, P3Di, DirectionAng + P3Ang);
double P4Di = CircleRMax;
double P4Ang = RoutArcData.a圆心角 * 0.5;
gPoint p4s = calc2.p_val_ang(ACircleList[].pc, P4Di, DirectionAng - P4Ang);
gPoint p4e = calc2.p_val_ang(ACircleList[].pc, P4Di, DirectionAng + P4Ang);
double P5Di = Math.Sqrt(Math.Pow(RoutDiDirection, ) + (Math.Pow((ConnectWidth + RoutDiVal) * 0.5, )));
double P5Ang = calc1.side3_angle(RoutDiDirection, (ConnectWidth + RoutDiVal) * 0.5, P5Di, );
gPoint p5s = calc2.p_val_ang(ACircleList[].pc, P5Di, DirectionAng - P5Ang);
gPoint p5e = calc2.p_val_ang(ACircleList[].pc, P5Di, DirectionAng + P5Ang);
if (calc2.p2p_di(ACircleList[].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[], InnerDi * 0.5, 0.5, );
polyList.Add(new gSur_Point(arc1.a.pe, ));
polyList.Add(new gSur_Point(arc1.a.pc, ));
polyList.Add(new gSur_Point(arc1.a.ps, ));
}
else
{
polyList.Add(new gSur_Point(p4s, ));
}
polyList.Add(new gSur_Point(p5s, ));
polyList.Add(new gSur_Point(p2s, ));
polyList.Add(new gSur_Point(p3s, ));
polyList.Add(new gSur_Point(p3e, ));
polyList.Add(new gSur_Point(p2e, ));
polyList.Add(new gSur_Point(p5e, ));
if (isArc)
{
var arc2 = calc2.l2a__Round(new gL(p5e, p4e, LineWidth), ACircleList[], InnerDi*0.5, 0.5, );
polyList.Add(new gSur_Point(arc2.a.pe, ));
polyList.Add(new gSur_Point(arc2.a.pc, ));
polyList.Add(new gSur_Point(arc2.a.ps, ));
}
else
{
polyList.Add(new gSur_Point(p4e, ));
}
addCom.line_poly_AL(polyList, LineWidth);
}
g.COM("sel_extend_slots,mode=ext_by,size=500,from=center");
for (int i = ; i < ; 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();
}
六.脚本界面

七.切边效果演示

PCB 圆形板切边算法 实现的更多相关文章
- PCB Genesis SET拼板(圆形板拼板) 实现效果(二)
越来发现Genesis采用Surface多边形数据结构的重要性了,当撑握了多边形缩放,交集, 差集,并集等算法, 想实现PCB拼板简直轻而易举了;当然借助多边形算法可以开发出更多的PCB实用的工具出来 ...
- PCB抄板评估需要关注的因素
减少PCB抄板的反复是可能的,但这依赖于抄板前期工作的完成情况.多数时候,越是到产品抄板的后期越容易发现问题,更为痛苦的是要针对发现的问题进行更改.然而,尽管许多人都清楚这个经验法则,但实际情况却是另 ...
- PCB 锣板和半孔工艺的差别
PCB 锣板和半孔工艺的差别 PCB 在做模块时会用到半孔工艺,但是由于半孔是特殊工艺. 需要加费用,打板时费还不低. 下面这个图是锣板和半孔工艺的差别. https://www.amobbs.com ...
- KiCad EDA 5.1.2 使用圆形板框时出现无法走线的问题
KiCad EDA 5.1.2 使用圆形板框时出现无法走线的问题 看到官方已经修复,等着官方发布新的版本 5.1.3. Steps to reproduce: 1) create new board. ...
- Altium Designer PCB 常用功能键
altium designer 5种走线模式的切换 : shift+space 方格与格点的切换:View-Grids-ToggleVisible Grid Kind源点:Edit-Origin-Se ...
- 【转】非常实用的高频PCB电路设计70问
1.如何选择PCB 板材? 选择PCB 板材必须在满足设计需求和可量产性及成本中间取得平衡点.设计需求包含电气和机构这两部分.通常在设计非常高速的 PCB 板子(大于 GHz 的频率)时这材质问题会比 ...
- 【PCB】扫盲总结
1.PCB是什么 PCB( Printed Circuit Board),中文名称为印制电路板,又称印刷线路板,是重要的电子部件,是电子元器件的支撑体,是电子元器件电气连接的载体.由于它是采用电子印刷 ...
- PCB走线角度选择 — PCB Layout 跳坑指南
现在但凡打开SoC原厂的PCB Layout Guide,都会提及到高速信号的走线的拐角角度问题,都会说高速信号不要以直角走线,要以45度角走线,并且会说走圆弧会比45度拐角更好.狮屎是不是这样?PC ...
- 针对PCB飞针测试快速有效的技巧
测试探针通过多路传输(multiplexing)系统连接到驱动器(信号发生器.电源供应等)和传感器(数字万用表.频率计数器等)来测试UUT上的元件.当一个元件正在测试的时候,UUT上的其它元件通过探针 ...
随机推荐
- Eclipse Myeclipse 设定文件的默认打开方式
Eclipse Myeclipse 设定文件的默认打开方式 菜单:Window -> Preferences -> General -> Editors -> File A ...
- linux 下CPU数量、核心数量、是否支持超线程的判断
判断依据:1.具有相同core id的cpu是同一个core的超线程.2.具有相同physical id的cpu是同一颗cpu封装的线程或者cores. 英文版:1.Physical id and c ...
- 总结:常用的Linux系统监控命令(2)
判断I/O瓶颈 mpstat命令 命令:mpstat -P ALL 1 1000 结果显示: 注意一下这里面的%iowait列,CPU等待I/O操作所花费的时间.这个值持续很高通常可能是I/O瓶颈所导 ...
- codevs3164 质因数分解
题目描述 Description (多数据)给出t个数,求出它的质因子个数. 数据没坑,难度降低. 输入描述 Input Description 第一行 t 之后t行 数据 输出描述 Output D ...
- 常用的delphi 第三方控件
Devexpress VCL 这个基本上覆盖了系统界面及数据库展示的方方面面,是做桌面系统必备的一套控件,目前的版本是2011.2.3, 支持win32 及win64. AutoUpgrader 这个 ...
- IE11 文档模式空白
环境描述: win7 64位系统 安装了 更新 IE11-Windows6.1-KB2929437-x64.IE11-Windows6.1-KB3008923-x64 解决方案: 卸载 IE11-Wi ...
- DTRACE简介(1)
https://blogs.oracle.com/swan/entry/dtrace%E7%AE%80%E4%BB%8B By samwan on 三月 20, 2007 记得几年前看过一部美国大片叫 ...
- io计算
http://www.cnblogs.com/yalong_xiang/archive/2011/11/15/2249530.html ぬ儱←OWEN★ windows下如何查看磁盘IO性能 复制 ...
- MongoDB小结26 - 地理空间索引
现在有一种查询变得越来越流行(尤其是移动设备):找到离当前位置最近的N个场所. MongoDB专为平面坐标查询做了专门的索引,称为地理空间索引. 同样需要用ensureIndex创建,不过,参数是两个 ...
- mysql导入大型sql文件时注意事项
原文:http://blog.csdn.net/k21325/article/details/70808563 大型sql文件,需要在my.ini(windows)或者my.cnf(Linux)中设置 ...