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上的其它元件通过探针 ...
随机推荐
- UVA 227 周期串
题意: 给一个字符串,寻找最短的循环节 如abcabcabcabc以3为周期,也按6和12为周期. 分析: 因为循环节肯定是相等的,所以枚举串长度的所有约数的循环节再判断是否相等即可. 我的方法是枚举 ...
- 字符串类String类的判断功能
StringDemo.java /* * Object:是类层级结构中的根类,所有的类都直接或间接的继承自该类. * 如果一个方法的形式参数是Object,那么这里我们就可以传递它的任意的子类对象. ...
- Webdriver测试脚本1(打开网页并打印标题)
案例: 启动火狐浏览器 首页打开博客园页面,打印网页标题,等待3秒 打开百度首页,打印网页标题,再等待2秒 关闭浏览器 from selenium import webdriver from time ...
- hihoCoder#1048 状态压缩·二
原题地址 位运算的状态压缩太操蛋了,很容易出错...又是数组没开够导致诡异现象(明明某个值是1,莫名其妙就变成0了),害我debug一整天!fuck 代码: #include <iostream ...
- HDU 4473
题目大意: 给定一个long long 型的数 n,找到一共有多少对a,b,使比n小的某一个数的是a*b的倍数 这样我们可以理解为 存在a*b*c <= n,令 a <= b <= ...
- hdu 5093 二分匹配
/* 题意:给你一些冰岛.公共海域和浮冰,冰岛可以隔开两个公共海域,浮冰无影响 求选尽可能多的选一些公共海域点每行每列仅能选一个. 限制条件:冰山可以隔开这个限制条件.即*#*可以选两个 预处理: * ...
- 网络编程基础:粘包现象、基于UDP协议的套接字
粘包现象: 如上篇博客中最后的示例,客户端有个 phone.recv(2014) , 当服务端发送给客户端的数据大于1024个字节时, 多于1024的数据就会残留在管道中,下次客户端再给服务端发命令时 ...
- XMLREADER/DOM/SIMPLEXML 解析大文件
DOM和simplexml处理xml非常的灵活方便,它们的内存组织结构与xml文件格式很相近.但是同时它们也有一个缺点,对于大文件处理起来力不从心,太耗内存了. 还好有xmlreader,基于流的解析 ...
- [NOIP2004] 提高组 洛谷P1090 合并果子
题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...
- POJ1422 Air Raid
Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 8006 Accepted: 4803 Description Consi ...