1. 程式人生 > >PCB genesis連孔加除毛刺孔實現方法

PCB genesis連孔加除毛刺孔實現方法

一.為什麼 連孔加除毛刺孔

        原因是 PCB板材中含有玻璃纖維, 毛刺產生位置在於2個孔相交位置,由於此處鑽刀受力不均導致纖維切削不斷形成毛刺 ,為了解決這個問題:在鑽完2個連孔後,在相交處再鑽一個孔,並鑽進去一點(常規進去1-2mil),這樣就可以將纖維毛刺去除

  

    PCB同行業毛刺問題處理辦法 鑽孔孔內毛刺問題分析改善報告

二.連孔加除毛刺孔實現原理

求解思路:
1.已知小圓半徑:1.5mm,大圓半徑 2mm,2個點距離3mm
利用海倫公式(三邊求高)求出除塵孔徑半徑:0.8887mm


2.除塵孔半徑 0.8888mm 轉為鑽刀向上取整為1.8mm
3. 求出小圓到大圓方位角,即為0度
求出小圓到毛刺孔距離,即為1.2083mm
4. 以小圓中心,通過方位角0與增量距1.2083mm求出毛刺孔座標

三.C#簡易程式碼實現:

    1.加除毛刺孔程式碼(因為有現成的2D庫直接用上來,其實還有一種更簡便的計算公式;這裡不介紹了)

            #region 加除毛刺孔  mcdrl  
            double a_side, b_side, c_side, height_side, holesize;
            a_side 
= calc2.p2p_di(hole1.p, hole2.p); b_side = hole1.width * 0.001 * 0.5; c_side = hole2.width * 0.001 * 0.5; height_side = calc1.side3_hight(a_side, b_side, c_side, 1) ; holesize = (int)(Math.Ceiling((height_side * 2 * 1000 ) / 50)) * 50; double direction_ang = calc2.p_ang(hole1.p, hole2.p);
double direction_val = Math.Sqrt((b_side * b_side) - (height_side * height_side)); gPoint mcHole = calc2.p_val_ang(hole1.p, direction_val, direction_ang); addCOM.pad(mcHole, holesize); #endregion
View Code

    2.計算函式

        /// <summary>
        /// 3邊求高
        /// </summary>
        /// <param name="a_side"></param>
        /// <param name="b_side"></param>
        /// <param name="c_side"></param>
        /// <param name="abc"></param>
        /// <returns></returns>
        public double side3_hight(double a_side, double b_side, double c_side, int abc = 1)
        {
            double p, s;
            p = (a_side + b_side + c_side) / 2;
            s = Math.Sqrt(p * (p - a_side) * (p - b_side) * (p - c_side));
            if (abc == 1)
                return (s / a_side ) *2;
            else if (abc == 2)
                return (s / b_side) * 2;
            else
                return (s / c_side) * 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;
            //象限角  轉方位角   計算所屬象限   並求得方位角
            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>
        /// 返回兩點之間歐氏距離
        /// </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>
        /// 求增量座標
        /// </summary>
        /// <param name="ps">起點</param>
        /// <param name="val">增量值</param>
        /// <param name="ang_direction">角度</param>
        /// <returns></returns>
        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 / 180);
            pe.y = ps.y + val * Math.Sin(ang_direction * Math.PI / 180);
            return pe;
        }
View Code

   3.Point,PAD資料結構

  /// <summary>
    /// PAD  資料型別
    /// </summary>
    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 = 0;
            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;
        }
    }
    /// <summary>
    /// 點  資料型別 (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;
        }


    }
View Code

四.在Genesis或Incam中如何判斷是否為連孔

     判斷2個孔是否為連孔,可以自己寫演算法實現啦,當然更多人還是會選擇奧寶提供DrillChecklist分析出來的的結果來判斷是否為連孔.因為你自己寫的演算法效率沒有奧寶的效率高呀

 

 

五.實現效果