PCB genesis连孔加除毛刺孔(槽孔与槽孔)实现方法(三)

您所在的位置:网站首页 pcb半孔毛刺去除 PCB genesis连孔加除毛刺孔(槽孔与槽孔)实现方法(三)

PCB genesis连孔加除毛刺孔(槽孔与槽孔)实现方法(三)

2023-09-08 20:50| 来源: 网络整理| 查看: 265

一.为什么 连孔加除毛刺孔

原因是 PCB板材中含有玻璃纤维, 毛刺产生位置在于2个孔相交位置,由于此处钻刀受力不均导致纤维切削不断形成毛刺 ,为了解决这个问题:在钻完2个连孔后,在相交处再钻一个孔,并钻进去一点(常规进去1-2mil),这样就可以将纤维毛刺去除 (没找到SLOT槽与SLOT槽的实物图.就用SLOT槽与圆孔吧,产生毛刺效果也是一样的)

PCB genesis连孔加除毛刺孔(槽孔与槽孔)实现方法(三)-LMLPHP

PCB同行业毛刺问题处理办法 钻孔孔内毛刺问题分析改善报告

二.如何判断除毛刺孔加多少个?

在PCB行业工程加除毛刺孔加多少个也没有太明确的定义,只要满足毛刺去除即可.

这里我们把相交的SLOT槽分为2类,一类是十字形,另一类是T型,分别用实际的案例做以说明.

1.十字型交叉SLOT槽:

