最新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) / , (this.max.y + this.min.y) / ); }
}
}

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

第一步:分别进行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();
List<int> y_CountList = new List<int>();
y_CountList.Add();
double tempDi = ;
double minDi = ;
bool isMinDi = false;
int tempCount = ;
for (int i = ; i < sr_dataList_y_Order.Count - ; i++)
{
if (Math.Abs(sr_dataList_y_Order[i + ].min.y - sr_dataList_y_Order[i].min.y) > 0.1)
break;
tempDi = Math.Abs(sr_dataList_y_Order[i + ].min.x - sr_dataList_y_Order[i].min.x);
if (!isMinDi)
{
minDi = tempDi;
isMinDi = true;
x_CountList[tempCount] = i + ;
}
else
{
if ((Math.Abs(minDi - tempDi) < 0.001))
{
x_CountList[tempCount] = i + ;
}
else
{
tempCount++;
x_CountList.Add(i + );
}
}
}
isMinDi = false;
tempCount = ;
for (int i = ; i < sr_dataList_x_Order.Count - ; i++)
{
if (Math.Abs(sr_dataList_x_Order[i + ].min.x - sr_dataList_x_Order[i].min.x) > 0.1)
break;
tempDi = Math.Abs(sr_dataList_x_Order[i + ].min.y - sr_dataList_x_Order[i].min.y);
if (!isMinDi)
{
minDi = tempDi;
isMinDi = true;
y_CountList[tempCount] = i + ;
}
else
{
if ((Math.Abs(minDi - tempDi) < 0.001))
{
y_CountList[tempCount] = i + ;
}
else
{
tempCount++;
y_CountList.Add(i + );
}
}
} int x_Count = x_CountList.Max(tt => tt) + ;
int y_Count = y_CountList.Max(tt => tt) + ;
List<Mod_Sr_data>[] sr_dataListGroup = new List<Mod_Sr_data>[(x_CountList.Count * y_CountList.Count)];
for (int i = ; i < sr_dataListGroup.Count(); i++)
{
sr_dataListGroup[i] = new List<Mod_Sr_data>();
}
for (int i = ; i < sr_dataList_y_Order.Count; i++)
{
int x_index = i % x_Count;
int y_index = i / x_Count;
for (int j = ; j < x_CountList.Count; j++)
{
if (x_index <= x_CountList[j])
{
x_index = j;
break;
}
}
for (int j = ; 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(), );
}

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

