utils.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. export function getDistance2D(point1, point2) {
  2. return Math.sqrt(
  3. Math.pow(Number(point1.x) - Number(point2.x), 2) +
  4. Math.pow(Number(point1.y) - Number(point2.y), 2)
  5. )
  6. }
  7. // 斜率slope:指的是点位阵列排列的每行斜率。计算方法:取考察点“上下左右”(注意与x轴、y轴方向无必然关系)的邻居,即与它最近的四个邻居,分别计算邻居与它的连线的斜率,限定斜率范围是[0, +Infinity),不符合则计算其负倒数。
  8. export function computePointDistanceAndRowSlope(rawWholeData) {
  9. // return 0.36
  10. const sampleNumber = Math.min(1000, rawWholeData.length)
  11. let pointDistance = null
  12. let rowSlope = null
  13. while((pointDistance === null) || (rowSlope === null)) {
  14. const distanceList = []
  15. const rowSlopeList = []
  16. for (let index = 0; index < sampleNumber; index++) {
  17. const sampleIdx = Math.floor(Math.random() * rawWholeData.length)
  18. const sample = rawWholeData[sampleIdx]
  19. for (const neighbourId of sample.ids.slice(0, 4)) {
  20. if (neighbourId !== "-1") {
  21. distanceList.push(getDistance2D(sample, rawWholeData[neighbourId - 1]))
  22. let rowSlopeTemp = null
  23. if (Math.abs(Number(sample.x) - Number(rawWholeData[neighbourId - 1].x)) <= Number.EPSILON) {
  24. rowSlopeTemp = 0
  25. } else if ((Number(sample.x) - Number(rawWholeData[neighbourId - 1].x)) < 0) {
  26. rowSlopeTemp = -1 / (Number(sample.x) - Number(rawWholeData[neighbourId - 1].x))
  27. } else {
  28. rowSlopeTemp = (Number(sample.y) - Number(rawWholeData[neighbourId - 1].y)) / (Number(sample.x) - Number(rawWholeData[neighbourId - 1].x))
  29. }
  30. rowSlopeList.push(rowSlopeTemp)
  31. }
  32. }
  33. }
  34. if (distanceList.length) {
  35. let sum = 0
  36. for (const distItem of distanceList) {
  37. sum += distItem
  38. }
  39. pointDistance = sum / distanceList.length
  40. }
  41. if (rowSlopeList.length) {
  42. let sum = 0
  43. for (const rowSlopeItem of rowSlopeList) {
  44. sum += rowSlopeItem
  45. }
  46. rowSlope = sum / rowSlopeList.length
  47. }
  48. }
  49. console.log('pointDistance: ', pointDistance, 'rowSlope: ', rowSlope)
  50. return [pointDistance, rowSlope]
  51. }
  52. export function getNeighbourLocations(centerPointPos, pointDistance, rowSlope) {
  53. // 返回的位置列表中位置顺序:
  54. // posRight
  55. // posBottom
  56. // posLeft
  57. // posTop
  58. // posTopRight
  59. // posBottomRight
  60. // posBottomLeft
  61. // posTopLeft
  62. // 注意,方位的确定与x轴、y轴无直接关联,而是由点位阵列中的行列(或者说行的斜率)决定的。
  63. const alpha = Math.atan(rowSlope)
  64. const posRight = {
  65. x: centerPointPos.x + pointDistance * Math.cos(alpha),
  66. y: centerPointPos.y + pointDistance * Math.sin(alpha),
  67. }
  68. const posBottom = {
  69. x: centerPointPos.x + pointDistance * Math.cos(Math.PI / 2 - alpha),
  70. y: centerPointPos.y - pointDistance * Math.sin(Math.PI / 2 - alpha),
  71. }
  72. const posLeft = {
  73. x: centerPointPos.x - pointDistance * Math.cos(alpha),
  74. y: centerPointPos.y - pointDistance * Math.sin(alpha),
  75. }
  76. const posTop = {
  77. x: centerPointPos.x - pointDistance * Math.cos(Math.PI / 2 - alpha),
  78. y: centerPointPos.y + pointDistance * Math.sin(Math.PI / 2 - alpha),
  79. }
  80. // 相当于right的top
  81. const posTopRight = {
  82. x: posRight.x - pointDistance * Math.cos(Math.PI / 2 - alpha),
  83. y: posRight.y + pointDistance * Math.sin(Math.PI / 2 - alpha),
  84. }
  85. // 相当于right的bottom
  86. const posBottomRight = {
  87. x: posRight.x + pointDistance * Math.cos(Math.PI / 2 - alpha),
  88. y: posRight.y - pointDistance * Math.sin(Math.PI / 2 - alpha),
  89. }
  90. // 相当于left的bottom
  91. const posBottomLeft = {
  92. x: posLeft.x + pointDistance * Math.cos(Math.PI / 2 - alpha),
  93. y: posLeft.y - pointDistance * Math.sin(Math.PI / 2 - alpha),
  94. }
  95. // 相当于left的top
  96. const posTopLeft = {
  97. x: posLeft.x + pointDistance * Math.cos(alpha),
  98. y: posLeft.y + pointDistance * Math.sin(alpha),
  99. }
  100. return {
  101. posRight,
  102. posBottom,
  103. posLeft,
  104. posTop,
  105. posTopRight,
  106. posBottomRight,
  107. posBottomLeft,
  108. posTopLeft,
  109. }
  110. }