RandomPointsInGridBuilder.js 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. import GeometryFactory from '../../geom/GeometryFactory'
  2. import Coordinate from '../../geom/Coordinate'
  3. import MathUtil from '../../math/MathUtil'
  4. import GeometricShapeBuilder from '../GeometricShapeBuilder'
  5. export default class RandomPointsInGridBuilder extends GeometricShapeBuilder {
  6. constructor() {
  7. super()
  8. RandomPointsInGridBuilder.constructor_.apply(this, arguments)
  9. }
  10. static constructor_() {
  11. this._isConstrainedToCircle = false
  12. this._gutterFraction = 0
  13. if (arguments.length === 0) {
  14. GeometricShapeBuilder.constructor_.call(this, new GeometryFactory())
  15. } else if (arguments.length === 1) {
  16. const geomFact = arguments[0]
  17. GeometricShapeBuilder.constructor_.call(this, geomFact)
  18. }
  19. }
  20. static randomPointInCircle(orgX, orgY, width, height) {
  21. const centreX = orgX + width / 2
  22. const centreY = orgY + height / 2
  23. const rndAng = 2 * Math.PI * Math.random()
  24. const rndRadius = Math.random()
  25. const rndRadius2 = Math.sqrt(rndRadius)
  26. const rndX = width / 2 * rndRadius2 * Math.cos(rndAng)
  27. const rndY = height / 2 * rndRadius2 * Math.sin(rndAng)
  28. const x0 = centreX + rndX
  29. const y0 = centreY + rndY
  30. return new Coordinate(x0, y0)
  31. }
  32. randomPointInCell(orgX, orgY, xLen, yLen) {
  33. if (this._isConstrainedToCircle)
  34. return RandomPointsInGridBuilder.randomPointInCircle(orgX, orgY, xLen, yLen)
  35. return this.randomPointInGridCell(orgX, orgY, xLen, yLen)
  36. }
  37. getGeometry() {
  38. let nCells = Math.trunc(Math.sqrt(this._numPts))
  39. if (nCells * nCells < this._numPts) nCells += 1
  40. const gridDX = this.getExtent().getWidth() / nCells
  41. const gridDY = this.getExtent().getHeight() / nCells
  42. const gutterFrac = MathUtil.clamp(this._gutterFraction, 0.0, 1.0)
  43. const gutterOffsetX = gridDX * gutterFrac / 2
  44. const gutterOffsetY = gridDY * gutterFrac / 2
  45. const cellFrac = 1.0 - gutterFrac
  46. const cellDX = cellFrac * gridDX
  47. const cellDY = cellFrac * gridDY
  48. const pts = new Array(nCells * nCells).fill(null)
  49. let index = 0
  50. for (let i = 0; i < nCells; i++)
  51. for (let j = 0; j < nCells; j++) {
  52. const orgX = this.getExtent().getMinX() + i * gridDX + gutterOffsetX
  53. const orgY = this.getExtent().getMinY() + j * gridDY + gutterOffsetY
  54. pts[index++] = this.randomPointInCell(orgX, orgY, cellDX, cellDY)
  55. }
  56. return this._geomFactory.createMultiPointFromCoords(pts)
  57. }
  58. setConstrainedToCircle(isConstrainedToCircle) {
  59. this._isConstrainedToCircle = isConstrainedToCircle
  60. }
  61. setGutterFraction(gutterFraction) {
  62. this._gutterFraction = gutterFraction
  63. }
  64. randomPointInGridCell(orgX, orgY, xLen, yLen) {
  65. const x = orgX + xLen * Math.random()
  66. const y = orgY + yLen * Math.random()
  67. return this.createCoord(x, y)
  68. }
  69. }