实例1:十字槽 加1个孔 需满足2点需求           P1到P3 两点距离 与 P2与P4 两点距离相等           P1与P2 两点距离 与 P2与P3两点距离相差 l2Rval ? l2Rval : l1Rval; double Hole_Radius = Rval; double HoleSize = Hole_Radius * ; l_offset(l1, l1Rval, out l1_L, out l1_R); l_offset(l2, l2Rval, out l2_L, out l2_R); jdP1 = l2l_Intersect(l1_L, l2_R, ref jd1Type); jdP2 = l2l_Intersect(l1_L, l2_L, ref jd2Type); jdP3 = l2l_Intersect(l1_R, l2_L, ref jd3Type); jdP4 = l2l_Intersect(l1_R, l2_R, ref jd4Type); jd1Type = jd1Type < ? : jd1Type; jd2Type = jd2Type < ? : jd2Type; jd3Type = jd3Type < ? : jd3Type; jd4Type = jd4Type < ? : jd4Type; if ((jd1Type + jd2Type + jd3Type + jd4Type) == ) //产生4个交点 { if (Math.Abs(p2p_di(jdP1, jdP3) - p2p_di(jdP2, jdP4)) < 0.01) //4个交点且交错交点相等时 加1个孔 { if (Math.Abs(p2p_di(jdP1, jdP2) - p2p_di(jdP2, jdP3)) < 0.51) //4个交点且2条槽宽相差小于0.5mm 加1个孔 { gPoint PointCenter = p2p_centerP(jdP1, jdP3); Hole_Radius = p2p_di(PointCenter, jdP1) + CutInner; HoleSize = ((int)(Math.Ceiling((Hole_Radius * * ) / )) * ) * 0.001; ; gpList.Add(new gP(PointCenter, HoleSize * )); return gpList; } } } if ((jd1Type + jd2Type + jd3Type + jd4Type) == ) //产生2个交点 { //P2 P3 //P1 P4 gPoint LineCenter = new gPoint(); double AngDirdction = ; double ValDirdction = ; double ValR = ; double Lwidth = ; if (jd1Type + jd2Type == ) { LineCenter = p2p_centerP(jdP1, jdP2); AngDirdction = p_ang(LineCenter, l1_R); ValDirdction = p2p_di(jdP1, jdP2) * 0.5; ValR = ValDirdction * 1.4142136; Lwidth = l1Rval * ; } if (jd2Type + jd3Type == ) { LineCenter = p2p_centerP(jdP2, jdP3); AngDirdction = p_ang(LineCenter, l2_R); ValDirdction = p2p_di(jdP2, jdP3) * 0.5; ValR = ValDirdction * 1.4142136; Lwidth = l2Rval * ; } if (jd3Type + jd4Type == ) { LineCenter = p2p_centerP(jdP3, jdP4); AngDirdction = p_ang(LineCenter, l1_L); ValDirdction = p2p_di(jdP3, jdP4) * 0.5; ValR = ValDirdction * 1.4142136; Lwidth = l1Rval * ; } if (jd4Type + jd1Type == ) { LineCenter = p2p_centerP(jdP4, jdP1); AngDirdction = p_ang(LineCenter, l2_L); ValDirdction = p2p_di(jdP4, jdP1) * 0.5; ValR = ValDirdction * 1.4142136; Lwidth = l2Rval * ; } Hole_Radius = ValR + CutInner; HoleSize = ((int)(Math.Ceiling((Hole_Radius * * ) / )) * ) * 0.001; Hole_Radius = HoleSize * 0.5; double diffVal = Hole_Radius - (ValR + CutInner); if (diffVal > ) { ValDirdction = Math.Sqrt(Math.Pow((ValR + diffVal), ) - Math.Pow((ValDirdction), )); } if ((ValDirdction + Hole_Radius - 0.1) < Lwidth) //2个交点且正交时 加1个孔 { gPoint PointCenter = p_val_ang(LineCenter, ValDirdction, AngDirdction); gpList.Add(new gP(PointCenter, HoleSize * )); return gpList; } } //当不满足条件的,全按一个交点加一个孔的方式处理 HoleSize = ((int)(Math.Ceiling((Rval * * ) / )) * ) * 0.001; Hole_Radius = HoleSize * 0.5; ang1 = a_AngleCenter_dirdction(jdP2, jdP1, jdP4); ang2 = a_AngleCenter_dirdction(jdP3, jdP2, jdP1); ang3 = p_ang_invert(ang1); ang4 = p_ang_invert(ang2); HoleP1 = p_val_ang(jdP1, Hole_Radius - CutInner, ang1); HoleP2 = p_val_ang(jdP2, Hole_Radius - CutInner, ang2); HoleP3 = p_val_ang(jdP3, Hole_Radius - CutInner, ang3); HoleP4 = p_val_ang(jdP4, Hole_Radius - CutInner, ang4); if (jd1Type == ) gpList.Add(new gP(HoleP1, HoleSize * )); if (jd2Type == ) gpList.Add(new gP(HoleP2, HoleSize * )); if (jd3Type == ) gpList.Add(new gP(HoleP3, HoleSize * )); if (jd4Type == ) gpList.Add(new gP(HoleP4, HoleSize * )); return gpList; } /// /// 线Line偏移 out 左与右偏移线Line /// /// /// 偏移数值 /// out 左偏移线L /// out 右偏移线L public void l_offset(gL l, double offset_val, out gL left_l, out gL rithg_l) { left_l = l; rithg_l = l; double angle_ = p_ang(l.ps, l.pe); left_l.ps = p_val_ang(l.ps, offset_val, angle_ + ); left_l.pe = p_val_ang(l.pe, offset_val, angle_ + ); rithg_l.ps = p_val_ang(l.ps, offset_val, angle_ - ); rithg_l.pe = p_val_ang(l.pe, offset_val, angle_ - ); } /// /// 求方位角 /// /// /// /// public double p_ang(gPoint ps, gPoint pe) { double a_ang = Math.Atan((pe.y - ps.y) / (pe.x - ps.x)) / Math.PI * ; //象限角 转方位角 计算所属象限 并求得方位角 if (pe.x >= ps.x && pe.y >= ps.y) //↗ 第一象限 { return a_ang; } else if (!(pe.x >= ps.x) && pe.y >= ps.y) // ↖ 第二象限 { return a_ang + ; } else if (!(pe.x >= ps.x) && !(pe.y >= ps.y)) //↙ 第三象限 { return a_ang + ; } else if (pe.x >= ps.x && !(pe.y >= ps.y)) // ↘ 第四象限 { return a_ang + ; } else { return a_ang; } }//求方位角 /// /// 求增量坐标 /// /// 起点 /// 增量值 /// 角度 /// public gPoint p_val_ang(gPoint ps, double val, double ang_direction) { gPoint pe; pe.x = ps.x + val * Math.Cos(ang_direction * Math.PI / ); pe.y = ps.y + val * Math.Sin(ang_direction * Math.PI / ); return pe; } /// /// 求线段与线段相交点 (线段与线段相差微小距离误差无法可控 之前测试有发现后来没发现了,有待验证) /// /// /// /// 0平行无交点 1本身相交 -1本身不相交(但延长相交) /// public gPoint l2l_Intersect(gL L1, gL L2, ref int isIntersectType) { return l2l_Intersect(L1.ps, L1.pe, L2.ps, L2.pe, ref isIntersectType); } /// /// 求线段与线段相交点 (线段与线段相差微小距离误差无法可控 之前测试有发现后来没发现了,有待验证) /// /// /// /// /// /// 0平行无交点 1本身相交 -1本身不相交(但延长相交) /// public gPoint l2l_Intersect(gPoint l1ps, gPoint l1pe, gPoint l2ps, gPoint l2pe, ref int isIntersectType) { gL L1 = new gL(l1ps, l1pe, ); gL L2 = new gL(l2ps, l2pe, ); gPoint tempP = new gPoint(); double ABC, ABD, CDA, CDB, T; //面积符号相同则两点在线段同侧,不相交 (对点在线段上的情况,本例当作不相交处理) ABC = (L1.ps.x - L2.ps.x) * (L1.pe.y - L2.ps.y) - (L1.ps.y - L2.ps.y) * (L1.pe.x - L2.ps.x); ABD = (L1.ps.x - L2.pe.x) * (L1.pe.y - L2.pe.y) - (L1.ps.y - L2.pe.y) * (L1.pe.x - L2.pe.x); CDA = (L2.ps.x - L1.ps.x) * (L2.pe.y - L1.ps.y) - (L2.ps.y - L1.ps.y) * (L2.pe.x - L1.ps.x); // 三角形cda 面积的2倍 // 注意: 这里有一个小优化.不需要再用公式计算面积,而是通过已知的三个面积加减得出. CDB = CDA + ABC - ABD; // 三角形cdb 面积的2倍 if (Math.Abs(ABC - ABD) = ) return ang_direction - ; else return ang_direction + ; }

