DisplayParticle.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732
  1. using DevExpress.Utils.Extensions;
  2. using OTSCommon.DBOperate.Model;
  3. using OTSIncAReportGraph.Class;
  4. using OTSMeasureApp._0_OTSModel.OTSDataType;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Diagnostics;
  8. using System.Drawing;
  9. using System.Drawing.Drawing2D;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Threading.Tasks;
  13. using System.Windows.Forms;
  14. namespace OTSIncAReportGraph
  15. {
  16. /// <summary>
  17. /// Particle对象上操作状态的枚举
  18. /// </summary>
  19. public enum PaintState
  20. {
  21. PAINT = 0,
  22. NOPAINT = 1,
  23. CONCISEPAINT=2,// display as a "+"
  24. }
  25. public enum DisplayState
  26. {
  27. DISPLAY = 0,
  28. NODISPLAY = 1,
  29. }
  30. /// <summary>
  31. /// Particle对象上操作xray的枚举状态,显示xray数据,不显示
  32. /// </summary>
  33. public enum ParticleShowXray
  34. {
  35. DISPLAYXRAY = 0,
  36. NODISPLAY = 1,
  37. }
  38. /// <summary>
  39. /// Segment对象绘制的枚举,以点绘制,还是以线绘制
  40. /// </summary>
  41. public enum SegmentShowMode
  42. {
  43. DRAWPARTICLEIMAGE = 0,
  44. DRAWCOLORIMAGE = 1,
  45. }
  46. /// <summary>
  47. /// 颗粒类
  48. /// </summary>
  49. public class DisplayParticle : ICloneable
  50. {
  51. private const float m_zoom_displayThreshold = 0.1f;
  52. public Particle objParticleData;
  53. private Guid m_id;
  54. private RectangleF m_Globalrect;
  55. private PointF m_OTSPointF;
  56. private RectangleF m_smallRect;
  57. private bool m_isSelected;
  58. private bool m_isDeleted;
  59. private bool m_isMouseOver;
  60. private PaintState m_paintState = PaintState.PAINT;
  61. private ParticleShowXray m_operator_showxray = ParticleShowXray.NODISPLAY;//选定显示XRAY,不显示XRAY,默认应为(不显示XRAY)
  62. private bool m_isdragging;
  63. private PointF m_dragingpoint;
  64. private Color m_color;
  65. private DisplayState m_displayState;
  66. private SegmentShowMode show_mode = SegmentShowMode.DRAWPARTICLEIMAGE;//绘线,绘点,默认绘点,意思为默认显示BSE原图像
  67. private Bitmap m_BSEimage;
  68. private Bitmap m_Colorimage;
  69. private Bitmap originalFieldImage;
  70. private string m_sort_type = "从大到小";
  71. private float m_f_size = 0;
  72. private string m_str_lj = "颗粒粒级";
  73. private string m_str_klzl = "颗粒种类";
  74. private string m_str_klfl = "颗粒分类";
  75. private float m_CurrentZoomNum = 1;
  76. public COTSRect OTSRect=new COTSRect();
  77. public int TypeId
  78. {
  79. get
  80. {
  81. return objParticleData.TypeId;
  82. }
  83. }
  84. //TypeName
  85. public string TypeName
  86. {
  87. get
  88. {
  89. return objParticleData.TypeName;
  90. }
  91. }
  92. //XRayId
  93. public int XRayId
  94. {
  95. get
  96. {
  97. return objParticleData.XrayId;
  98. }
  99. }
  100. public int SEMPosX
  101. {
  102. get
  103. {
  104. return objParticleData.SEMPosX;
  105. }
  106. }
  107. public int SEMPosY
  108. {
  109. get
  110. {
  111. return objParticleData.SEMPosY;
  112. }
  113. }
  114. public DisplayParticle()
  115. {
  116. m_id = System.Guid.NewGuid();
  117. }
  118. public DisplayParticle(Particle part)
  119. {
  120. m_id = System.Guid.NewGuid();
  121. objParticleData = part;
  122. this.Color = DrawFunction.GetColorBySTDTypeIDForBSEAndSorImage(part.TypeColor, part.TypeId);
  123. }
  124. public DisplayParticle(Particle particle,PointF FieldLeftTop,Bitmap a_originalFieldImage/*,Bitmap fieldParticleImage*/)
  125. {
  126. m_id = System.Guid.NewGuid();
  127. objParticleData = particle;
  128. originalFieldImage = a_originalFieldImage;
  129. this.Color = DrawFunction.GetColorBySTDTypeIDForBSEAndSorImage(particle.TypeColor, particle.TypeId);
  130. SetPaintState(PaintState.PAINT);
  131. m_Globalrect.X = particle.RectLeft + FieldLeftTop.X;
  132. m_Globalrect.Y = particle.RectTop + FieldLeftTop.Y;
  133. m_Globalrect.Width = particle.RectWidth;
  134. m_Globalrect.Height = particle.RectHeight;
  135. }
  136. public void InitImageData()
  137. {
  138. List<Segment> list_seg;
  139. list_seg = objParticleData.SegmentList;
  140. this.m_BSEimage = new Bitmap(objParticleData.RectWidth + 1, objParticleData.RectHeight + 1);
  141. this.m_Colorimage = new Bitmap(objParticleData.RectWidth + 1, objParticleData.RectHeight + 1);
  142. //再循环取出里面所有的segment
  143. foreach (Segment seg in list_seg)
  144. {
  145. #region
  146. //合成图像完成,开始抠取像素-----------------------------------------------------------------
  147. for (int m = 0; m < seg.Length; m++)
  148. {
  149. int lsjs_x = seg.Start + m;
  150. int lsjs_y = seg.Height;
  151. var pixelColor = originalFieldImage.GetPixel(lsjs_x, lsjs_y);
  152. lsjs_x = seg.Start - objParticleData.RectLeft + m;
  153. lsjs_y = seg.Height - objParticleData.RectTop;
  154. //Debug.Assert(lsjs_x > -1);
  155. //Debug.Assert(lsjs_y > -1);
  156. //Debug.Assert(lsjs_x < m_BSEimage.Width);
  157. //Debug.Assert(lsjs_y< m_BSEimage.Height);
  158. m_BSEimage.SetPixel(lsjs_x, lsjs_y, pixelColor);//ls_list_colors[m]
  159. m_Colorimage.SetPixel(lsjs_x, lsjs_y, m_color);
  160. }
  161. #endregion //------------------------------------------------------------------------------
  162. }
  163. }
  164. public bool WhetherInRange(Point WhetherPoint)
  165. {
  166. var rect = GetShowRect();
  167. if(rect.Contains(WhetherPoint))
  168. {
  169. m_smallRect = GetSmallRectangleFromRect();
  170. bool b_inrange;
  171. b_inrange=m_smallRect.Contains(WhetherPoint);
  172. return b_inrange;
  173. }
  174. else
  175. {
  176. return false;
  177. }
  178. }
  179. public DisplayParticle( DisplayParticle in_particle)
  180. {
  181. objParticleData = in_particle.objParticleData;
  182. m_id = in_particle.m_id;
  183. m_paintState = in_particle.m_paintState;
  184. m_operator_showxray = in_particle.m_operator_showxray;
  185. m_Globalrect = in_particle.m_Globalrect;
  186. this.m_BSEimage = in_particle.m_BSEimage;
  187. this.m_Colorimage = in_particle.m_Colorimage;
  188. }
  189. /// <summary>
  190. /// 设置显示的方式,可以用,绘线显示查看标准库颜色的,也可以用绘点,查看BSE原图颗粒图色的
  191. /// </summary>
  192. public SegmentShowMode ShowMode
  193. {
  194. get { return show_mode; }
  195. set { show_mode = value; }
  196. }
  197. /// <summary>
  198. /// 克隆方法
  199. /// </summary>
  200. /// <returns></returns>
  201. public object Clone()
  202. {
  203. return new DisplayParticle( this);
  204. }
  205. public PointF GetCenterPoint()
  206. {
  207. return new PointF(m_Globalrect.X + m_Globalrect.Width / 2, m_Globalrect.Y + m_Globalrect.Height / 2);
  208. }
  209. /// <summary>
  210. /// ID
  211. /// </summary>
  212. public Guid guid
  213. {
  214. get { return m_id; }
  215. set { m_id = value; }
  216. }
  217. /// <summary>
  218. /// 颗粒的外边框大小
  219. /// </summary>
  220. public RectangleF GetShowRect()
  221. {
  222. return m_Globalrect;
  223. }
  224. public void SetShowRect(RectangleF rectangleF)
  225. {
  226. m_Globalrect= rectangleF;
  227. }
  228. /// <summary>
  229. /// OTSPointF
  230. /// </summary>
  231. public PointF OTSPointF
  232. {
  233. get { return m_OTSPointF; }
  234. set { m_OTSPointF = value; }
  235. }
  236. public bool IsSelect
  237. {
  238. get { return m_isSelected; }
  239. set { m_isSelected = value; }
  240. }
  241. /// <summary>
  242. /// 该颗粒是否被设置成,选中状态
  243. /// </summary>
  244. public PaintState GetPaintState()
  245. {
  246. if (GetDisplayState() == DisplayState.NODISPLAY)
  247. {
  248. m_paintState = PaintState.NOPAINT;
  249. }
  250. return m_paintState;
  251. }
  252. /// <summary>
  253. /// 该颗粒是否被设置成,选中状态
  254. /// </summary>
  255. public void SetPaintState(PaintState value)
  256. {
  257. if (value == PaintState.PAINT)
  258. {
  259. if (m_CurrentZoomNum >= m_zoom_displayThreshold)
  260. {
  261. m_paintState = PaintState.PAINT;
  262. }
  263. else
  264. {
  265. m_paintState = PaintState.CONCISEPAINT;
  266. }
  267. }
  268. else
  269. {
  270. m_paintState = value;
  271. }
  272. }
  273. /// <summary>
  274. /// 是否对该颗粒选定显示X-Ray能谱图
  275. /// </summary>
  276. public ParticleShowXray Operator_ShowXRay
  277. {
  278. get { return m_operator_showxray; }
  279. set { m_operator_showxray = value; }
  280. }
  281. /// <summary>
  282. /// 是否在被拖动
  283. /// </summary>
  284. public bool IsDragging
  285. {
  286. get { return m_isdragging; }
  287. set { m_isdragging = value; }
  288. }
  289. /// <summary>
  290. /// 被拖动到的位置坐标
  291. /// </summary>
  292. public PointF DraggingPoint
  293. {
  294. get { return m_dragingpoint; }
  295. set {
  296. m_dragingpoint = value;
  297. }
  298. }
  299. /// <summary>
  300. /// 线的颜色
  301. /// </summary>
  302. public Color Color
  303. {
  304. get { return m_color; }
  305. set { m_color = value; }
  306. }
  307. /// <summary>
  308. /// 里面包含的多个线的集合
  309. /// </summary>
  310. public List<Segment> GetDSegments()
  311. { return objParticleData.SegmentList; }
  312. public void Zoom(float zoomDelta,PointF refPoint)
  313. {
  314. //var rec = m_rect;
  315. m_Globalrect.Width = (float)(m_Globalrect.Width + Convert.ToDouble(m_Globalrect.Width / m_CurrentZoomNum * zoomDelta));
  316. m_Globalrect.Height = (float)(m_Globalrect.Height + Convert.ToDouble(m_Globalrect.Height / m_CurrentZoomNum * zoomDelta));
  317. //锚点缩放补差值计算,得出差值
  318. float xShiftOld = m_Globalrect.X - refPoint.X;
  319. float yShiftOld = m_Globalrect.Y - refPoint.Y;
  320. float xShift = m_Globalrect.X - refPoint.X + xShiftOld / m_CurrentZoomNum * zoomDelta;
  321. float yShift = m_Globalrect.Y - refPoint.Y + yShiftOld / m_CurrentZoomNum * zoomDelta;
  322. //对背景矩形与所有的segment进行修补差值
  323. m_Globalrect.X = refPoint.X + xShift;
  324. m_Globalrect.Y = refPoint.Y + yShift;
  325. m_CurrentZoomNum += zoomDelta;
  326. if (m_CurrentZoomNum < 0.7)
  327. {
  328. m_isMouseOver = false;
  329. }
  330. //设置缩放到多少倍时进行显示
  331. if (m_CurrentZoomNum >= m_zoom_displayThreshold)
  332. {
  333. m_paintState = PaintState.PAINT;
  334. }
  335. else
  336. {
  337. m_paintState = PaintState.CONCISEPAINT;
  338. }
  339. }
  340. public void DraggingMove(PointF mousePoint)
  341. {
  342. m_Globalrect.X = m_Globalrect.X + mousePoint.X - this.DraggingPoint.X; //获取到原先点与移动点的增减量,+原先的x坐标,就是新的坐标
  343. m_Globalrect.Y = m_Globalrect.Y + mousePoint.Y - this.DraggingPoint.Y;
  344. this.DraggingPoint = mousePoint;
  345. }
  346. public void Move(SizeF xyShift)
  347. {
  348. m_Globalrect.X =m_Globalrect.X - xyShift.Width; //获取到原先点与移动点的增减量,+原先的x坐标,就是新的坐标
  349. m_Globalrect.Y = m_Globalrect.Y - xyShift.Height;
  350. }
  351. /// <summary>
  352. /// 设置排序的类型
  353. /// </summary>
  354. public string SortType
  355. {
  356. get { return m_sort_type; }
  357. set { m_sort_type = value; }
  358. }
  359. /// <summary>
  360. /// 设置该多边形的尺寸大小
  361. /// </summary>
  362. public float FSize
  363. {
  364. get { return m_f_size; }
  365. set { m_f_size = value; }
  366. }
  367. /// <summary>
  368. /// 设置粒级
  369. /// </summary>
  370. public string ParticleLJ
  371. {
  372. get { return m_str_lj; }
  373. set { m_str_lj = value; }
  374. }
  375. /// <summary>
  376. /// 设置种类
  377. /// </summary>
  378. public string ParticleZL
  379. {
  380. get { return m_str_klzl; }
  381. set { m_str_klzl = value; }
  382. }
  383. /// <summary>
  384. /// 设置分类
  385. /// </summary>
  386. public string ParticleFL
  387. {
  388. get { return m_str_klfl; }
  389. set { m_str_klfl = value; }
  390. }
  391. /// <summary>
  392. /// 获取或设置该Particle对应底层的FieldID值
  393. /// </summary>
  394. public int FieldId
  395. {
  396. get { return objParticleData.FieldId; }
  397. }
  398. /// <summary>
  399. /// 获取或设置该Particle对应底层的ParticleID值
  400. /// </summary>
  401. public int ParticleId
  402. {
  403. get { return objParticleData.ParticleId; }
  404. }
  405. public bool IsDeleted { get => m_isDeleted; set => m_isDeleted = value; }
  406. public bool IsMouseOver { get => m_isMouseOver; set => m_isMouseOver = value; }
  407. public Image GetImage()
  408. {
  409. return m_BSEimage;
  410. }
  411. public void SetImage(Image value)
  412. {
  413. m_BSEimage = (Bitmap)value;
  414. }
  415. public DisplayState GetDisplayState()
  416. {
  417. if (m_isDeleted)
  418. {
  419. m_displayState = DisplayState.NODISPLAY;
  420. }
  421. return m_displayState;
  422. }
  423. public void SetDisplayState(DisplayState value)
  424. {
  425. m_displayState = value;
  426. if (m_displayState == DisplayState.DISPLAY)
  427. {
  428. m_paintState = PaintState.PAINT;
  429. }
  430. }
  431. /// <summary>
  432. /// 绘制函数
  433. /// </summary>
  434. /// <param name="e"></param>
  435. public void Paint(Graphics g)
  436. {
  437. //Graphics g = e.Graphics;
  438. //绘制鼠标移动到颗粒上时的边框,需要判断当前鼠标在颗粒上,及颗粒的操作为正常显示
  439. if (m_isMouseOver == true)
  440. {
  441. //如果有鼠标在该矩形上,那么进行描边
  442. ControlPaint.DrawBorder(g,
  443. Rectangle.Round(this.GetShowRect()),
  444. Color.Lime,
  445. 1,
  446. ButtonBorderStyle.Solid,
  447. Color.Lime,
  448. 1,
  449. ButtonBorderStyle.Solid,
  450. Color.Lime,
  451. 1,
  452. ButtonBorderStyle.Solid,
  453. Color.Lime,
  454. 1,
  455. ButtonBorderStyle.Solid);
  456. }
  457. if (GetPaintState() == PaintState.PAINT)
  458. {
  459. if (this.ShowMode == SegmentShowMode.DRAWPARTICLEIMAGE)
  460. {
  461. g.DrawImage(m_BSEimage, m_Globalrect);
  462. }
  463. else
  464. {
  465. g.DrawImage(m_Colorimage, m_Globalrect);
  466. }
  467. }
  468. if (GetPaintState() == PaintState.CONCISEPAINT)
  469. {
  470. if (m_isSelected)
  471. {
  472. g.DrawString("+", new Font("黑体", 12), new SolidBrush(Color.Red), new PointF(GetCenterPoint().X, GetCenterPoint().Y));
  473. }
  474. else
  475. {
  476. g.DrawString("+", new Font("黑体", 6), new SolidBrush(Color.DarkSlateBlue), new PointF(GetCenterPoint().X, GetCenterPoint().Y));
  477. }
  478. }
  479. if (m_isSelected)
  480. {
  481. //如果説该矩形被选择上了的话,那么也显示边框
  482. ControlPaint.DrawBorder(g,
  483. Rectangle.Round(this.GetShowRect()),
  484. Color.Blue,
  485. 1,
  486. ButtonBorderStyle.Solid,
  487. Color.Blue,
  488. 1,
  489. ButtonBorderStyle.Solid,
  490. Color.Blue,
  491. 1,
  492. ButtonBorderStyle.Solid,
  493. Color.Blue,
  494. 1,
  495. ButtonBorderStyle.Solid);
  496. }
  497. if (ParticleShowXray.DISPLAYXRAY == m_operator_showxray && PaintState.NOPAINT != GetPaintState())
  498. {
  499. //当鼠标在该颗粒上进行点击,则对颗粒状态更改为选定状态,用来显示X-ray能谱表
  500. ControlPaint.DrawBorder(g,
  501. Rectangle.Round(this.GetShowRect()),
  502. Color.DeepSkyBlue,
  503. 1,
  504. ButtonBorderStyle.Solid,
  505. Color.DeepSkyBlue,
  506. 1,
  507. ButtonBorderStyle.Solid,
  508. Color.DeepSkyBlue,
  509. 1,
  510. ButtonBorderStyle.Solid,
  511. Color.DeepSkyBlue,
  512. 1,
  513. ButtonBorderStyle.Solid);
  514. }
  515. }
  516. /// <summary>
  517. /// 从已经确定的外边框来计算出里面的+号小框位置
  518. /// </summary>
  519. /// <returns></returns>
  520. private RectangleF GetSmallRectangleFromRect()
  521. {
  522. RectangleF rect = new RectangleF();
  523. //用外边框的坐标,除2获得中心点,然后再分别+,- 4
  524. float x = 0, y = 0;
  525. x = m_Globalrect.X + (m_Globalrect.Width / 2);
  526. y = m_Globalrect.Y + (m_Globalrect.Height / 2);
  527. var smallwidth = m_Globalrect.Width * 1 / 5;
  528. var smallheight = m_Globalrect.Height * 1 / 5;
  529. rect.X = x - smallwidth/2;
  530. rect.Y = y - smallheight / 2;
  531. rect.Width = smallwidth;
  532. rect.Height = smallheight;
  533. return rect;
  534. }
  535. /// <summary>
  536. /// 根据该多边形所有包含的线长度,计算出,该多边形的面积大小
  537. /// </summary>
  538. /// <returns></returns>
  539. public float GetAreaFormSegments()
  540. {
  541. float f_size_sum = 0;
  542. foreach (var ls_ds in this.objParticleData.SegmentList)
  543. {
  544. f_size_sum = f_size_sum + ls_ds.Length;
  545. }
  546. return f_size_sum;
  547. }
  548. }
  549. }