zoukankan      html  css  js  c++  java
  • PCB genesis SET取中心点--算法实现

     最新ICS工厂有一项incam脚本新需求,这里介绍5种解决方法解决

    需求如下图所示:绿色所圈处是是需求出的中心点(图形间距一致归为一类并计算中心点坐标)

    前题条件:
    1.一个SET里面可能有多个CAM,存在CAM1,CAM2,CAM3
    2.每个CAM与CAM这最小间距不是固定值

    对方法求解前;对此数据存储结构列出来:

        /// <summary>
        /// Mod_step  坐标data类型    存放PNL中的子板排放坐标位置
        /// </summary>
        public class Mod_Sr_data
        {
            public string step_name { get; set; }
            public gPoint ps;
            public int angle { get; set; }
            public bool mirror { get; set; }
            public gPoint min;
            public gPoint max;
            public gPoint size
            {
                get { return new gPoint(Math.Abs(this.min.x - this.max.x), Math.Abs(this.min.y - this.max.y)); }
            }
            public gPoint center
            {
                get { return new gPoint((this.max.x + this.min.x) / 2, (this.max.y + this.min.y) / 2); }
            }
        }

    方法一:矩阵排序分组法求解

      第一步:分别进行X与Y排列,如下图所示

     

       第二步,求出X最近距离,与Y最近距离

       第三步, 通过X与Y最近距离求出,间距分组ID号

       第四步,通过间距分组ID号,遍历分组

       第五步,通过每个分组求出中心点

       缺点:只能支持矩阵排列(X数*Y数=PCS总数),X或Y间距全部需保持一致,最小左下角相连PCS最少2个,不支持PCS旋转

           代码实现:

            private static  void SetCenterAddPad1()
            {
                step gstep = new step(g.JOB);
                gProfile profile = g.getProfile(g.STEP, g.JOB);
                List<Mod_Sr_data> sr_dataList = gstep.get_step_Sr_data(g.STEP);
                List<Mod_Sr_data> sr_dataList_y_Order = sr_dataList.OrderBy(tt => tt.min.y).ThenBy(tt => tt.min.x).ToList();
                List<Mod_Sr_data> sr_dataList_x_Order = sr_dataList.OrderBy(tt => tt.min.x).ThenBy(tt => tt.min.y).ToList();
                List<int> x_CountList = new List<int>();
                x_CountList.Add(0);
                List<int> y_CountList = new List<int>();
                y_CountList.Add(0);
                double tempDi = 0;
                double minDi = 0;
                bool isMinDi = false;
                int tempCount = 0;
                for (int i = 0; i < sr_dataList_y_Order.Count - 1; i++)
                {
                    if (Math.Abs(sr_dataList_y_Order[i + 1].min.y - sr_dataList_y_Order[i].min.y) > 0.1)
                        break;
                    tempDi = Math.Abs(sr_dataList_y_Order[i + 1].min.x - sr_dataList_y_Order[i].min.x);
                    if (!isMinDi)
                    {
                        minDi = tempDi;
                        isMinDi = true;
                        x_CountList[tempCount] = i + 1;
                    }
                    else
                    {
                        if ((Math.Abs(minDi - tempDi) < 0.001))
                        {
                            x_CountList[tempCount] = i + 1;
                        }
                        else
                        {
                            tempCount++;
                            x_CountList.Add(i + 1);
                        }
                    }
                }
                isMinDi = false;
                tempCount = 0;
                for (int i = 0; i < sr_dataList_x_Order.Count - 1; i++)
                {
                    if (Math.Abs(sr_dataList_x_Order[i + 1].min.x - sr_dataList_x_Order[i].min.x) > 0.1)
                        break;
                    tempDi = Math.Abs(sr_dataList_x_Order[i + 1].min.y - sr_dataList_x_Order[i].min.y);
                    if (!isMinDi)
                    {
                        minDi = tempDi;
                        isMinDi = true;
                        y_CountList[tempCount] = i + 1;
                    }
                    else
                    {
                        if ((Math.Abs(minDi - tempDi) < 0.001))
                        {
                            y_CountList[tempCount] = i + 1;
                        }
                        else
                        {
                            tempCount++;
                            y_CountList.Add(i + 1);
                        }
                    }
                }
    
                int x_Count = x_CountList.Max(tt => tt) + 1;
                int y_Count = y_CountList.Max(tt => tt) + 1;
                List<Mod_Sr_data>[] sr_dataListGroup = new List<Mod_Sr_data>[(x_CountList.Count * y_CountList.Count)];
                for (int i = 0; i < sr_dataListGroup.Count(); i++)
                {
                    sr_dataListGroup[i] = new List<Mod_Sr_data>();
                }
                for (int i = 0; i < sr_dataList_y_Order.Count; i++)
                {
                    int x_index = i % x_Count;
                    int y_index = i / x_Count;
                    for (int j = 0; j < x_CountList.Count; j++)
                    {
                        if (x_index <= x_CountList[j])
                        {
                            x_index = j;
                            break;
                        }
                    }
                    for (int j = 0; j < y_CountList.Count; j++)
                    {
                        if (y_index <= y_CountList[j])
                        {
                            y_index = j;
                            break;
                        }
                    }
                    int index = y_index * x_CountList.Count + x_index;
                    sr_dataListGroup[index].Add(sr_dataList_y_Order[i]);
                }
                List<gPoint> gpointList = new List<gPoint>();
                foreach (var item in sr_dataListGroup)
                {
                    double xVal = item.Sum(tt => tt.center.x) / item.Count;
                    double yVal = item.Sum(tt => tt.center.y) / item.Count;
                    gpointList.Add(new gPoint(xVal, yVal));
                }
                add add_ = new add();
                add_.pad(gpointList.ToArray(), 500);
            }
    View Code

    方法二:坐标对号入坑法(类拟桶排序算法思想上改进)

     

        第一步:分别进行X与Y排列

       第二步,求出X最近距离,与Y最近距离

       第三步, 建二维数组准备挖坑了(X与Y尺寸依据旋转时X与Y互换)

       第四步,遍历数据填入到对应的坑位

       第五步,通过二维的坑位依次对比最近距离X与Y进行划分数据分组

       第五步,通过每个分组求出中心点

       缺点:只能支持矩阵排列(中心可以缺少PCS),X或Y间距全部需保持一致,

     代码实现,未完待完善

            private void SetCenterAddPad2()
            {
    
                step gstep = new step(g.JOB);
                gProfile profile = g.getProfile(g.STEP, g.JOB);
                List<Mod_Sr_data> sr_dataList = gstep.get_step_Sr_data(g.STEP);
                List<Mod_Sr_data> sr_dataList_y_Order = sr_dataList.OrderBy(tt => tt.min.y).ThenBy(tt => tt.min.x).ToList();
                List<Mod_Sr_data> sr_dataList_x_Order = sr_dataList.OrderBy(tt => tt.min.x).ThenBy(tt => tt.min.y).ToList();
                double tempDi = 0;
                double yDi = 10000;
                double xDi = 10000;
                for (int i = 0; i < sr_dataList_y_Order.Count - 1; i++)
                {
                    tempDi = Math.Abs(sr_dataList_y_Order[i + 1].min.y - sr_dataList_y_Order[i].min.y);
                    if (tempDi > 0.01 && yDi > tempDi)
                        yDi = tempDi;
                }
                for (int i = 0; i < sr_dataList_x_Order.Count - 1; i++)
                {
                    tempDi = Math.Abs(sr_dataList_x_Order[i + 1].min.x - sr_dataList_x_Order[i].min.x);
                    if (tempDi > 0.01 && xDi > tempDi)
                        xDi = tempDi;
                }
                int x_array, y_array;
                double xWidth, yHeigth;
                double PcsAng = Math.Abs(sr_dataList[0].angle - 180);
                if (89 < PcsAng && PcsAng < 91)
                {
                    x_array = (int)Math.Ceiling(profile.Prof.size.y / sr_dataList[0].size.y);
                    y_array = (int)Math.Ceiling(profile.Prof.size.x / sr_dataList[0].size.x);
                    xWidth = sr_dataList[0].size.y;
                    yHeigth = sr_dataList[0].size.x;
                }
                else
                {
                    x_array = (int)Math.Ceiling(profile.Prof.size.x / sr_dataList[0].size.x);
                    y_array = (int)Math.Ceiling(profile.Prof.size.y / sr_dataList[0].size.y);
                    xWidth = sr_dataList[0].size.x;
                    yHeigth = sr_dataList[0].size.y;
                }
                Mod_Sr_data[,] sr_dataArray = new Mod_Sr_data[x_array, y_array];
                for (int i = 0; i < sr_dataList_y_Order.Count; i++)
                {
                    int x_index = (int)Math.Floor((sr_dataList_y_Order[i].min.x - profile.Prof.min.x) / xWidth);
                    int y_index = (int)Math.Floor((sr_dataList_y_Order[i].min.y - profile.Prof.min.y) / yHeigth);
                    sr_dataArray[x_index, y_index] = sr_dataList_y_Order[i];
                }
                List<int> x_CountList = new List<int>();
                x_CountList.Add(0);
                List<int> y_CountList = new List<int>();
                y_CountList.Add(0);
                for (int i = 0; i < x_array-1; i++)
                {
                    for (int j = 0; j < y_array-1; j++)
                    {
                        var aa = sr_dataArray[i, j];
    
    
                    }
                }
            }
    View Code

    方法三:最近邻聚类算法

    方法四:递归最左下角坐标定原点,进行相等距离求

    方法五:扩边求解

  • 相关阅读:
    zTree根据json选中节点,并且设置其他节点不可选
    点击一次按钮,发生多次ajax请求
    sublimeText3 中配置sass环境,并将编译后文件保存到指定文件夹
    MD5加密
    c# Http请求之HttpClient
    xml与object 之间的ORM
    wpf和winform的那点区别
    c# http请求ajax页面
    c# https请求
    python爬虫框架Pyspider初次接触
  • 原文地址:https://www.cnblogs.com/pcbren/p/9581686.html
Copyright © 2011-2022 走看看