3.Point,PAD;Line;Arc数据结构

/// /// Line 数据类型 /// public struct gL { public gL(double ps_x, double ps_y, double pe_x, double pe_y, double width_) { this.ps = new gPoint(ps_x, ps_y); this.pe = new gPoint(pe_x, pe_y); this.negative = false; this.symbols = "r"; this.attribut = string.Empty; this.width = width_; } public gL(gPoint ps_, gPoint pe_, double width_) { this.ps = ps_; this.pe = pe_; this.negative = false; this.symbols = "r"; this.attribut = string.Empty; this.width = width_; } public gL(gPoint ps_, gPoint pe_, string symbols_, double width_) { this.ps = ps_; this.pe = pe_; this.negative = false; this.symbols = symbols_; this.attribut = string.Empty; this.width = width_; } public gPoint ps; public gPoint pe; public bool negative;//polarity-- positive negative public string symbols; public string attribut; public double width; public static gL operator +(gL l1, gPoint move_p) { l1.ps += move_p; l1.pe += move_p; return l1; } public static gL operator +(gL l1, gP move_p) { l1.ps += move_p.p; l1.pe += move_p.p; return l1; } public static gL operator -(gL l1, gPoint move_p) { l1.ps -= move_p; l1.pe -= move_p; return l1; } public static gL operator -(gL l1, gP move_p) { l1.ps -= move_p.p; l1.pe -= move_p.p; return l1; } } /// /// ARC 数据类型 /// public struct gA { public gA(double ps_x, double ps_y, double pc_x, double pc_y, double pe_x, double pe_y, double width_, bool ccw_) { this.ps = new gPoint(ps_x, ps_y); this.pc = new gPoint(pc_x, pc_y); this.pe = new gPoint(pe_x, pe_y); this.negative = false; this.ccw = ccw_; this.symbols = "r"; this.attribut = string.Empty; this.width = width_; } public gA(gPoint ps_, gPoint pc_, gPoint pe_, double width_, bool ccw_ = false) { this.ps = ps_; this.pc = pc_; this.pe = pe_; this.negative = false; this.ccw = ccw_; this.symbols = "r"; this.attribut = string.Empty; this.width = width_; } public gPoint ps; public gPoint pe; public gPoint pc; public bool negative;//polarity-- positive negative public bool ccw; //direction-- cw ccw public string symbols; public string attribut; public double width; public static gA operator +(gA arc1, gPoint move_p) { arc1.ps += move_p; arc1.pe += move_p; arc1.pc += move_p; return arc1; } public static gA operator +(gA arc1, gP move_p) { arc1.ps += move_p.p; arc1.pe += move_p.p; arc1.pc += move_p.p; return arc1; } public static gA operator -(gA arc1, gPoint move_p) { arc1.ps -= move_p; arc1.pe -= move_p; arc1.pc -= move_p; return arc1; } public static gA operator -(gA arc1, gP move_p) { arc1.ps -= move_p.p; arc1.pe -= move_p.p; arc1.pc -= move_p.p; return arc1; } } /// /// PAD 数据类型 /// public struct gP { public gP(double x_val, double y_val, double width_) { this.p = new gPoint(x_val, y_val); this.negative = false; this.angle = ; this.mirror = false; this.symbols = "r"; this.attribut = string.Empty; this.width = width_; } public gPoint p; public bool negative;//polarity-- positive negative public double angle; public bool mirror; public string symbols; public string attribut; public double width; public static gP operator +(gP p1, gP p2) { p1.p += p2.p; return p1; } public static gP operator -(gP p1, gP p2) { p1.p -= p2.p; return p1; } } /// /// 点 数据类型 (XY) /// public struct gPoint { public gPoint(gPoint p_) { this.x = p_.x; this.y = p_.y; } public gPoint(double x_val, double y_val) { this.x = x_val; this.y = y_val; } public double x; public double y; public static gPoint operator +(gPoint p1, gPoint p2) { p1.x += p2.x; p1.y += p2.y; return p1; } public static gPoint operator -(gPoint p1, gPoint p2) { p1.x -= p2.x; p1.y -= p2.y; return p1; } }

五.在Genesis或Incam中如何判断是否为连孔

判断2个孔是否为连孔,可以自己写算法实现啦,当然更多人还是会选择奥宝提供DrillChecklist分析出来的的结果来判断是否为连孔.因为你自己写的算法效率没有奥宝的效率高呀

PCB genesis连孔加除毛刺孔(槽孔与槽孔)实现方法(三)-LMLPHP

PCB genesis连孔加除毛刺孔(槽孔与槽孔)实现方法(三)-LMLPHP

六.实现效果

PCB genesis连孔加除毛刺孔(槽孔与槽孔)实现方法(三)-LMLPHP



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3