zoukankan      html  css  js  c++  java
  • 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分析出来的的结果来判断是否为连孔.因为你自己写的算法效率没有奥宝的效率高呀

    五.实现效果

         

  • 相关阅读:
    .NET HttpWebRequest应用
    .NET 文件上传和文件接收
    小程序报错:对应的服务器 TLS 为 TLS 1.0 ,小程序要求的 TLS 版本必须大于等于 1.2
    发布微信小程序体验版
    .NET 通过entity framework报数据库连接错误:ORA-01017: invalid username/password; logon denied
    将Oracle 12c的某用户数据迁移至OracleXE的用户
    C# Oracle 时间字符串转时间类型
    在.NET中调用Java的类
    Oracle 取前几条记录
    oracle impdp将导出用户的所有对象导入至另一个用户下,生成的触发器语句问题处理
  • 原文地址:https://www.cnblogs.com/pcbren/p/9906554.html
Copyright © 2011-2022 走看看