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 210 并行程序模拟(deque)
题意: 模拟n个程序运行 格式一共有5种:var = constant(赋值):print var(打印):lock:unlock:end, 上述5种语句分别需要t1.t2.t3.t4.t5单位时间 ...
- Directory获取方式
1) FSDirectory.open FSDirectory.open()会以最合适的方式来获取一个Directory对象. 2) RAMDirectory 可以将磁盘中的索引加载到内存中,访问速度 ...
- CSU 1554 SG Value (集合类的学习)
题目大意: 2种操作 1 a:往集合中添加一个元素a 2: 询问这个集合中的元素任意组合相加所不能得到的最小数的值 这道题总是不断地去找当前所能处的最小值能否被当前的最小值加上其前部的一堆可抵达数到达 ...
- [luoguP1877] [HAOI2012]音量调节(DP)
传送门 绝世傻DP #include <cstdio> #include <iostream> #define N 51 int n, s, mx; bool f[N][100 ...
- android 上AES解密是报错javax.crypto.BadPaddingException: pad block corrupted
网上看到两种方法: 1.SecretKeySpec skeySpec = new SecretKeySpec(getRawKey(key), "AES"); private sta ...
- 2018/2/17 SpringCloud的一个简单小介绍
在学习SpringCloud之前,我以为SpringCloud是与Double一样,只是个单纯的RPC框架.但在今天的学习中,我发现并非如此,事实上,SpringCloud是多个框架的集合,感觉Spr ...
- vagrant的学习 之 LNMP和LAMP
vagrant的学习 之 LNMP和LAMP 本文根据慕课网的视频教程练习,感谢慕课网! 慕课的参考文档地址:https://github.com/apanly/mooc/tree/master/va ...
- Thinkphp5.0 的Db操作
Thinkphp5.0 的Db操作 连接操作: <?php namespace app\index\controller; use think\Controller; use think\Db; ...
- CentOS系统下Hadoop、Hbase、Zookeeper安装配置
近期给一个项目搭建linux下的大数据处理环境,系统是CentOS 6.3.主要是配置JDK.安装Tomcat,Hadoop.HBase和Zookeeper软件.博主在Hadoop这方面也是新手.配置 ...
- JavaScript错误处理和堆栈追踪
转自:https://github.com/dwqs/blog/issues/49 有时我们会忽略错误处理和堆栈追踪的一些细节, 但是这些细节对于写与测试或错误处理相关的库来说是非常有用的. 例如这周 ...