PCB genesis 大孔扩孔(不用G84命令)实现方法
生活随笔
收集整理的這篇文章主要介紹了
PCB genesis 大孔扩孔(不用G84命令)实现方法
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
PCB鉆孔時(shí),當(dāng)鉆刀>6.3mm時(shí),超出鉆孔范圍,鉆孔工序是沒有這么大的鉆刀,當(dāng)這種情況,工程CAM會(huì)都采用G84命令用小孔擴(kuò)孔的方式制作, 在這里介紹一種如果不用G84命令,用程序?qū)崿F(xiàn)將大孔生成小孔鉆孔達(dá)到擴(kuò)孔的目的。
一.我們先了解一下G84命令擴(kuò)孔
孔尺寸大小
孔密度
連一篇文章有關(guān)于孔數(shù)計(jì)算方式:https://www.cnblogs.com/pcbren/p/9379178.html
二.求解思路
1.通過孔密度,求出孔與孔中心距離
2.求出單次增量方位角
3.以大孔中心為,長度為(大孔半徑-小孔半徑), 任選擇一個(gè)方位角作為起始方位角,并增加一個(gè)起始孔,并圍繞這個(gè)起始方位角不斷遞增方位角,直到360度遞增完成后即結(jié)束。
三.C#簡易代碼實(shí)現(xiàn):
1.擴(kuò)孔鉆孔代碼
string drilllayer = "drl";
gLayer layer = g.getFEATURES($"{drilllayer}", g.STEP, g.JOB, "mm", true);
List<gPP> pList = new List<gPP>();
double HoleSize = 3175; //擴(kuò)孔所用鉆刀大小
foreach (var pad in layer.Plist)
{
if (pad.width > 6300) //鉆孔>6300需擴(kuò)孔
{
gA arc = calc2.p_2A(new gP(pad.p, pad.width - HoleSize));
arc.width = HoleSize;
var HoleCenterDi = calc2.p_Convex(arc.width * 0.0005)*3;
pList.AddRange(calc2.a_2Plist(arc, HoleCenterDi, 2, true));
}
}
addCOM.pad(pList);
View Code
2.計(jì)算函數(shù)
/// <summary>
/// 通過孔半徑與凸高位求 孔中心距
/// </summary>
/// <param name="Rradius">孔半徑</param>
/// <param name="tol_">凸位高度值</param>
/// <returns></returns>
public double p_Convex(double Rradius, double tol_ = 0.0127)
{
return Math.Sqrt(Math.Pow(Rradius, 2) - Math.Pow(Rradius - tol_, 2)) * 2;
}
/// <summary>
/// 求方位角
/// </summary>
/// <param name="ps"></param>
/// <param name="pe"></param>
/// <returns></returns>
public double p_ang(gPoint ps, gPoint pe)
{
double a_ang = Math.Atan((pe.y - ps.y) / (pe.x - ps.x)) / Math.PI * 180;
//象限角 轉(zhuǎn)方位角 計(jì)算所屬象限 并求得方位角
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 + 180;
}
else if (!(pe.x >= ps.x) && !(pe.y >= ps.y)) //↙ 第三象限
{
return a_ang + 180;
}
else if (pe.x >= ps.x && !(pe.y >= ps.y)) // ↘ 第四象限
{
return a_ang + 360;
}
else
{
return a_ang;
}
}//求方位角
/// <summary>
/// 求增量坐標(biāo)
/// </summary>
/// <param name="ps">起點(diǎn)</param>
/// <param name="val">增量值</param>
/// <param name="ang_direction">角度</param>
/// <returns></returns>
public gPP p_val_ang(gPP ps, double val, double ang_direction)
{
gPP pe = ps;
pe.p.x = ps.p.x + val * Math.Cos(ang_direction * Math.PI / 180);
pe.p.y = ps.p.y + val * Math.Sin(ang_direction * Math.PI / 180);
return pe;
}
/// <summary>
/// 弧Arc 轉(zhuǎn)點(diǎn)P組集
/// </summary>
/// <param name="a"></param>
/// <param name="val_">此數(shù)值表示:分段數(shù)值</param>
/// <param name="type_">代表值數(shù)值類型 【0】弧長 【1】角度 【2】弦長 </param>
/// <param name="is_avg">是否平均分布 </param>
/// <returns></returns>
public List<gPP> a_2Plist(gA a, double val_ = 0.1d, int type_ = 0, bool is_avg = false)
{
List<gPP> list_point = new List<gPP>();
gPP tempP;
tempP.p = a.ps;
tempP.symbols = a.symbols;
tempP.width = a.width;
list_point.Add(tempP);
double avg_count;
double angle_val = 0;
double rad_ = p2p_di(a.pc, a.pe);
double sum_alge = a_Angle(a);
if (type_ == 1) // 【1】角度
{
angle_val = val_;
avg_count = (int)(Math.Ceiling(sum_alge / angle_val)) - 1; // 總角度/單角度
}
else if (type_ == 2) //【2】弦長
{
angle_val = Math.Asin(val_ / (rad_ * 2)) * 360 / pi;
avg_count = (int)(Math.Ceiling(sum_alge / angle_val)) - 1; // 總角度/單角度
}
else // 【0】弧長
{
angle_val = val_ * 180 / (pi * rad_);
avg_count = (int)(Math.Ceiling(sum_alge / angle_val)) - 1; // 總角度/單角度
//avg_count = (int)(Math.Ceiling(a_Lenght(a) / val_)) - 1; // 或 總弧長/單弧長
}
if (is_avg)
angle_val = sum_alge / avg_count;
if (avg_count > 1)
{
gPP centerP = tempP;
centerP.p = a.pc;
double angle_s = p_ang(a.pc, a.ps);
if (a.ccw) { angle_val = 0 - angle_val; }
for (int i = 1; i < avg_count; i++)
{
tempP = p_val_ang(centerP, rad_, angle_s - angle_val * i);
list_point.Add(tempP);
}
}
if (!(zero(a.ps.x - a.pe.x) && zero(a.ps.y - a.pe.y)))
{
tempP.p = a.pe;
list_point.Add(tempP);
}
return list_point;
}
/// <summary>
/// 返回兩點(diǎn)之間歐氏距離
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <returns></returns>
public double p2p_di(gPoint p1, gPoint p2)
{
return Math.Sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
/// <summary>
/// 求弧Arc圓心角 //后續(xù)改進(jìn) 用叉積 與3P求角度求解 驗(yàn)證哪個(gè)效率高
/// </summary>
/// <param name="a"></param>
/// <returns></returns>
public double a_Angle(gA a)
{
double angle_s, angle_e, angle_sum;
if (a.ccw)
{
angle_s = p_ang(a.pc, a.pe);
angle_e = p_ang(a.pc, a.ps);
}
else
{
angle_s = p_ang(a.pc, a.ps);
angle_e = p_ang(a.pc, a.pe);
}
if (angle_s == 360) { angle_s = 0; }
if (angle_e >= angle_s)
angle_sum = 360 - Math.Abs(angle_s - angle_e);
else
angle_sum = Math.Abs(angle_s - angle_e);
return angle_sum;
}
/// <summary>
/// 檢查值決對值 小于 (eps = 0.001) 浮點(diǎn)誤差處理
/// </summary>
/// <param name="x"></param>
/// <returns></returns>
public bool zero(double x)
{
return (((x) > 0 ? (x) : (-x)) < eps);
}
View Code
3.Point,PAD,Arc數(shù)據(jù)結(jié)構(gòu)
/// <summary>
/// 精簡 PAD 數(shù)據(jù)類型
/// </summary>
public struct gPP
{
public gPP(double x_val, double y_val, double width_)
{
this.p = new gPoint(x_val, y_val);
this.symbols = "r";
this.width = width_;
}
public gPP(gPoint p_, double width_)
{
this.p = p_;
this.symbols = "r";
this.width = width_;
}
public gPP(gPoint p_, string symbols_, double width_)
{
this.p = p_;
this.symbols = symbols_;
this.width = width_;
}
public gPoint p;
public string symbols;
public double width;
public static gPP operator +(gPP p1, gPP p2)
{
p1.p += p2.p;
return p1;
}
public static gPP operator +(gPP p1, gPoint p2)
{
p1.p += p2;
return p1;
}
public static gPP operator -(gPP p1, gPP p2)
{
p1.p -= p2.p;
return p1;
}
public static gPP operator -(gPP p1, gPoint p2)
{
p1.p -= p2;
return p1;
}
}
/// <summary>
/// 點(diǎn) 數(shù)據(jù)類型 (XY)
/// </summary>
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;
}
}
/// <summary>
/// ARC 數(shù)據(jù)類型
/// </summary>
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;
}
}
View Code
四.實(shí)現(xiàn)效果
總結(jié)
以上是生活随笔為你收集整理的PCB genesis 大孔扩孔(不用G84命令)实现方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android面试题集
- 下一篇: 微信授权登录微信公众号和PC端网站