SDoorItem.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import {SColor, SPainter, SPoint, SRect} from "@persagy-web/draw/lib";
  2. import { SGraphItem } from "@persagy-web/graph/lib";
  3. import { Door } from "@persagy-web/big/lib/types/floor/Door";
  4. import { ItemColor, ItemOrder } from "@persagy-web/big/lib";
  5. import { SMathUtil } from "@persagy-web/big/lib/utils/SMathUtil";
  6. /**
  7. * 门item
  8. *
  9. * @author 郝建龙
  10. */
  11. export class SDoorItem extends SGraphItem {
  12. /** 门数据 */
  13. data: Door;
  14. /** 门轮廓线坐标list */
  15. private readonly pointArr: SPoint[] = [];
  16. /** 门长度 */
  17. private readonly r: number = 0;
  18. /** 角度 */
  19. private readonly ang: number = 0;
  20. /** 旋转点 */
  21. private readonly p: SPoint = new SPoint(0, 0);
  22. /** 旋转起始角度,结束角度+Math.PI/2 */
  23. private readonly startAng: number = -Math.PI / 2;
  24. /** X坐标最小值 */
  25. private minX = Number.MAX_SAFE_INTEGER;
  26. /** X坐标最大值 */
  27. private maxX = Number.MIN_SAFE_INTEGER;
  28. /** Y坐标最小值 */
  29. private minY = Number.MAX_SAFE_INTEGER;
  30. /** Y坐标最大值 */
  31. private maxY = Number.MIN_SAFE_INTEGER;
  32. /**
  33. * 构造函数
  34. *
  35. * @param parent 指向父对象
  36. * @param data 门数据
  37. */
  38. constructor(parent: SGraphItem | null, data: Door) {
  39. super(parent);
  40. this.data = data;
  41. this.zOrder = ItemOrder.doorOrder;
  42. if (this.data.OutLine.length) {
  43. this.pointArr = this.data.OutLine[0].map(
  44. (t): SPoint => {
  45. let x = t.X,
  46. y = -t.Y;
  47. if (x < this.minX) {
  48. this.minX = x;
  49. }
  50. if (y < this.minY) {
  51. this.minY = y;
  52. }
  53. if (x > this.maxX) {
  54. this.maxX = x;
  55. }
  56. if (y > this.maxY) {
  57. this.maxY = y;
  58. }
  59. return new SPoint(t.X, -t.Y);
  60. }
  61. );
  62. let p1 = this.pointArr[0],
  63. p2 = this.pointArr[1];
  64. // 旋转点
  65. this.p = p1;
  66. const HX = (this.data.HandDirection.X = Number(
  67. this.data.HandDirection.X.toFixed()
  68. ));
  69. const HY = (this.data.HandDirection.Y = Number(
  70. this.data.HandDirection.Y.toFixed()
  71. ));
  72. const FX = (this.data.FaceDirection.X = Number(
  73. this.data.FaceDirection.X.toFixed()
  74. ));
  75. const FY = (this.data.FaceDirection.Y = Number(
  76. this.data.FaceDirection.Y.toFixed()
  77. ));
  78. // 向量点乘 => x1 * x2 + y1 * y2,大于0同向
  79. let dotProduct = (p2.x - p1.x) * HX + (p2.y - p1.y) * -HY;
  80. if (dotProduct > 0) {
  81. this.p = p2;
  82. p2 = p1;
  83. p1 = this.p;
  84. }
  85. // 两点间距离
  86. this.r = SMathUtil.pointDistance(p1.x, p1.y, p2.x, p2.y);
  87. // 门朝向角度
  88. let fo = Math.atan(-FY / FX);
  89. this.ang = FX > 0 ? fo : fo + Math.PI;
  90. // 向量叉乘 => x1 * y2 - x2 * y1,小于0是顺时针
  91. let direction = (p2.x - p1.x) * -FY - (p2.y - p1.y) * FX;
  92. if (direction > 0) {
  93. this.startAng = 0;
  94. }
  95. }
  96. } // Constructor
  97. /**
  98. * Item对象边界区域
  99. *
  100. * @return SRect
  101. */
  102. boundingRect(): SRect {
  103. return new SRect(
  104. 0,
  105. 0,
  106. this.r,
  107. this.r
  108. );
  109. } // Function boundingRect()
  110. /**
  111. * Item绘制操作
  112. *
  113. * @param painter painter对象
  114. */
  115. onDraw(painter: SPainter): void {
  116. painter.translate(this.p.x, this.p.y);
  117. painter.rotate(this.ang);
  118. painter.pen.lineWidth = painter.toPx(1);
  119. painter.pen.color = ItemColor.doorColor;
  120. painter.drawLine(0, 0, this.r, 0);
  121. painter.pen.lineDash = [50, 100];
  122. painter.pen.lineWidth = painter.toPx(1);
  123. // painter.drawArc(
  124. // -this.r,
  125. // -this.r,
  126. // this.r * 2,
  127. // this.r * 2,
  128. // this.startAng,
  129. // this.startAng + Math.PI / 2
  130. // );
  131. } // Function onDraw()
  132. } // Class SDoorItem