IntersectionMatrix.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. import Location from './Location'
  2. import IllegalArgumentException from '../../../../java/lang/IllegalArgumentException'
  3. import Dimension from './Dimension'
  4. import Cloneable from '../../../../java/lang/Cloneable'
  5. import StringBuilder from '../../../../java/lang/StringBuilder'
  6. export default class IntersectionMatrix {
  7. constructor() {
  8. IntersectionMatrix.constructor_.apply(this, arguments)
  9. }
  10. static constructor_() {
  11. this._matrix = null
  12. if (arguments.length === 0) {
  13. this._matrix = Array(3).fill().map(() => Array(3))
  14. this.setAll(Dimension.FALSE)
  15. } else if (arguments.length === 1) {
  16. if (typeof arguments[0] === 'string') {
  17. const elements = arguments[0]
  18. IntersectionMatrix.constructor_.call(this)
  19. this.set(elements)
  20. } else if (arguments[0] instanceof IntersectionMatrix) {
  21. const other = arguments[0]
  22. IntersectionMatrix.constructor_.call(this)
  23. this._matrix[Location.INTERIOR][Location.INTERIOR] = other._matrix[Location.INTERIOR][Location.INTERIOR]
  24. this._matrix[Location.INTERIOR][Location.BOUNDARY] = other._matrix[Location.INTERIOR][Location.BOUNDARY]
  25. this._matrix[Location.INTERIOR][Location.EXTERIOR] = other._matrix[Location.INTERIOR][Location.EXTERIOR]
  26. this._matrix[Location.BOUNDARY][Location.INTERIOR] = other._matrix[Location.BOUNDARY][Location.INTERIOR]
  27. this._matrix[Location.BOUNDARY][Location.BOUNDARY] = other._matrix[Location.BOUNDARY][Location.BOUNDARY]
  28. this._matrix[Location.BOUNDARY][Location.EXTERIOR] = other._matrix[Location.BOUNDARY][Location.EXTERIOR]
  29. this._matrix[Location.EXTERIOR][Location.INTERIOR] = other._matrix[Location.EXTERIOR][Location.INTERIOR]
  30. this._matrix[Location.EXTERIOR][Location.BOUNDARY] = other._matrix[Location.EXTERIOR][Location.BOUNDARY]
  31. this._matrix[Location.EXTERIOR][Location.EXTERIOR] = other._matrix[Location.EXTERIOR][Location.EXTERIOR]
  32. }
  33. }
  34. }
  35. static matches() {
  36. if (Number.isInteger(arguments[0]) && typeof arguments[1] === 'string') {
  37. const actualDimensionValue = arguments[0], requiredDimensionSymbol = arguments[1]
  38. if (requiredDimensionSymbol === Dimension.SYM_DONTCARE)
  39. return true
  40. if (requiredDimensionSymbol === Dimension.SYM_TRUE && (actualDimensionValue >= 0 || actualDimensionValue === Dimension.TRUE))
  41. return true
  42. if (requiredDimensionSymbol === Dimension.SYM_FALSE && actualDimensionValue === Dimension.FALSE)
  43. return true
  44. if (requiredDimensionSymbol === Dimension.SYM_P && actualDimensionValue === Dimension.P)
  45. return true
  46. if (requiredDimensionSymbol === Dimension.SYM_L && actualDimensionValue === Dimension.L)
  47. return true
  48. if (requiredDimensionSymbol === Dimension.SYM_A && actualDimensionValue === Dimension.A)
  49. return true
  50. return false
  51. } else if (typeof arguments[0] === 'string' && typeof arguments[1] === 'string') {
  52. const actualDimensionSymbols = arguments[0], requiredDimensionSymbols = arguments[1]
  53. const m = new IntersectionMatrix(actualDimensionSymbols)
  54. return m.matches(requiredDimensionSymbols)
  55. }
  56. }
  57. static isTrue(actualDimensionValue) {
  58. if (actualDimensionValue >= 0 || actualDimensionValue === Dimension.TRUE)
  59. return true
  60. return false
  61. }
  62. isIntersects() {
  63. return !this.isDisjoint()
  64. }
  65. isCovers() {
  66. const hasPointInCommon = IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.INTERIOR]) || IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.BOUNDARY]) || IntersectionMatrix.isTrue(this._matrix[Location.BOUNDARY][Location.INTERIOR]) || IntersectionMatrix.isTrue(this._matrix[Location.BOUNDARY][Location.BOUNDARY])
  67. return hasPointInCommon && this._matrix[Location.EXTERIOR][Location.INTERIOR] === Dimension.FALSE && this._matrix[Location.EXTERIOR][Location.BOUNDARY] === Dimension.FALSE
  68. }
  69. isCoveredBy() {
  70. const hasPointInCommon = IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.INTERIOR]) || IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.BOUNDARY]) || IntersectionMatrix.isTrue(this._matrix[Location.BOUNDARY][Location.INTERIOR]) || IntersectionMatrix.isTrue(this._matrix[Location.BOUNDARY][Location.BOUNDARY])
  71. return hasPointInCommon && this._matrix[Location.INTERIOR][Location.EXTERIOR] === Dimension.FALSE && this._matrix[Location.BOUNDARY][Location.EXTERIOR] === Dimension.FALSE
  72. }
  73. set() {
  74. if (arguments.length === 1) {
  75. const dimensionSymbols = arguments[0]
  76. for (let i = 0; i < dimensionSymbols.length; i++) {
  77. const row = Math.trunc(i / 3)
  78. const col = i % 3
  79. this._matrix[row][col] = Dimension.toDimensionValue(dimensionSymbols.charAt(i))
  80. }
  81. } else if (arguments.length === 3) {
  82. const row = arguments[0], column = arguments[1], dimensionValue = arguments[2]
  83. this._matrix[row][column] = dimensionValue
  84. }
  85. }
  86. isContains() {
  87. return IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.INTERIOR]) && this._matrix[Location.EXTERIOR][Location.INTERIOR] === Dimension.FALSE && this._matrix[Location.EXTERIOR][Location.BOUNDARY] === Dimension.FALSE
  88. }
  89. setAtLeast() {
  90. if (arguments.length === 1) {
  91. const minimumDimensionSymbols = arguments[0]
  92. for (let i = 0; i < minimumDimensionSymbols.length; i++) {
  93. const row = Math.trunc(i / 3)
  94. const col = i % 3
  95. this.setAtLeast(row, col, Dimension.toDimensionValue(minimumDimensionSymbols.charAt(i)))
  96. }
  97. } else if (arguments.length === 3) {
  98. const row = arguments[0], column = arguments[1], minimumDimensionValue = arguments[2]
  99. if (this._matrix[row][column] < minimumDimensionValue)
  100. this._matrix[row][column] = minimumDimensionValue
  101. }
  102. }
  103. setAtLeastIfValid(row, column, minimumDimensionValue) {
  104. if (row >= 0 && column >= 0)
  105. this.setAtLeast(row, column, minimumDimensionValue)
  106. }
  107. isWithin() {
  108. return IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.INTERIOR]) && this._matrix[Location.INTERIOR][Location.EXTERIOR] === Dimension.FALSE && this._matrix[Location.BOUNDARY][Location.EXTERIOR] === Dimension.FALSE
  109. }
  110. isTouches(dimensionOfGeometryA, dimensionOfGeometryB) {
  111. if (dimensionOfGeometryA > dimensionOfGeometryB)
  112. return this.isTouches(dimensionOfGeometryB, dimensionOfGeometryA)
  113. if (dimensionOfGeometryA === Dimension.A && dimensionOfGeometryB === Dimension.A || dimensionOfGeometryA === Dimension.L && dimensionOfGeometryB === Dimension.L || dimensionOfGeometryA === Dimension.L && dimensionOfGeometryB === Dimension.A || dimensionOfGeometryA === Dimension.P && dimensionOfGeometryB === Dimension.A || dimensionOfGeometryA === Dimension.P && dimensionOfGeometryB === Dimension.L)
  114. return this._matrix[Location.INTERIOR][Location.INTERIOR] === Dimension.FALSE && (IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.BOUNDARY]) || IntersectionMatrix.isTrue(this._matrix[Location.BOUNDARY][Location.INTERIOR]) || IntersectionMatrix.isTrue(this._matrix[Location.BOUNDARY][Location.BOUNDARY]))
  115. return false
  116. }
  117. isOverlaps(dimensionOfGeometryA, dimensionOfGeometryB) {
  118. if (dimensionOfGeometryA === Dimension.P && dimensionOfGeometryB === Dimension.P || dimensionOfGeometryA === Dimension.A && dimensionOfGeometryB === Dimension.A)
  119. return IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.INTERIOR]) && IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.EXTERIOR]) && IntersectionMatrix.isTrue(this._matrix[Location.EXTERIOR][Location.INTERIOR])
  120. if (dimensionOfGeometryA === Dimension.L && dimensionOfGeometryB === Dimension.L)
  121. return this._matrix[Location.INTERIOR][Location.INTERIOR] === 1 && IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.EXTERIOR]) && IntersectionMatrix.isTrue(this._matrix[Location.EXTERIOR][Location.INTERIOR])
  122. return false
  123. }
  124. isEquals(dimensionOfGeometryA, dimensionOfGeometryB) {
  125. if (dimensionOfGeometryA !== dimensionOfGeometryB)
  126. return false
  127. return IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.INTERIOR]) && this._matrix[Location.INTERIOR][Location.EXTERIOR] === Dimension.FALSE && this._matrix[Location.BOUNDARY][Location.EXTERIOR] === Dimension.FALSE && this._matrix[Location.EXTERIOR][Location.INTERIOR] === Dimension.FALSE && this._matrix[Location.EXTERIOR][Location.BOUNDARY] === Dimension.FALSE
  128. }
  129. toString() {
  130. const builder = new StringBuilder('123456789')
  131. for (let ai = 0; ai < 3; ai++)
  132. for (let bi = 0; bi < 3; bi++)
  133. builder.setCharAt(3 * ai + bi, Dimension.toDimensionSymbol(this._matrix[ai][bi]))
  134. return builder.toString()
  135. }
  136. setAll(dimensionValue) {
  137. for (let ai = 0; ai < 3; ai++)
  138. for (let bi = 0; bi < 3; bi++)
  139. this._matrix[ai][bi] = dimensionValue
  140. }
  141. get(row, column) {
  142. return this._matrix[row][column]
  143. }
  144. transpose() {
  145. let temp = this._matrix[1][0]
  146. this._matrix[1][0] = this._matrix[0][1]
  147. this._matrix[0][1] = temp
  148. temp = this._matrix[2][0]
  149. this._matrix[2][0] = this._matrix[0][2]
  150. this._matrix[0][2] = temp
  151. temp = this._matrix[2][1]
  152. this._matrix[2][1] = this._matrix[1][2]
  153. this._matrix[1][2] = temp
  154. return this
  155. }
  156. matches(requiredDimensionSymbols) {
  157. if (requiredDimensionSymbols.length !== 9)
  158. throw new IllegalArgumentException('Should be length 9: ' + requiredDimensionSymbols)
  159. for (let ai = 0; ai < 3; ai++)
  160. for (let bi = 0; bi < 3; bi++)
  161. if (!IntersectionMatrix.matches(this._matrix[ai][bi], requiredDimensionSymbols.charAt(3 * ai + bi)))
  162. return false
  163. return true
  164. }
  165. add(im) {
  166. for (let i = 0; i < 3; i++)
  167. for (let j = 0; j < 3; j++)
  168. this.setAtLeast(i, j, im.get(i, j))
  169. }
  170. isDisjoint() {
  171. return this._matrix[Location.INTERIOR][Location.INTERIOR] === Dimension.FALSE && this._matrix[Location.INTERIOR][Location.BOUNDARY] === Dimension.FALSE && this._matrix[Location.BOUNDARY][Location.INTERIOR] === Dimension.FALSE && this._matrix[Location.BOUNDARY][Location.BOUNDARY] === Dimension.FALSE
  172. }
  173. isCrosses(dimensionOfGeometryA, dimensionOfGeometryB) {
  174. if (dimensionOfGeometryA === Dimension.P && dimensionOfGeometryB === Dimension.L || dimensionOfGeometryA === Dimension.P && dimensionOfGeometryB === Dimension.A || dimensionOfGeometryA === Dimension.L && dimensionOfGeometryB === Dimension.A)
  175. return IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.INTERIOR]) && IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.EXTERIOR])
  176. if (dimensionOfGeometryA === Dimension.L && dimensionOfGeometryB === Dimension.P || dimensionOfGeometryA === Dimension.A && dimensionOfGeometryB === Dimension.P || dimensionOfGeometryA === Dimension.A && dimensionOfGeometryB === Dimension.L)
  177. return IntersectionMatrix.isTrue(this._matrix[Location.INTERIOR][Location.INTERIOR]) && IntersectionMatrix.isTrue(this._matrix[Location.EXTERIOR][Location.INTERIOR])
  178. if (dimensionOfGeometryA === Dimension.L && dimensionOfGeometryB === Dimension.L)
  179. return this._matrix[Location.INTERIOR][Location.INTERIOR] === 0
  180. return false
  181. }
  182. get interfaces_() {
  183. return [Cloneable]
  184. }
  185. }