SRect.ts 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. /*
  2. * *********************************************************************************************************************
  3. *
  4. * !!
  5. * .F88X
  6. * X8888Y
  7. * .}888888N;
  8. * i888888N; .:! .I$WI:
  9. * R888888I .'N88~ i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
  10. * .R888888I .;N8888~ .X8' "8I.!,/8" !%NY8`"8I8~~8>,88I
  11. * +888888N; .8888888Y "&&8Y.}8,
  12. * ./888888N; .R888888Y .'}~ .>}'.`+> i}! "i' +/' .'i~ !11,.:">, .~]! .i}i
  13. * ~888888%: .I888888l .]88~`1/iY88Ii+1'.R$8$8]"888888888> Y8$ W8E X8E W8888'188Il}Y88$*
  14. * 18888888 E8888881 .]W%8$`R8X'&8%++N8i,8N%N8+l8%` .}8N:.R$RE%N88N%N$K$R 188,FE$8%~Y88I
  15. * .E888888I .i8888888' .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
  16. * 8888888I .,N888888~ ~88i"8W,!N8*.I88.}888%F,i$88"F88" 888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
  17. * i888888N' I888Y ]88;/EX*IFKFK88X K8R .l8W 88Y ~88}'88E&%8W.X8N``]88!.$8K .:W8I
  18. * .i888888N; I8Y .&8$ .X88! i881.:%888>I88 ;88] +88+.';;;;:.Y88X 18N.,88l .+88/
  19. * .:R888888I
  20. * .&888888I Copyright (c) 2009-2020. 博锐尚格科技股份有限公司
  21. * ~8888'
  22. * .!88~ All rights reserved.
  23. *
  24. * *********************************************************************************************************************
  25. */
  26. import { SPoint } from "./SPoint";
  27. import { SSize } from "./SSize";
  28. /**
  29. * 矩形数据类型定义
  30. *
  31. * @author 庞利祥 <sybotan@126.com>
  32. */
  33. export class SRect {
  34. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. // 属性定义
  36. /** 左上角坐标 */
  37. leftTop: SPoint;
  38. /** 大小 */
  39. size: SSize;
  40. /** 矩形的 X 轴坐标 */
  41. get x(): number {
  42. return this.leftTop.x;
  43. }
  44. set x(value: number) {
  45. this.leftTop.x = value;
  46. }
  47. /** 矩形的 Y 轴坐标 */
  48. get y(): number {
  49. return this.leftTop.y;
  50. }
  51. set y(value: number) {
  52. this.leftTop.y = value;
  53. }
  54. /** 矩形的宽 */
  55. get width(): number {
  56. return this.size.width;
  57. }
  58. set width(v: number) {
  59. this.size.width = v;
  60. }
  61. /** 矩形的高 */
  62. get height(): number {
  63. return this.size.height;
  64. }
  65. set height(v: number) {
  66. this.size.height = v;
  67. }
  68. /** 矩形的左 */
  69. get left(): number {
  70. return this.leftTop.x;
  71. }
  72. set left(v: number) {
  73. this.leftTop.x = v;
  74. }
  75. /** 矩形的上 */
  76. get top(): number {
  77. return this.y;
  78. }
  79. set top(v: number) {
  80. this.y = v;
  81. }
  82. /** 矩形的右 */
  83. get right(): number {
  84. return this.x + this.width;
  85. }
  86. set right(right: number) {
  87. this.width = right - this.x;
  88. }
  89. /** 矩形的下 */
  90. get bottom(): number {
  91. return this.y + this.height;
  92. }
  93. set bottom(value: number) {
  94. this.height = value - this.y;
  95. }
  96. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  97. // 构造函数
  98. /**
  99. * 构造函数
  100. */
  101. constructor();
  102. /**
  103. *构造函数
  104. *
  105. * @param leftTop 左上角坐标
  106. * @param rightBottom 右下角坐标
  107. */
  108. constructor(leftTop: SPoint, rightBottom: SPoint);
  109. /**
  110. * 构造函数
  111. *
  112. * @param leftTop 左上角坐标
  113. * @param size 大小
  114. */
  115. constructor(leftTop: SPoint, size: SSize);
  116. /**
  117. * 构造函数
  118. *
  119. * @param x X 轴坐标
  120. * @param y Y 轴坐标
  121. * @param width 宽度
  122. * @param height 高度
  123. */
  124. constructor(x: number, y: number, width: number, height: number);
  125. /**
  126. * 构造函数
  127. *
  128. * @param x X 轴坐标 | 左上角坐标
  129. * @param y Y 轴坐标 | 右下角坐标 | 大小
  130. * @param width 宽度
  131. * @param height 高度
  132. */
  133. constructor(
  134. x?: number | SPoint,
  135. y?: number | SPoint | SSize,
  136. width?: number,
  137. height?: number
  138. ) {
  139. if (x == undefined) {
  140. this.leftTop = new SPoint(0, 0);
  141. this.size = new SSize(0, 0);
  142. } else if (x instanceof SPoint && y instanceof SPoint) {
  143. // constructor(leftTop: SPoint, rightBottom: SPoint)
  144. this.leftTop = new SPoint(x.x, x.y);
  145. this.size = new SSize(y.x - x.x, y.y - x.y);
  146. } else if (x instanceof SPoint && y instanceof SSize) {
  147. // constructor(leftTop: SPoint, size: SSize)
  148. this.leftTop = new SPoint(x.x, x.y);
  149. this.size = new SSize(y.width, y.height);
  150. } else {
  151. // constructor(x: number, y: number, width: number, height: number)
  152. this.leftTop = new SPoint(x as number, y as number);
  153. this.size = new SSize(width as number, height as number);
  154. }
  155. }
  156. /**
  157. * 是否为空
  158. *
  159. * @return width 或 height 小于等于 0,返回 true,否则返回 false。
  160. *
  161. * @see isNull(), isValid()
  162. */
  163. isEmpty(): boolean {
  164. return this.size.isEmpty();
  165. }
  166. /**
  167. * 是否为 Null
  168. *
  169. * @return width 与 height 都等于 0,返回 true,否则返回 false。
  170. *
  171. * @see isEmpty(), isValid()
  172. */
  173. isNull(): boolean {
  174. return this.size.isNull();
  175. }
  176. /**
  177. * 是否有效
  178. *
  179. * @return width 与 height 都大于 0,返回 true,否则返回 false。
  180. *
  181. * @see isEmpty(), isNull()
  182. */
  183. isValid(): boolean {
  184. return this.size.isValid();
  185. }
  186. /**
  187. * 是否包含另一个矩阵
  188. *
  189. * @return true 包含
  190. */
  191. isIn(rect: SRect): boolean {
  192. return (
  193. this.left <= rect.left &&
  194. this.right >= rect.right &&
  195. this.bottom >= rect.bottom &&
  196. this.top <= rect.top
  197. );
  198. }
  199. /**
  200. * 判断矩形空间是否包含点x,y
  201. *
  202. * @param x X 坐标
  203. * @param y Y 坐标
  204. * @return 如果包含返回 true, 否则返回 false
  205. */
  206. contains(x: number, y: number): boolean {
  207. return (
  208. x >= this.left &&
  209. x <= this.right &&
  210. y >= this.top &&
  211. y <= this.bottom
  212. );
  213. }
  214. /**
  215. * 计算中心点
  216. *
  217. * @return 中心点坐标
  218. */
  219. center(): SPoint {
  220. return new SPoint(
  221. this.x + this.width / 2.0,
  222. this.y + this.height / 2.0
  223. );
  224. }
  225. /**
  226. * 平移矩形
  227. *
  228. * @param dx X 轴位移
  229. * @param dy Y 轴位移
  230. */
  231. translate(dx: number, dy: number): void {
  232. this.x += dx;
  233. this.y += dy;
  234. }
  235. /**
  236. * 生成平移矩形
  237. *
  238. * @param dx X 轴位移
  239. * @param dy Y 轴位移
  240. * @return 移动后的矩形
  241. */
  242. translated(dx: number, dy: number): SRect {
  243. return new SRect(this.x + dx, this.y + dy, this.width, this.height);
  244. }
  245. /**
  246. * 调整Rect位置
  247. *
  248. * @param dx X 轴位移
  249. * @param dy Y 轴位移
  250. * @param dw 宽度调整
  251. * @param dh 高度调整
  252. */
  253. adjust(dx: number, dy: number, dw: number, dh: number): void {
  254. this.x += dx;
  255. this.y += dy;
  256. this.width += dw;
  257. this.height += dh;
  258. }
  259. /**
  260. * 调整 Rect 位置
  261. *
  262. * @param dx X 轴位移
  263. * @param dy Y 轴位移
  264. * @param dw 宽度调整
  265. * @param dh 高度调整
  266. * @return 调整后的矩形
  267. */
  268. adjusted(dx: number, dy: number, dw: number, dh: number): SRect {
  269. return new SRect(
  270. this.x + dx,
  271. this.y + dy,
  272. this.width + dw,
  273. this.height + dh
  274. );
  275. }
  276. /**
  277. * 合并矩形
  278. *
  279. * @param rect 合并的矩形
  280. */
  281. union(rect: SRect): void {
  282. let r = this.unioned(rect);
  283. this.x = r.x;
  284. this.y = r.y;
  285. this.width = r.width;
  286. this.height = r.height;
  287. }
  288. /**
  289. * 生成合并矩形
  290. *
  291. * @param rect 合并的矩形
  292. * @return 返回合并后的矩形
  293. */
  294. unioned(rect: SRect): SRect {
  295. let left = Math.min(this.left, rect.left);
  296. let top = Math.min(this.top, rect.top);
  297. let right = Math.max(this.right, rect.right);
  298. let bottom = Math.max(this.bottom, rect.bottom);
  299. return new SRect(left, top, right - left, bottom - top);
  300. }
  301. /**
  302. * 生成相交矩形
  303. *
  304. * @param rect 合并的矩形
  305. * @return 返回合并后的矩形
  306. */
  307. intersected(rect: SRect): SRect {
  308. let minX = this.left < rect.left ? this.left : rect.left;
  309. let minY = this.top < rect.top ? this.top : rect.top;
  310. let maxX = this.right > rect.right ? this.right : rect.right;
  311. let maxY = this.bottom > rect.bottom ? this.bottom : rect.bottom;
  312. if (
  313. this.width + rect.width > maxX - minX &&
  314. this.height + rect.height > maxY - minY
  315. ) {
  316. return new SRect();
  317. }
  318. return new SRect();
  319. }
  320. /**
  321. * 相交矩形
  322. *
  323. * @param rect 合并的矩形
  324. */
  325. intersect(rect: SRect): SRect {
  326. let left = Math.min(this.left, rect.left);
  327. let top = Math.min(this.top, rect.top);
  328. let right = Math.max(this.right, rect.right);
  329. let bottom = Math.max(this.bottom, rect.bottom);
  330. return new SRect(left, top, right - left, bottom - top);
  331. }
  332. }