OTSIncAReportFun.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. 
  2. using OTSIncAReportApp.DataOperation.DataAccess;
  3. using OTSIncAReportApp.DataOperation.Model;
  4. using OTSIncAReportApp.SysMgrTools;
  5. using OTSIncAReportGraph.Class;
  6. using OTSIncAReportGraph.Controls;
  7. using System;
  8. using System.Collections;
  9. using System.Collections.Generic;
  10. using System.Data;
  11. using System.Diagnostics;
  12. using System.Drawing;
  13. using System.Drawing.Drawing2D;
  14. using System.Linq;
  15. namespace OTSIncAReportGraph.OTSIncAReportGraphFuncation
  16. {
  17. class OTSIncAReportFun
  18. {
  19. #region 枚举定义
  20. /// <summary>
  21. /// 样品台X轴方向
  22. /// </summary>
  23. enum OTS_X_AXIS_DIRECTION
  24. {
  25. LEFT_TOWARD = 0,
  26. RIGHT_TOWARD = 1
  27. }
  28. /// <summary>
  29. /// 样品台Y轴方向
  30. /// </summary>
  31. enum OTS_Y_AXIS_DIRECTION
  32. {
  33. UP_TOWARD = 0,
  34. DOWN_TOWARD = 1
  35. }
  36. #endregion
  37. #region 定义变量
  38. private ResultFile resultFile = null;
  39. //新版排序图窗体对象
  40. //private Control_DrawDistrbutionSortImage m_Control_DrawdistrbutionsortImage = null;
  41. //全局对象,为了能够快速的获取到xray数据,而做为一个临时变量进行保存,使用前应该判断是否为空
  42. public List<Field> m_list_OTSField = null;
  43. NLog.Logger log;
  44. //field的数量
  45. public int m_field_count = 0;
  46. //particle的数量
  47. public int m_particle_count = 0;
  48. //加载使用的时间
  49. public string m_time_str = "";
  50. //加载使用时间计算时间段2
  51. public string m_time_str2 = "";
  52. //电镜设置对象
  53. public ServiceInterface.SemController m_cfun = null;
  54. //是否已经连接到了电镜
  55. public bool m_SEMConnectionState = false;
  56. //连接到电镜的ID号
  57. public int m_SEM_ID = 0;
  58. //国际化
  59. //Language lan = new Language();
  60. //Hashtable table;
  61. #endregion
  62. #region 构造函数
  63. /// <summary>
  64. /// 构造函数,接收新版分布图和排序图的构造函数
  65. /// </summary>
  66. /// <param name="in_Control_DrawDistrbutionImageAndBSE"></param>
  67. /// <param name="in_Cotsreportprojfilemgrclr"></param>
  68. public OTSIncAReportFun( ResultFile result)
  69. {
  70. resultFile = result;
  71. m_cfun =new ServiceInterface.SemController();
  72. log = NLog.LogManager.GetCurrentClassLogger();
  73. //table = lan.GetNameTable("OTSIncAReportFun");
  74. }
  75. #endregion
  76. #region 封装自定义方法
  77. /// <summary>
  78. /// 通过传入的各field物理坐标列表,和单个field的屏幕分辨率,及单个的field的物理坐标,来获取当前field在整个image中的屏幕像素坐标偏移,并且是OTS向上为正做了Y轴相反运算
  79. /// </summary>
  80. /// <param name="in_list_point"></param>
  81. /// <param name="in_screen_width"></param>
  82. /// <param name="in_screen_height"></param>
  83. /// <param name="in_physics_width"></param>
  84. /// <param name="in_physics_height"></param>
  85. /// <returns></returns>
  86. public Point GetFieldPhysicsConvertToScreen(List<Point> in_list_point, int in_screen_width, int in_screen_height, Point in_physics_point)
  87. {
  88. //先确定单个物理坐标的宽和高
  89. Rectangle rect_onefield_wl = GetOneFieldWidthAndHeight(in_list_point);
  90. //找出最小的x,y用来做偏移运算
  91. int i_offset_x = 1000000000;
  92. int i_offset_y = 1000000000;
  93. //先取出最小的x,y
  94. for (int i = 0; i < in_list_point.Count; i++)
  95. {
  96. if (i_offset_x > in_list_point[i].X)
  97. {
  98. i_offset_x = in_list_point[i].X;
  99. }
  100. if (i_offset_y > in_list_point[i].Y)
  101. {
  102. i_offset_y = in_list_point[i].Y;
  103. }
  104. }
  105. List<Point> list_point = new List<Point>();
  106. //将各Field的OTS坐标与屏幕左上角的坐标进行相减,取出与屏幕左上角的偏移量,也就是取出了屏幕坐标
  107. int index = 0;
  108. for (int i = 0; i < in_list_point.Count; i++)
  109. {
  110. list_point.Add(new Point(in_list_point[i].X - i_offset_x, in_list_point[i].Y - i_offset_y));
  111. //根据物理坐标的对应关系,找到了在数组中的位置,下面将用该位置对应得出像素坐标的位置,并进行返回
  112. if (in_list_point[i] == in_physics_point)
  113. {
  114. index = i;
  115. }
  116. }
  117. //再将物理像素list_point换算成像素list_point,再用index定位
  118. for (int i = 0; i < list_point.Count; i++)
  119. {
  120. //将单个物理像素变换成屏幕像素分辨率
  121. int i_bs_x = 0;
  122. int i_bs_y = 0;
  123. if (rect_onefield_wl.Width != 0)
  124. i_bs_x = list_point[i].X / rect_onefield_wl.Width;
  125. if (rect_onefield_wl.Height != 0)
  126. i_bs_y = list_point[i].Y / rect_onefield_wl.Height;
  127. //再将屏幕像素分辨率按倍数赋值给list_point
  128. //考虑到OTS坐标整体是Y轴向上为正,所以这里需要根据总高,减y轴就是向上为正
  129. list_point[i] = new Point(in_screen_width * i_bs_x, in_screen_height * i_bs_y);
  130. }
  131. #region Y轴向上为正转换---------------------------------------------------------------------------------------
  132. //但上面由于相减,会出现y轴为负的情况,所以这里要根据Y轴是否出现负值,再次做偏移运算
  133. //找到最小的y轴,也就是 [Y轴偏移量]
  134. int i_offset_y_second = 100000000;
  135. //找到最大的Y轴,用于做相反运算,Y轴向上
  136. int i_screen_y = -100000000;
  137. for (int i = 0; i < list_point.Count; i++)
  138. {
  139. if (i_offset_y_second > list_point[i].Y)
  140. {
  141. i_offset_y_second = list_point[i].Y;//这个偏移Y就是最小的Y,可能是负数,也可能是0
  142. }
  143. if (i_screen_y < list_point[i].Y)
  144. {
  145. i_screen_y = list_point[i].Y;
  146. }
  147. }
  148. //对Y轴进行反转,OTS坐标向屏幕坐标转换
  149. for (int i = 0; i < list_point.Count; i++)
  150. {
  151. list_point[i] = new Point(list_point[i].X, i_screen_y - list_point[i].Y);
  152. }
  153. //再将所有的Field与这个 [Y轴偏移量] 相加,防止OTS向上为正转换屏幕坐标,造成的Y轴为负的情况
  154. for (int i = 0; i < list_point.Count; i++)
  155. {
  156. list_point[i] = new Point(list_point[i].X, list_point[i].Y + Math.Abs(i_offset_y_second));
  157. }
  158. #endregion Y轴向上为正转换结束--------------------------------------------------------------------------
  159. return list_point[index];
  160. }
  161. /// <summary>
  162. /// 根据type,从三种分类的分析库中提取当前分析物的颜色
  163. /// </summary>
  164. /// <param name="in_cotssampleclr"></param>
  165. /// <param name="in_stdtypeid"></param>
  166. /// <returns></returns>
  167. public Color GetColorBySTDTypeIDForBSEAndSorImage(string in_cotssampleclr, int in_stdtypeid)
  168. {
  169. Color ret_c = new Color();
  170. if (in_stdtypeid < 1000)
  171. {
  172. OTSSysSTDMgrClass osc = new OTSSysSTDMgrClass();
  173. //小于1000,使用系统默认分类
  174. ret_c = osc.GetColorByEnum(in_stdtypeid);
  175. }
  176. else if (in_stdtypeid >= 1000)
  177. {
  178. //大于等于1000,并且小于10000时,使用用户标准库来分析夹杂物名称
  179. if (!in_cotssampleclr.Contains("#"))
  180. {
  181. ret_c = DrawFunction.colorHx16toRGB("#" + in_cotssampleclr);//接收必须是#000000的格式
  182. }
  183. else
  184. {
  185. ret_c = DrawFunction.colorHx16toRGB(in_cotssampleclr);//接收必须是#000000的格式
  186. }
  187. }
  188. return ret_c;
  189. }
  190. /// <summary>
  191. /// 计算像素总画面Image大小,及进行物理坐标与分辨率坐标的换算操作 传入物理坐标,及宽高,来
  192. /// </summary>
  193. /// <param name="in_list_point">传入的物理坐标数组</param>
  194. /// <param name="width">单个field宽</param>
  195. /// <param name="height">单个field高</param>
  196. /// <returns></returns>
  197. public Rectangle ConvertAndGetMaxRect(List<Point> in_list_point, int in_width, int in_height)
  198. {
  199. //首先要能确定下来,单个物理坐标的宽和高--------------------------------
  200. int i_wl_width = 0;
  201. int i_wl_height = 0;
  202. Rectangle ls_r = GetOneFieldWidthAndHeight(in_list_point);
  203. i_wl_width = ls_r.Width;
  204. i_wl_height = ls_r.Height;
  205. //-----------------------------------------------------------------------------
  206. int point_x_min = 10000000;
  207. int point_x_max = -10000000;
  208. int point_y_min = 10000000;
  209. int point_y_max = -10000000;
  210. for (int i = 0; i < in_list_point.Count(); i++)
  211. {
  212. Point ls_point = in_list_point[i];
  213. //取出正数最大x
  214. if (ls_point.X > point_x_max)
  215. point_x_max = ls_point.X;
  216. if (ls_point.Y > point_y_max)
  217. point_y_max = ls_point.Y;
  218. if (ls_point.X < point_x_min)
  219. point_x_min = ls_point.X;
  220. if (ls_point.Y < point_y_min)
  221. point_y_min = ls_point.Y;
  222. }
  223. //然后分别用最大值+abs(最小值),就是x,和y轴的总长值
  224. point_x_max = point_x_max - point_x_min;
  225. point_y_max = point_y_max - point_y_min;
  226. //该算法有个问题,就是不能直观的得到整个范围的大小,要除以倍数再补1能补充缺少的一个field视域**********
  227. point_x_max = ((point_x_max / i_wl_width) + 1) * i_wl_width;
  228. point_y_max = ((point_y_max / i_wl_height) + 1) * i_wl_height;
  229. //将物理宽高,变换成分辨率宽高
  230. if (i_wl_width != 0) point_x_max = (point_x_max / i_wl_width) * in_width; else point_x_max = 0;
  231. if (i_wl_height != 0) point_y_max = (point_y_max / i_wl_height) * in_height; else point_y_max = 0;
  232. Rectangle ret_rectangle = new Rectangle(0, 0, 0, 0);
  233. //判断一下防止出错,只有在有数据的情况下,进行赋值才行
  234. if (in_list_point.Count > 0)
  235. {
  236. ret_rectangle = new Rectangle(0, 0, point_x_max, point_y_max);
  237. }
  238. //这样返回是物理坐标的总大小,应该返回像素坐标大小才对
  239. return ret_rectangle;
  240. }
  241. /// <summary>
  242. /// 计算单个field的物理大小 传入field的list,还有测量结果管理类对象,在无法计算出单file的物理大小的情况下,到这里取再计算得出
  243. /// </summary>
  244. /// <returns></returns>
  245. public Rectangle GetOneFieldWidthAndHeight(List<Point> in_list_point)
  246. {
  247. int i_wl_width_max = -10000000;
  248. int i_wl_height_max = -10000000;
  249. int i_wl_width_max2 = -10000000;
  250. int i_wl_height_max2 = -10000000;
  251. //先找出最大的值,
  252. for (int i = 0; i < in_list_point.Count(); i++)
  253. {
  254. if (i_wl_width_max < in_list_point[i].X)
  255. i_wl_width_max = in_list_point[i].X;
  256. if (i_wl_height_max < in_list_point[i].Y)
  257. i_wl_height_max = in_list_point[i].Y;
  258. }
  259. //再找出第二大的值
  260. for (int i = 0; i < in_list_point.Count(); i++)
  261. {
  262. if (i_wl_width_max2 < in_list_point[i].X && i_wl_width_max != in_list_point[i].X)
  263. i_wl_width_max2 = in_list_point[i].X;
  264. if (i_wl_height_max2 < in_list_point[i].Y && i_wl_height_max != in_list_point[i].Y)
  265. i_wl_height_max2 = in_list_point[i].Y;
  266. }
  267. //需要针对第二大的值,获取时进行判断,感觉这里应该如果并未找到第二大的值的情况下,赋于0值,便于以后进行计算
  268. if (i_wl_width_max2 == -10000000)
  269. i_wl_width_max2 = 0;
  270. if (i_wl_height_max2 == -10000000)
  271. i_wl_height_max2 = 0;
  272. Rectangle ret_rect = new Rectangle(0, 0, i_wl_width_max - i_wl_width_max2, i_wl_height_max - i_wl_height_max2);
  273. //如果最后计算出的宽高有0则重新到测量数据中获取---------------------------------------
  274. if (ret_rect.Width == 0 || ret_rect.Height == 0)
  275. {
  276. //到参数中去取单个宽
  277. double d_onefilesize_width = Convert.ToDouble(((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["scanFieldSize"]);
  278. //然后再用单个宽去计算出高是多少
  279. double d_onefilesize_height = 0;
  280. if (d_onefilesize_width != 0)
  281. d_onefilesize_height = (d_onefilesize_width / 4) * 3;
  282. ret_rect.Width = (int)d_onefilesize_width;
  283. ret_rect.Height = (int)d_onefilesize_height;
  284. }
  285. ///-----------because all the fields 's height/width=0.75 so here we make an enforce. gsp add at 2019/10/31
  286. ///sometimes the gbfields are not conform to this for the cuting and merging operation.
  287. //if (ret_rect.Height / ret_rect.Width != 0.75f)
  288. //{
  289. // ret_rect = new Rectangle(ret_rect.X, ret_rect.Y, ret_rect.Width, (int)(ret_rect.Width * 0.75f));
  290. //}
  291. return ret_rect;
  292. }
  293. #endregion
  294. #region 电镜操作相关方法
  295. /// <summary>
  296. /// 连接电镜,分布图使用
  297. /// </summary>
  298. public void ConnectToSEM()
  299. {
  300. log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + "Connect to SEM");
  301. if (!m_SEMConnectionState)
  302. {
  303. //和电镜建立通讯连接
  304. m_SEMConnectionState = m_cfun.Connect();
  305. log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + "Connect to SEM" + ":--" + m_SEMConnectionState + "---");
  306. }
  307. else
  308. {
  309. log.Trace("(Connection_ForDrawDistrbutionImageAndBSE)" + ":allready connected, state:" + m_SEMConnectionState);
  310. //断开电镜连接
  311. }
  312. }
  313. public void DisConnectSEM()
  314. {
  315. m_SEMConnectionState = false;
  316. m_cfun.DisConnect();
  317. }
  318. /// <summary>
  319. /// 移动电镜到指定的X,Y坐标上,R坐标使用原先的值进行移动
  320. /// </summary>
  321. /// <param name="PositionX"></param>
  322. /// <param name="PositionY"></param>
  323. public void MoveSemToPointXY(double in_PositionX, double in_PositionY)
  324. {
  325. log.Trace("Begin MoveSemToPointXY:(" +in_PositionX.ToString()+","+in_PositionY.ToString()+")");
  326. //首先获取电镜当前的位置,并记录原R值
  327. double ls_PositionX = 0;
  328. double ls_PositionY = 0;
  329. double ls_PositionR = 0;
  330. if (m_SEMConnectionState)
  331. {
  332. m_cfun.GetSemPositionXY(ref ls_PositionX, ref ls_PositionY, ref ls_PositionR);
  333. }
  334. else
  335. {
  336. log.Error("Failed to GetSemPositionXY");
  337. return;
  338. }
  339. if (m_SEMConnectionState)
  340. {
  341. m_cfun.MoveSEMToPoint(new Point((int)in_PositionX, (int)in_PositionY), ls_PositionR);
  342. }
  343. }
  344. #endregion
  345. #region //--------------------------------------颗粒分布图相关部份---------------------------------------------------------------------
  346. /// <summary>
  347. /// 传入颗粒的tagid和fieldid,来获取该颗粒下对应的xray数据
  348. /// </summary>
  349. /// <param name="in_clr_tagid"></param>
  350. /// <param name="in_clr_fieldid"></param>
  351. /// <param name="Search_xray"></param>
  352. /// <param name="Analysis_xray"></param>
  353. public void GetXrayByParticleTagIDAndFieldID_ForDrawDistrbutionImageAndBSE(int in_clr_tagid, int in_clr_fieldid, out uint[] Search_xray, out uint[] Analysis_xray, out int xray_id, out List<Element> list_celementchemistryclr)
  354. {
  355. Search_xray = new uint[2000];
  356. Analysis_xray = new uint[2000];
  357. xray_id = 0;
  358. list_celementchemistryclr = new List<Element>();
  359. //防止为空校验判断
  360. if (m_list_OTSField == null)
  361. return;
  362. Particle particle = m_list_OTSField.Find(x => x.FieldID == in_clr_fieldid).ParticleList.Find(x => x.ParticleId == in_clr_tagid);
  363. var tmpPart = new ParticleData(resultFile.FilePath).GetParticleXrayDataByFidAndPid(Convert.ToString(particle.FieldId), Convert.ToString(particle.XrayId));
  364. particle.XRayData = tmpPart.XRayData;
  365. if (particle.XrayId > -1)
  366. {
  367. for (int i = 0; i < 2000; i++)
  368. {
  369. Analysis_xray[i] = BitConverter.ToUInt32(particle.XRayData, i * 4);
  370. }
  371. Search_xray = Analysis_xray;
  372. xray_id = particle.XrayId;
  373. list_celementchemistryclr = particle.ElementList;
  374. }
  375. }
  376. /// <summary>
  377. /// 传入所有的物理field坐标点,和单个物理field的宽高,返回所有field的左上角位置,和整个field组成的rect大小
  378. /// </summary>
  379. /// <param name="in_list_point"></param>
  380. /// <param name="in_width"></param>
  381. /// <param name="in_height"></param>
  382. /// <returns></returns>
  383. public Rectangle GetWlRectTopLeftAndRect(List<Point> in_list_point, int in_width, int in_height)
  384. {
  385. //分别获取整个rect的xy最小值和最大值
  386. int i_rect_x_min = 100000000;
  387. int i_rect_y_min = 100000000;
  388. int i_rect_x_max = -100000000;
  389. int i_rect_y_max = -100000000;
  390. for (int i = 0; i < in_list_point.Count; i++)
  391. {
  392. if (i_rect_x_min > in_list_point[i].X)
  393. i_rect_x_min = in_list_point[i].X;
  394. if (i_rect_y_min > in_list_point[i].Y)
  395. i_rect_y_min = in_list_point[i].Y;
  396. if (i_rect_x_max < in_list_point[i].X)
  397. i_rect_x_max = in_list_point[i].X;
  398. if (i_rect_y_max < in_list_point[i].Y)
  399. i_rect_y_max = in_list_point[i].Y;
  400. }
  401. Rectangle ret_rect = new Rectangle(i_rect_x_min, i_rect_y_min,
  402. i_rect_x_max - i_rect_x_min, i_rect_y_max - i_rect_y_min);
  403. return ret_rect;
  404. }
  405. /// <summary>
  406. /// 根据Field的ID,来获取Field列表中对应FIeld的OTS 坐标
  407. /// </summary>
  408. /// <param name="in_fieldid"></param>
  409. /// <returns></returns>
  410. public Point GetOTSPointByFieldID(List<DField> in_list_dfield, int in_fieldid)
  411. {
  412. Point ret_point = new Point(0, 0);
  413. for (int i = 0; i < in_list_dfield.Count; i++)
  414. {
  415. //这里TagID先代表的是底层返回的ID
  416. if (in_list_dfield[i].FieldID == in_fieldid.ToString())
  417. {
  418. ret_point = new Point(Convert.ToInt32(in_list_dfield[i].OTS_RECT.X), Convert.ToInt32(in_list_dfield[i].OTS_RECT.Y));
  419. }
  420. }
  421. return ret_point;
  422. }
  423. /// <summary>
  424. /// 将OTS坐标转换为Sem 坐标
  425. /// </summary>
  426. /// <param name="POTSCoord"></param>
  427. /// <returns></returns>
  428. public Point ChangeOTSToSemCoord(Point POTSCoord)
  429. {
  430. //first if m_semstagedata is null to get stage inforation
  431. Convert.ToDouble(((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["scanFieldSize"]);
  432. //after obtaining stage info,calc stage point data
  433. Point ret_SEM_point = new Point();
  434. // get center point, um
  435. long xStart = Convert.ToInt64(((Dictionary<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["Members"])["XAxis"])["start"]);
  436. long xEnd = Convert.ToInt64(((Dictionary<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["Members"])["XAxis"])["end"]);
  437. long xCenter = (xStart + xEnd) / 2;
  438. long yStart = Convert.ToInt64(((Dictionary<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["Members"])["YAxis"])["start"]);
  439. long yEnd = Convert.ToInt64(((Dictionary<string, object>)((Dictionary<string, object>)((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["Members"])["YAxis"])["end"]);
  440. long yCenter = (yStart + yEnd) / 2;
  441. // delte = SEM - OTSa
  442. long deltex = xCenter - 0;
  443. long deltey = yCenter - 0;
  444. int xdir = Convert.ToInt32(((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["xAxisDir"]);
  445. int ydir = Convert.ToInt32(((Dictionary<string, object>)resultFile.ResultInfo["SEMStageData"])["yAxisDir"]);
  446. if (xdir == (int)OTS_X_AXIS_DIRECTION.LEFT_TOWARD)
  447. {
  448. ret_SEM_point.X = -1 * (POTSCoord.X - Convert.ToInt32(deltex));
  449. }
  450. else if (xdir == (int)OTS_X_AXIS_DIRECTION.RIGHT_TOWARD)
  451. {
  452. ret_SEM_point.X = POTSCoord.X + Convert.ToInt32(deltex);
  453. }
  454. if (ydir == (int)OTS_Y_AXIS_DIRECTION.UP_TOWARD)
  455. {
  456. ret_SEM_point.Y = POTSCoord.Y + Convert.ToInt32(deltey);
  457. }
  458. else if (ydir == (int)OTS_Y_AXIS_DIRECTION.DOWN_TOWARD)
  459. {
  460. ret_SEM_point.Y = -1 * (POTSCoord.Y - Convert.ToInt32(deltey));
  461. }
  462. return ret_SEM_point;
  463. }
  464. #endregion
  465. /// <summary>
  466. /// 判断该点是否在多边形的范围内
  467. /// </summary>
  468. /// <param name="inPoints"></param>
  469. /// <param name="WhetherPoint"></param>
  470. /// <returns></returns>
  471. public bool WhetherInRange(DParticle Part,/*PointF[] inPoints,*/ Point WhetherPoint)
  472. {
  473. var rect = Part.Rect;
  474. if ((rect.Left < WhetherPoint.X && WhetherPoint.X < rect.Right) && (rect.Top < WhetherPoint.Y && WhetherPoint.Y < rect.Bottom))
  475. {
  476. var itm = (BaseObject)Part;
  477. PointF[] inPoints = itm.GPath.PathPoints;
  478. bool b_inrange = false;
  479. GraphicsPath myGraphicsPath = new GraphicsPath();
  480. Region myRegion = new Region();
  481. myGraphicsPath.Reset();
  482. myGraphicsPath.AddPolygon(inPoints);
  483. myRegion.MakeEmpty();
  484. myRegion.Union(myGraphicsPath);
  485. //返回判断点是否在多边形里
  486. b_inrange = myRegion.IsVisible(WhetherPoint);
  487. return b_inrange;
  488. }
  489. else
  490. {
  491. return false;
  492. }
  493. }
  494. /// <summary>
  495. /// 判断该点是否在多边形的范围内的float版本重载
  496. /// </summary>
  497. /// <param name="inPoints"></param>
  498. /// <param name="WhetherPoint"></param>
  499. /// <returns></returns>
  500. public bool WhetherInRange(DParticle Part,/* PointF[] inPoints, */PointF WhetherPoint)
  501. {
  502. var rect = Part.Rect;
  503. if ((rect.Left < WhetherPoint.X && WhetherPoint.X < rect.Right) && (rect.Top < WhetherPoint.Y && WhetherPoint.Y < rect.Bottom))
  504. {
  505. var itm = (BaseObject)Part;
  506. PointF[] inPoints = itm.GPath.PathPoints;
  507. bool b_inrange = false;
  508. GraphicsPath myGraphicsPath = new GraphicsPath();
  509. Region myRegion = new Region();
  510. myGraphicsPath.Reset();
  511. myGraphicsPath.AddPolygon(inPoints);
  512. myRegion.MakeEmpty();
  513. myRegion.Union(myGraphicsPath);
  514. //返回判断点是否在多边形里
  515. b_inrange = myRegion.IsVisible(WhetherPoint);
  516. return b_inrange;
  517. }
  518. else
  519. {
  520. return false;
  521. }
  522. }
  523. #region //--------------------------------------颗粒排序图相关部份---------------------------------------------------------------------
  524. /// <summary>
  525. /// 根据传入的fieldid和tagid返回该颗粒的OTS坐标
  526. /// </summary>
  527. /// <param name="in_fieldid"></param>
  528. /// <param name="in_tagid"></param>
  529. /// <returns></returns>
  530. public Point GetOTSPointFromOld_list_sortparticledistribution(int in_fieldid, int in_tagid, Control_DrawDistrbutionSortImage in_control_drawdistrbutionsortimage)
  531. {
  532. Point ret_point = new Point(0, 0);
  533. if (m_list_OTSField != null)
  534. {
  535. Field field = m_list_OTSField.Find(x => x.FieldID == in_fieldid);
  536. ret_point = new Point() { X = field.FieldPosX, Y = field.FieldPosY };
  537. }
  538. return ret_point;
  539. }
  540. #endregion
  541. }
  542. }