第一步:分别进行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 = ;
double yDi = ;
double xDi = ;
for (int i = ; i < sr_dataList_y_Order.Count - ; i++)
{
tempDi = Math.Abs(sr_dataList_y_Order[i + ].min.y - sr_dataList_y_Order[i].min.y);
if (tempDi > 0.01 && yDi > tempDi)
yDi = tempDi;
}
for (int i = ; i < sr_dataList_x_Order.Count - ; i++)
{
tempDi = Math.Abs(sr_dataList_x_Order[i + ].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[].angle - );
if ( < PcsAng && PcsAng < )
{
x_array = (int)Math.Ceiling(profile.Prof.size.y / sr_dataList[].size.y);
y_array = (int)Math.Ceiling(profile.Prof.size.x / sr_dataList[].size.x);
xWidth = sr_dataList[].size.y;
yHeigth = sr_dataList[].size.x;
}
else
{
x_array = (int)Math.Ceiling(profile.Prof.size.x / sr_dataList[].size.x);
y_array = (int)Math.Ceiling(profile.Prof.size.y / sr_dataList[].size.y);
xWidth = sr_dataList[].size.x;
yHeigth = sr_dataList[].size.y;
}
Mod_Sr_data[,] sr_dataArray = new Mod_Sr_data[x_array, y_array];
for (int i = ; 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();
List<int> y_CountList = new List<int>();
y_CountList.Add();
for (int i = ; i < x_array-; i++)
{
for (int j = ; j < y_array-; j++)
{
var aa = sr_dataArray[i, j]; }
}
}

方法三:最近邻聚类算法

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

方法五:扩边求解

PCB genesis SET取中心点--算法实现的更多相关文章

  1. K中心点算法之PAM

    一.PAM聚类算法:         选用簇中位置最中心的对象,试图对n个对象给出k个划分:代表对象也被称为是中心点,其他对象则被称为非代表对象:最初随机选择k个对象作为中心点,该算法反复地用非代表对 ...

  2. PCB Genesis SET拼板(圆形板拼板) 实现效果(二)

    越来发现Genesis采用Surface多边形数据结构的重要性了,当撑握了多边形缩放,交集, 差集,并集等算法, 想实现PCB拼板简直轻而易举了;当然借助多边形算法可以开发出更多的PCB实用的工具出来 ...

  3. PCB genesis自制孔点 Font字体实现方法

    一.先看genesis原有Font字体 在PCB工程CAM加孔点字体要求时,通常我们直接用Geneis软件给我们提供了2种孔点字体canned_57与canned_67,但此字体可能不能满足各个工厂个 ...

  4. 【转】C语言快速幂取模算法小结

    (转自:http://www.jb51.net/article/54947.htm) 本文实例汇总了C语言实现的快速幂取模算法,是比较常见的算法.分享给大家供大家参考之用.具体如下: 首先,所谓的快速 ...

  5. Raising Modulo Numbers_快速幂取模算法

    Description People are different. Some secretly read magazines full of interesting girls' pictures, ...

  6. 位运算之——按位与(&)操作——(快速取模算法)

    学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...

  7. 【Java基础】14、位运算之——按位与(&)操作——(快速取模算法)

    学习redis 字典结构,hash找槽位 求槽位的索引值时,用到了 hash值 & sizemask操作, 其后的scan操作涉及扫描顺序逻辑,对同模的槽位 按一定规则扫描! 其中涉及位运算 ...

  8. 09 Memcached 分布式之取模算法的缺陷

    一: Memcached 分布式之取模算法的缺陷(1)假设你有8台服务器,运行中突然down一台,则求余数的底数就7. 后果: key_0%8==0 ,key_0%7==0 =>hist(命中) ...

  9. [原创][开源] SunnyUI.Net 开发日志:UIBarChart 坐标轴刻度取值算法

    _ 在开发UIBarChart的过程中,需要绘制Y轴的刻度,数据作图时,纵横坐标轴刻度范围及刻度值的取法,很大程度上取决于数据的分布.对某一组数据,我们很容易就能知道如何选取这些值才能使图画得漂亮.但 ...

随机推荐

  1. Python爬虫入门教程: 27270图片爬取

    今天继续爬取一个网站,http://www.27270.com/ent/meinvtupian/ 这个网站具备反爬,so我们下载的代码有些地方处理的也不是很到位,大家重点学习思路,有啥建议可以在评论的 ...

  2. BZOJ 2274 [Usaco2011 Feb]Generic Cow Protests

    [题解] 很容易可以写出朴素DP方程f[i]=sigma f[j] (sum[i]>=sum[j],1<=j<=i).  于是我们用权值树状数组优化即可. #include<c ...

  3. 恶补---bell数

    定义 bell数即一个集合划分的数目 示例 前几项的bell数列为 1, 1, 2, 5, 15, 52, 203, 877, 4140, 21147, 115975 ,... 求值方法 1.bell ...

  4. Spring核心技术(三)——Spring的依赖及其注入(续)

    本文将继续前文,针对依赖注入的细节进行描述 依赖注入细节 如前文所述,开发者可以通过定义Bean的依赖的来引用其他的Bean或者是一些值的,Spring基于XML的配置元数据通过支持一些子元素< ...

  5. idea中找不到maven projects的集中解决办法

    今天正常打开idea,却发现maven窗口找不到了:试了这些方法 首先idea自带了maven控件,不像Eclipse还需要下载控件,如果你以前有maven在右边,出于某种原因,消失找不到 了,你可以 ...

  6. Garden of Eden

    Garden of Eden Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  7. Wow! Such Sequence! (线段树) hdu4893

    http://acm.hdu.edu.cn/showproblem.php?pid=4893 先贴上一份还没过的代码,不知道拿出错了  1 // by caonima ; ; ],col[MAX< ...

  8. Navicat使用技巧

    1.有时按快捷键Ctrl+F搜某条数据的时候搜不到,但是能用sql查出来,这是怎么回事? Ctrl+F只能搜本页数据,不在本页的数据搜不到,navicat每页只显示1000条数据.在数据多的时候nav ...

  9. F - Piggy-Bank 完全背包问题

    Before ACM can do anything, a budget must be prepared and the necessary financial support obtained. ...

  10. Linux基本命令总结(初学者可以借鉴学习)

    Linux基本常用命令 个人在平时项目中用到的一些常规命令总结下 删除文件夹命令:rm -rf 目录名字 添加模式:按i 退出编辑模式:ese左上角键 首先先按esc退出进入一个模式然后再输入wq或者 ...