@visactor/vutils 1.0.24 → 1.0.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.zh-CN.md +12 -0
- package/REGRESSION.md +36 -0
- package/cjs/angle.d.ts +61 -0
- package/cjs/angle.js +73 -7
- package/cjs/angle.js.map +1 -1
- package/cjs/color/Color.d.ts +3 -0
- package/cjs/color/Color.js +64 -10
- package/cjs/color/Color.js.map +1 -1
- package/cjs/color/hexToRgb.d.ts +5 -0
- package/cjs/color/hexToRgb.js +5 -0
- package/cjs/color/hexToRgb.js.map +1 -1
- package/cjs/color/rgbToHsl.js +5 -1
- package/cjs/color/rgbToHsl.js.map +1 -1
- package/cjs/common/array.d.ts +43 -0
- package/cjs/common/array.js +44 -0
- package/cjs/common/array.js.map +1 -1
- package/cjs/common/bisect.d.ts +21 -0
- package/cjs/common/bisect.js +29 -0
- package/cjs/common/bisect.js.map +1 -1
- package/cjs/common/bootstrap.d.ts +5 -0
- package/cjs/common/bootstrap.js +22 -0
- package/cjs/common/bootstrap.js.map +1 -0
- package/cjs/common/clone.js +6 -0
- package/cjs/common/clone.js.map +1 -1
- package/cjs/common/cloneDeep.js +4 -1
- package/cjs/common/cloneDeep.js.map +1 -1
- package/cjs/common/correlation.d.ts +3 -0
- package/cjs/common/correlation.js +83 -0
- package/cjs/common/correlation.js.map +1 -0
- package/cjs/common/debounce.js +22 -4
- package/cjs/common/debounce.js.map +1 -1
- package/cjs/common/deviation.js +1 -2
- package/cjs/common/ecdf.d.ts +8 -0
- package/cjs/common/ecdf.js +11 -2
- package/cjs/common/ecdf.js.map +1 -1
- package/cjs/common/extent.d.ts +4 -0
- package/cjs/common/extent.js +4 -2
- package/cjs/common/extent.js.map +1 -1
- package/cjs/common/field.d.ts +6 -0
- package/cjs/common/field.js +3 -0
- package/cjs/common/field.js.map +1 -1
- package/cjs/common/has.d.ts +17 -0
- package/cjs/common/has.js +18 -1
- package/cjs/common/has.js.map +1 -1
- package/cjs/common/index.d.ts +5 -0
- package/cjs/common/index.js +34 -6
- package/cjs/common/index.js.map +1 -1
- package/cjs/common/interpolate.js +16 -3
- package/cjs/common/interpolate.js.map +1 -1
- package/cjs/common/isBase64.d.ts +6 -0
- package/cjs/common/isBase64.js +6 -0
- package/cjs/common/isBase64.js.map +1 -1
- package/cjs/common/isBoolean.d.ts +13 -0
- package/cjs/common/isBoolean.js +13 -1
- package/cjs/common/isBoolean.js.map +1 -1
- package/cjs/common/isEmpty.js +11 -1
- package/cjs/common/isEmpty.js.map +1 -1
- package/cjs/common/isEqual.js +19 -7
- package/cjs/common/isEqual.js.map +1 -1
- package/cjs/common/isFunction.d.ts +25 -0
- package/cjs/common/isFunction.js +27 -2
- package/cjs/common/isFunction.js.map +1 -1
- package/cjs/common/isNull.js +2 -1
- package/cjs/common/isNumber.d.ts +23 -0
- package/cjs/common/isNumber.js +23 -1
- package/cjs/common/isNumber.js.map +1 -1
- package/cjs/common/isNumeric.d.ts +25 -0
- package/cjs/common/isNumeric.js +25 -0
- package/cjs/common/isNumeric.js.map +1 -1
- package/cjs/common/isObject.d.ts +21 -0
- package/cjs/common/isObject.js +22 -0
- package/cjs/common/isObject.js.map +1 -1
- package/cjs/common/isObjectLike.d.ts +20 -0
- package/cjs/common/isObjectLike.js +21 -0
- package/cjs/common/isObjectLike.js.map +1 -1
- package/cjs/common/isPlainObject.d.ts +25 -0
- package/cjs/common/isPlainObject.js.map +1 -1
- package/cjs/common/isPrototype.js +1 -1
- package/cjs/common/isRegExp.js +1 -1
- package/cjs/common/isShallowEqual.js +1 -0
- package/cjs/common/isShallowEqual.js.map +1 -1
- package/cjs/common/isString.d.ts +13 -0
- package/cjs/common/isString.js +13 -1
- package/cjs/common/isString.js.map +1 -1
- package/cjs/common/isType.d.ts +6 -0
- package/cjs/common/isType.js +6 -0
- package/cjs/common/isType.js.map +1 -1
- package/cjs/common/isValidNumber.js.map +1 -1
- package/cjs/common/isValidUrl.js.map +1 -1
- package/cjs/common/kde.d.ts +28 -0
- package/cjs/common/kde.js +29 -5
- package/cjs/common/kde.js.map +1 -1
- package/cjs/common/mean.d.ts +2 -0
- package/cjs/common/mean.js +25 -0
- package/cjs/common/mean.js.map +1 -0
- package/cjs/common/merge.js +20 -4
- package/cjs/common/merge.js.map +1 -1
- package/cjs/common/mixin.js +14 -3
- package/cjs/common/mixin.js.map +1 -1
- package/cjs/common/normalQuantile.d.ts +5 -0
- package/cjs/common/normalQuantile.js +21 -0
- package/cjs/common/normalQuantile.js.map +1 -0
- package/cjs/common/number.d.ts +24 -0
- package/cjs/common/number.js +24 -1
- package/cjs/common/number.js.map +1 -1
- package/cjs/common/pad.d.ts +21 -0
- package/cjs/common/pad.js +21 -1
- package/cjs/common/pad.js.map +1 -1
- package/cjs/common/random.d.ts +3 -0
- package/cjs/common/random.js +13 -0
- package/cjs/common/random.js.map +1 -1
- package/cjs/common/regression-bootstrap.d.ts +14 -0
- package/cjs/common/regression-bootstrap.js +37 -0
- package/cjs/common/regression-bootstrap.js.map +1 -0
- package/cjs/common/regression-linear.d.ts +5 -0
- package/cjs/common/regression-linear.js +28 -39
- package/cjs/common/regression-linear.js.map +1 -1
- package/cjs/common/regression-logistic.d.ts +6 -0
- package/cjs/common/regression-logistic.js +25 -14
- package/cjs/common/regression-logistic.js.map +1 -1
- package/cjs/common/regression-lowess.d.ts +11 -1
- package/cjs/common/regression-lowess.js +125 -118
- package/cjs/common/regression-lowess.js.map +1 -1
- package/cjs/common/regression-polynomial.d.ts +1 -0
- package/cjs/common/regression-polynomial.js +24 -94
- package/cjs/common/regression-polynomial.js.map +1 -1
- package/cjs/common/regression-solver.d.ts +26 -0
- package/cjs/common/regression-solver.js +180 -0
- package/cjs/common/regression-solver.js.map +1 -0
- package/cjs/common/regression-utils.d.ts +13 -1
- package/cjs/common/regression-utils.js +27 -12
- package/cjs/common/regression-utils.js.map +1 -1
- package/cjs/common/throttle.js +3 -0
- package/cjs/common/throttle.js.map +1 -1
- package/cjs/common/toDate.js +22 -3
- package/cjs/common/toDate.js.map +1 -1
- package/cjs/common/uuid.d.ts +7 -0
- package/cjs/common/uuid.js +15 -1
- package/cjs/common/uuid.js.map +1 -1
- package/cjs/data-structure/bounds.d.ts +101 -0
- package/cjs/data-structure/bounds.js +74 -7
- package/cjs/data-structure/bounds.js.map +1 -1
- package/cjs/data-structure/hashTable.d.ts +4 -0
- package/cjs/data-structure/hashTable.js +11 -2
- package/cjs/data-structure/hashTable.js.map +1 -1
- package/cjs/data-structure/index.js +6 -2
- package/cjs/data-structure/index.js.map +1 -1
- package/cjs/data-structure/matrix.d.ts +91 -0
- package/cjs/data-structure/matrix.js +52 -4
- package/cjs/data-structure/matrix.js.map +1 -1
- package/cjs/data-structure/point.d.ts +3 -0
- package/cjs/data-structure/point.js +5 -1
- package/cjs/data-structure/point.js.map +1 -1
- package/cjs/dom.d.ts +36 -0
- package/cjs/dom.js +43 -1
- package/cjs/dom.js.map +1 -1
- package/cjs/fmin/blas1.js +10 -1
- package/cjs/fmin/blas1.js.map +1 -1
- package/cjs/fmin/conjugate-gradient.js +18 -3
- package/cjs/fmin/conjugate-gradient.js.map +1 -1
- package/cjs/fmin/linesearch.js +15 -1
- package/cjs/fmin/linesearch.js.map +1 -1
- package/cjs/fmin/nelder-mead.d.ts +1 -0
- package/cjs/fmin/nelder-mead.js +30 -10
- package/cjs/fmin/nelder-mead.js.map +1 -1
- package/cjs/format/number/formatDecimal.js +9 -1
- package/cjs/format/number/formatDecimal.js.map +1 -1
- package/cjs/format/number/formatGroup.js +7 -0
- package/cjs/format/number/formatGroup.js.map +1 -1
- package/cjs/format/number/formatPrefixAuto.js +8 -0
- package/cjs/format/number/formatPrefixAuto.js.map +1 -1
- package/cjs/format/number/formatRounded.js +7 -0
- package/cjs/format/number/formatRounded.js.map +1 -1
- package/cjs/format/number/formatTrim.js +7 -0
- package/cjs/format/number/formatTrim.js.map +1 -1
- package/cjs/format/number/number.js +39 -9
- package/cjs/format/number/number.js.map +1 -1
- package/cjs/format/time.js +23 -6
- package/cjs/format/time.js.map +1 -1
- package/cjs/geo/circle-intersection.d.ts +12 -0
- package/cjs/geo/circle-intersection.js +54 -9
- package/cjs/geo/circle-intersection.js.map +1 -1
- package/cjs/geo/constant.js +8 -1
- package/cjs/geo/constant.js.map +1 -1
- package/cjs/geo/invariant.d.ts +22 -0
- package/cjs/geo/invariant.js +24 -1
- package/cjs/geo/invariant.js.map +1 -1
- package/cjs/graphics/algorithm/aabb.js +7 -3
- package/cjs/graphics/algorithm/aabb.js.map +1 -1
- package/cjs/graphics/algorithm/intersect.d.ts +48 -0
- package/cjs/graphics/algorithm/intersect.js +75 -7
- package/cjs/graphics/algorithm/intersect.js.map +1 -1
- package/cjs/graphics/bounds-util.js +4 -2
- package/cjs/graphics/bounds-util.js.map +1 -1
- package/cjs/graphics/graph-util.js +4 -0
- package/cjs/graphics/graph-util.js.map +1 -1
- package/cjs/graphics/index.js +7 -4
- package/cjs/graphics/index.js.map +1 -1
- package/cjs/graphics/polygon.d.ts +12 -0
- package/cjs/graphics/polygon.js +28 -5
- package/cjs/graphics/polygon.js.map +1 -1
- package/cjs/graphics/text/measure/interface.d.ts +12 -0
- package/cjs/graphics/text/measure/textMeasure.d.ts +23 -0
- package/cjs/graphics/text/measure/textMeasure.js +50 -22
- package/cjs/graphics/text/measure/textMeasure.js.map +1 -1
- package/cjs/graphics/text/measure/util.js +1 -0
- package/cjs/graphics/text/measure/util.js.map +1 -1
- package/cjs/graphics/text/stringWidth.js +7 -3
- package/cjs/graphics/text/stringWidth.js.map +1 -1
- package/cjs/index.d.ts +6 -0
- package/cjs/index.js +19 -4
- package/cjs/index.js.map +1 -1
- package/cjs/logger.js +12 -2
- package/cjs/logger.js.map +1 -1
- package/cjs/lru.js +14 -6
- package/cjs/lru.js.map +1 -1
- package/cjs/math.d.ts +9 -0
- package/cjs/math.js +10 -0
- package/cjs/math.js.map +1 -1
- package/cjs/padding.d.ts +5 -0
- package/cjs/padding.js +5 -0
- package/cjs/padding.js.map +1 -1
- package/cjs/time/formatUtils.d.ts +6 -0
- package/cjs/time/formatUtils.js +7 -0
- package/cjs/time/formatUtils.js.map +1 -1
- package/dist/index.js +2035 -411
- package/dist/index.min.js +128 -1
- package/es/angle.d.ts +61 -0
- package/es/angle.js +66 -10
- package/es/angle.js.map +1 -1
- package/es/color/Color.d.ts +3 -0
- package/es/color/Color.js +64 -9
- package/es/color/Color.js.map +1 -1
- package/es/color/hexToRgb.d.ts +5 -0
- package/es/color/hexToRgb.js +5 -0
- package/es/color/hexToRgb.js.map +1 -1
- package/es/color/rgbToHsl.js +5 -1
- package/es/color/rgbToHsl.js.map +1 -1
- package/es/common/array.d.ts +43 -0
- package/es/common/array.js +44 -8
- package/es/common/array.js.map +1 -1
- package/es/common/bisect.d.ts +21 -0
- package/es/common/bisect.js +29 -4
- package/es/common/bisect.js.map +1 -1
- package/es/common/bootstrap.d.ts +5 -0
- package/es/common/bootstrap.js +14 -0
- package/es/common/bootstrap.js.map +1 -0
- package/es/common/clone.js +6 -0
- package/es/common/clone.js.map +1 -1
- package/es/common/cloneDeep.js +4 -1
- package/es/common/cloneDeep.js.map +1 -1
- package/es/common/correlation.d.ts +3 -0
- package/es/common/correlation.js +77 -0
- package/es/common/correlation.js.map +1 -0
- package/es/common/debounce.js +22 -4
- package/es/common/debounce.js.map +1 -1
- package/es/common/deviation.js +1 -2
- package/es/common/ecdf.d.ts +8 -0
- package/es/common/ecdf.js +11 -1
- package/es/common/ecdf.js.map +1 -1
- package/es/common/extent.d.ts +4 -0
- package/es/common/extent.js +8 -3
- package/es/common/extent.js.map +1 -1
- package/es/common/field.d.ts +6 -0
- package/es/common/field.js +3 -1
- package/es/common/field.js.map +1 -1
- package/es/common/has.d.ts +17 -0
- package/es/common/has.js +18 -1
- package/es/common/has.js.map +1 -1
- package/es/common/index.d.ts +5 -0
- package/es/common/index.js +24 -0
- package/es/common/index.js.map +1 -1
- package/es/common/interpolate.js +16 -3
- package/es/common/interpolate.js.map +1 -1
- package/es/common/isBase64.d.ts +6 -0
- package/es/common/isBase64.js +6 -0
- package/es/common/isBase64.js.map +1 -1
- package/es/common/isBoolean.d.ts +13 -0
- package/es/common/isBoolean.js +13 -1
- package/es/common/isBoolean.js.map +1 -1
- package/es/common/isEmpty.js +11 -1
- package/es/common/isEmpty.js.map +1 -1
- package/es/common/isEqual.js +19 -7
- package/es/common/isEqual.js.map +1 -1
- package/es/common/isFunction.d.ts +25 -0
- package/es/common/isFunction.js +27 -2
- package/es/common/isFunction.js.map +1 -1
- package/es/common/isNull.js +2 -1
- package/es/common/isNumber.d.ts +23 -0
- package/es/common/isNumber.js +23 -1
- package/es/common/isNumber.js.map +1 -1
- package/es/common/isNumeric.d.ts +25 -0
- package/es/common/isNumeric.js +25 -0
- package/es/common/isNumeric.js.map +1 -1
- package/es/common/isObject.d.ts +21 -0
- package/es/common/isObject.js +22 -0
- package/es/common/isObject.js.map +1 -1
- package/es/common/isObjectLike.d.ts +20 -0
- package/es/common/isObjectLike.js +21 -0
- package/es/common/isObjectLike.js.map +1 -1
- package/es/common/isPlainObject.d.ts +25 -0
- package/es/common/isPlainObject.js +26 -0
- package/es/common/isPlainObject.js.map +1 -1
- package/es/common/isPrototype.js +1 -1
- package/es/common/isRegExp.js +1 -1
- package/es/common/isShallowEqual.js +1 -0
- package/es/common/isShallowEqual.js.map +1 -1
- package/es/common/isString.d.ts +13 -0
- package/es/common/isString.js +13 -1
- package/es/common/isString.js.map +1 -1
- package/es/common/isType.d.ts +6 -0
- package/es/common/isType.js +6 -0
- package/es/common/isType.js.map +1 -1
- package/es/common/isValidNumber.js.map +1 -1
- package/es/common/isValidUrl.js.map +1 -1
- package/es/common/kde.d.ts +28 -0
- package/es/common/kde.js +29 -7
- package/es/common/kde.js.map +1 -1
- package/es/common/mean.d.ts +2 -0
- package/es/common/mean.js +19 -0
- package/es/common/mean.js.map +1 -0
- package/es/common/merge.js +22 -5
- package/es/common/merge.js.map +1 -1
- package/es/common/mixin.js +14 -3
- package/es/common/mixin.js.map +1 -1
- package/es/common/normalQuantile.d.ts +5 -0
- package/es/common/normalQuantile.js +15 -0
- package/es/common/normalQuantile.js.map +1 -0
- package/es/common/number.d.ts +24 -0
- package/es/common/number.js +24 -2
- package/es/common/number.js.map +1 -1
- package/es/common/pad.d.ts +21 -0
- package/es/common/pad.js +21 -1
- package/es/common/pad.js.map +1 -1
- package/es/common/random.d.ts +3 -0
- package/es/common/random.js +13 -1
- package/es/common/random.js.map +1 -1
- package/es/common/regression-bootstrap.d.ts +14 -0
- package/es/common/regression-bootstrap.js +31 -0
- package/es/common/regression-bootstrap.js.map +1 -0
- package/es/common/regression-linear.d.ts +5 -0
- package/es/common/regression-linear.js +25 -39
- package/es/common/regression-linear.js.map +1 -1
- package/es/common/regression-logistic.d.ts +6 -0
- package/es/common/regression-logistic.js +24 -16
- package/es/common/regression-logistic.js.map +1 -1
- package/es/common/regression-lowess.d.ts +11 -1
- package/es/common/regression-lowess.js +120 -118
- package/es/common/regression-lowess.js.map +1 -1
- package/es/common/regression-polynomial.d.ts +1 -0
- package/es/common/regression-polynomial.js +21 -89
- package/es/common/regression-polynomial.js.map +1 -1
- package/es/common/regression-solver.d.ts +26 -0
- package/es/common/regression-solver.js +168 -0
- package/es/common/regression-solver.js.map +1 -0
- package/es/common/regression-utils.d.ts +13 -1
- package/es/common/regression-utils.js +18 -9
- package/es/common/regression-utils.js.map +1 -1
- package/es/common/throttle.js +3 -0
- package/es/common/throttle.js.map +1 -1
- package/es/common/toDate.js +23 -3
- package/es/common/toDate.js.map +1 -1
- package/es/common/uuid.d.ts +7 -0
- package/es/common/uuid.js +15 -1
- package/es/common/uuid.js.map +1 -1
- package/es/data-structure/bounds.d.ts +101 -0
- package/es/data-structure/bounds.js +74 -8
- package/es/data-structure/bounds.js.map +1 -1
- package/es/data-structure/hashTable.d.ts +4 -0
- package/es/data-structure/hashTable.js +11 -2
- package/es/data-structure/hashTable.js.map +1 -1
- package/es/data-structure/index.js +2 -0
- package/es/data-structure/index.js.map +1 -1
- package/es/data-structure/matrix.d.ts +91 -0
- package/es/data-structure/matrix.js +52 -5
- package/es/data-structure/matrix.js.map +1 -1
- package/es/data-structure/point.d.ts +3 -0
- package/es/data-structure/point.js +5 -1
- package/es/data-structure/point.js.map +1 -1
- package/es/dom.d.ts +36 -0
- package/es/dom.js +43 -8
- package/es/dom.js.map +1 -1
- package/es/fmin/blas1.js +10 -0
- package/es/fmin/blas1.js.map +1 -1
- package/es/fmin/conjugate-gradient.js +18 -2
- package/es/fmin/conjugate-gradient.js.map +1 -1
- package/es/fmin/linesearch.js +15 -0
- package/es/fmin/linesearch.js.map +1 -1
- package/es/fmin/nelder-mead.d.ts +1 -0
- package/es/fmin/nelder-mead.js +29 -9
- package/es/fmin/nelder-mead.js.map +1 -1
- package/es/format/number/formatDecimal.js +9 -1
- package/es/format/number/formatDecimal.js.map +1 -1
- package/es/format/number/formatGroup.js +7 -0
- package/es/format/number/formatGroup.js.map +1 -1
- package/es/format/number/formatPrefixAuto.js +8 -0
- package/es/format/number/formatPrefixAuto.js.map +1 -1
- package/es/format/number/formatRounded.js +7 -0
- package/es/format/number/formatRounded.js.map +1 -1
- package/es/format/number/formatTrim.js +7 -0
- package/es/format/number/formatTrim.js.map +1 -1
- package/es/format/number/number.js +40 -8
- package/es/format/number/number.js.map +1 -1
- package/es/format/time.js +23 -5
- package/es/format/time.js.map +1 -1
- package/es/geo/circle-intersection.d.ts +12 -0
- package/es/geo/circle-intersection.js +54 -14
- package/es/geo/circle-intersection.js.map +1 -1
- package/es/geo/constant.js +8 -0
- package/es/geo/constant.js.map +1 -1
- package/es/geo/invariant.d.ts +22 -0
- package/es/geo/invariant.js +24 -0
- package/es/geo/invariant.js.map +1 -1
- package/es/graphics/algorithm/aabb.js +7 -3
- package/es/graphics/algorithm/aabb.js.map +1 -1
- package/es/graphics/algorithm/intersect.d.ts +48 -0
- package/es/graphics/algorithm/intersect.js +75 -12
- package/es/graphics/algorithm/intersect.js.map +1 -1
- package/es/graphics/bounds-util.js +4 -2
- package/es/graphics/bounds-util.js.map +1 -1
- package/es/graphics/graph-util.js +4 -0
- package/es/graphics/graph-util.js.map +1 -1
- package/es/graphics/index.js +2 -0
- package/es/graphics/index.js.map +1 -1
- package/es/graphics/polygon.d.ts +12 -0
- package/es/graphics/polygon.js +28 -6
- package/es/graphics/polygon.js.map +1 -1
- package/es/graphics/text/measure/interface.d.ts +12 -0
- package/es/graphics/text/measure/textMeasure.d.ts +23 -0
- package/es/graphics/text/measure/textMeasure.js +46 -21
- package/es/graphics/text/measure/textMeasure.js.map +1 -1
- package/es/graphics/text/measure/util.js +1 -0
- package/es/graphics/text/measure/util.js.map +1 -1
- package/es/graphics/text/stringWidth.js +7 -3
- package/es/graphics/text/stringWidth.js.map +1 -1
- package/es/index.d.ts +6 -0
- package/es/index.js +15 -1
- package/es/index.js.map +1 -1
- package/es/logger.js +12 -1
- package/es/logger.js.map +1 -1
- package/es/lru.js +14 -6
- package/es/lru.js.map +1 -1
- package/es/math.d.ts +9 -0
- package/es/math.js +10 -1
- package/es/math.js.map +1 -1
- package/es/padding.d.ts +5 -0
- package/es/padding.js +5 -1
- package/es/padding.js.map +1 -1
- package/es/time/formatUtils.d.ts +6 -0
- package/es/time/formatUtils.js +7 -1
- package/es/time/formatUtils.js.map +1 -1
- package/package.json +4 -3
|
@@ -1,14 +1,30 @@
|
|
|
1
|
+
/* Adapted from venn.js by Ben Frederickson
|
|
2
|
+
* https://github.com/benfred/venn.js
|
|
3
|
+
* Licensed under the MIT
|
|
4
|
+
|
|
5
|
+
* url: https://github.com/benfred/venn.js/blob/master/src/circleintersection.js
|
|
6
|
+
* License: https://github.com/benfred/venn.js/blob/master/LICENSE
|
|
7
|
+
* @license
|
|
8
|
+
*/
|
|
9
|
+
// eslint-disable-next-line no-duplicate-imports
|
|
1
10
|
import { PointService } from "../data-structure";
|
|
2
11
|
|
|
3
12
|
import { SMALL } from "./constant";
|
|
4
13
|
|
|
5
|
-
|
|
14
|
+
/** Returns the intersection area of a bunch of circles (where each circle
|
|
15
|
+
is an object having an x,y and radius property) */ export function intersectionArea(circles, stats) {
|
|
16
|
+
// get all the intersection points of the circles
|
|
6
17
|
const intersectionPoints = getIntersectionPoints(circles), innerPoints = intersectionPoints.filter((function(p) {
|
|
7
18
|
return containedInCircles(p, circles);
|
|
8
19
|
}));
|
|
9
|
-
|
|
20
|
+
// filter out points that aren't included in all the circles
|
|
21
|
+
let arcArea = 0, polygonArea = 0;
|
|
10
22
|
const arcs = [];
|
|
11
|
-
if
|
|
23
|
+
// if we have intersection points that are within all the circles,
|
|
24
|
+
// then figure out the area contained by them
|
|
25
|
+
if (innerPoints.length > 1) {
|
|
26
|
+
// sort the points by angle from the center of the polygon, which lets
|
|
27
|
+
// us just iterate over points to get the edges
|
|
12
28
|
const center = getCenter(innerPoints);
|
|
13
29
|
for (let i = 0; i < innerPoints.length; ++i) {
|
|
14
30
|
const p = innerPoints[i];
|
|
@@ -17,25 +33,37 @@ export function intersectionArea(circles, stats) {
|
|
|
17
33
|
innerPoints.sort((function(a, b) {
|
|
18
34
|
return b.angle - a.angle;
|
|
19
35
|
}));
|
|
36
|
+
// iterate over all points, get arc between the points
|
|
37
|
+
// and update the areas
|
|
20
38
|
let p2 = innerPoints[innerPoints.length - 1];
|
|
21
39
|
for (let i = 0; i < innerPoints.length; ++i) {
|
|
22
40
|
const p1 = innerPoints[i];
|
|
23
|
-
|
|
41
|
+
// polygon area updates easily ...
|
|
42
|
+
polygonArea += (p2.x + p1.x) * (p1.y - p2.y);
|
|
43
|
+
// updating the arc area is a little more involved
|
|
24
44
|
const midPoint = {
|
|
25
45
|
x: (p1.x + p2.x) / 2,
|
|
26
46
|
y: (p1.y + p2.y) / 2
|
|
27
47
|
};
|
|
28
48
|
let arc = null;
|
|
29
49
|
for (let j = 0; j < p1.parentIndex.length; ++j) if (p2.parentIndex.indexOf(p1.parentIndex[j]) > -1) {
|
|
50
|
+
// figure out the angle halfway between the two points
|
|
51
|
+
// on the current circle
|
|
30
52
|
const circle = circles[p1.parentIndex[j]], a1 = Math.atan2(p1.x - circle.x, p1.y - circle.y), a2 = Math.atan2(p2.x - circle.x, p2.y - circle.y);
|
|
31
53
|
let angleDiff = a2 - a1;
|
|
32
54
|
angleDiff < 0 && (angleDiff += 2 * Math.PI);
|
|
33
|
-
|
|
55
|
+
// and use that angle to figure out the width of the
|
|
56
|
+
// arc
|
|
57
|
+
const a = a2 - angleDiff / 2;
|
|
34
58
|
let width = PointService.distancePP(midPoint, {
|
|
35
59
|
x: circle.x + circle.radius * Math.sin(a),
|
|
36
60
|
y: circle.y + circle.radius * Math.cos(a)
|
|
37
61
|
});
|
|
38
|
-
|
|
62
|
+
// clamp the width to the largest is can actually be
|
|
63
|
+
// (sometimes slightly overflows because of FP errors)
|
|
64
|
+
width > 2 * circle.radius && (width = 2 * circle.radius),
|
|
65
|
+
// pick the circle whose arc has the smallest width
|
|
66
|
+
(null === arc || arc.width > width) && (arc = {
|
|
39
67
|
circle: circle,
|
|
40
68
|
width: width,
|
|
41
69
|
p1: p1,
|
|
@@ -46,9 +74,13 @@ export function intersectionArea(circles, stats) {
|
|
|
46
74
|
p2 = p1);
|
|
47
75
|
}
|
|
48
76
|
} else {
|
|
77
|
+
// no intersection points, is either disjoint - or is completely
|
|
78
|
+
// overlapped. figure out which by examining the smallest circle
|
|
49
79
|
let smallest = circles[0];
|
|
50
80
|
for (let i = 1; i < circles.length; ++i) circles[i].radius < smallest.radius && (smallest = circles[i]);
|
|
51
|
-
|
|
81
|
+
// make sure the smallest circle is completely contained in all
|
|
82
|
+
// the other circles
|
|
83
|
+
let disjoint = !1;
|
|
52
84
|
for (let i = 0; i < circles.length; ++i) if (PointService.distancePP(circles[i], smallest) > Math.abs(smallest.radius - circles[i].radius)) {
|
|
53
85
|
disjoint = !0;
|
|
54
86
|
break;
|
|
@@ -72,12 +104,12 @@ export function intersectionArea(circles, stats) {
|
|
|
72
104
|
stats.intersectionPoints = intersectionPoints), arcArea + polygonArea;
|
|
73
105
|
}
|
|
74
106
|
|
|
75
|
-
export function containedInCircles(point, circles) {
|
|
107
|
+
/** returns whether a point is contained by all of a list of circles */ export function containedInCircles(point, circles) {
|
|
76
108
|
for (let i = 0; i < circles.length; ++i) if (PointService.distancePP(point, circles[i]) > circles[i].radius + SMALL) return !1;
|
|
77
109
|
return !0;
|
|
78
110
|
}
|
|
79
111
|
|
|
80
|
-
function getIntersectionPoints(circles) {
|
|
112
|
+
/** Gets all intersection points between a bunch of circles */ function getIntersectionPoints(circles) {
|
|
81
113
|
const ret = [];
|
|
82
114
|
for (let i = 0; i < circles.length; ++i) for (let j = i + 1; j < circles.length; ++j) {
|
|
83
115
|
const intersect = circleCircleIntersection(circles[i], circles[j]);
|
|
@@ -89,19 +121,27 @@ function getIntersectionPoints(circles) {
|
|
|
89
121
|
return ret;
|
|
90
122
|
}
|
|
91
123
|
|
|
92
|
-
export function circleArea(r, width) {
|
|
124
|
+
/** Circular segment area calculation. See http://mathworld.wolfram.com/CircularSegment.html */ export function circleArea(r, width) {
|
|
93
125
|
return r * r * Math.acos(1 - width / r) - (r - width) * Math.sqrt(width * (2 * r - width));
|
|
94
126
|
}
|
|
95
127
|
|
|
96
|
-
|
|
128
|
+
/** Returns the overlap area of two circles of radius r1 and r2 - that
|
|
129
|
+
have their centers separated by distance d. Simpler faster
|
|
130
|
+
circle intersection for only two circles */ export function circleOverlap(r1, r2, d) {
|
|
131
|
+
// no overlap
|
|
97
132
|
if (d >= r1 + r2) return 0;
|
|
98
|
-
|
|
133
|
+
// completely overlapped
|
|
134
|
+
if (d <= Math.abs(r1 - r2)) return Math.PI * Math.min(r1, r2) * Math.min(r1, r2);
|
|
99
135
|
const w2 = r2 - (d * d - r1 * r1 + r2 * r2) / (2 * d);
|
|
100
136
|
return circleArea(r1, r1 - (d * d - r2 * r2 + r1 * r1) / (2 * d)) + circleArea(r2, w2);
|
|
101
137
|
}
|
|
102
138
|
|
|
103
|
-
|
|
139
|
+
/** Given two circles (containing a x/y/radius attributes),
|
|
140
|
+
returns the intersecting points if possible.
|
|
141
|
+
note: doesn't handle cases where there are infinitely many
|
|
142
|
+
intersection points (circles are equivalent):, or only one intersection point*/ export function circleCircleIntersection(p1, p2) {
|
|
104
143
|
const d = PointService.distancePP(p1, p2), r1 = p1.radius, r2 = p2.radius;
|
|
144
|
+
// if to far away, or self contained - can't be done
|
|
105
145
|
if (d >= r1 + r2 || d <= Math.abs(r1 - r2)) return [];
|
|
106
146
|
const a = (r1 * r1 - r2 * r2 + d * d) / (2 * d), h = Math.sqrt(r1 * r1 - a * a), x0 = p1.x + a * (p2.x - p1.x) / d, y0 = p1.y + a * (p2.y - p1.y) / d, rx = -(p2.y - p1.y) * (h / d), ry = -(p2.x - p1.x) * (h / d);
|
|
107
147
|
return [ {
|
|
@@ -113,7 +153,7 @@ export function circleCircleIntersection(p1, p2) {
|
|
|
113
153
|
} ];
|
|
114
154
|
}
|
|
115
155
|
|
|
116
|
-
export function getCenter(points) {
|
|
156
|
+
/** Returns the center of a bunch of points */ export function getCenter(points) {
|
|
117
157
|
const center = {
|
|
118
158
|
x: 0,
|
|
119
159
|
y: 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/geo/circle-intersection.ts"],"names":[],"mappings":"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","file":"circle-intersection.js","sourcesContent":["/* Adapted from venn.js by Ben Frederickson\n * https://github.com/benfred/venn.js\n * Licensed under the MIT\n\n * url: https://github.com/benfred/venn.js/blob/master/src/circleintersection.js\n * License: https://github.com/benfred/venn.js/blob/master/LICENSE\n * @license\n */\n\nimport type { IPointLike } from '../data-structure';\n// eslint-disable-next-line no-duplicate-imports\nimport { PointService } from '../data-structure';\nimport { SMALL } from './constant';\nimport type { ICircleArc, ICircle, IIntersectPoint, IOverlapAreaStats } from './interface';\n\n/** Returns the intersection area of a bunch of circles (where each circle\n is an object having an x,y and radius property) */\nexport function intersectionArea(circles: ICircle[], stats?: IOverlapAreaStats) {\n // get all the intersection points of the circles\n const intersectionPoints = getIntersectionPoints(circles);\n\n // filter out points that aren't included in all the circles\n const innerPoints = intersectionPoints.filter(function (p) {\n return containedInCircles(p, circles);\n });\n\n let arcArea = 0;\n let polygonArea = 0;\n const arcs: ICircleArc[] = [];\n\n // if we have intersection points that are within all the circles,\n // then figure out the area contained by them\n if (innerPoints.length > 1) {\n // sort the points by angle from the center of the polygon, which lets\n // us just iterate over points to get the edges\n const center = getCenter(innerPoints);\n for (let i = 0; i < innerPoints.length; ++i) {\n const p = innerPoints[i];\n p.angle = Math.atan2(p.x - center.x, p.y - center.y);\n }\n innerPoints.sort(function (a, b) {\n return b.angle - a.angle;\n });\n\n // iterate over all points, get arc between the points\n // and update the areas\n let p2 = innerPoints[innerPoints.length - 1];\n for (let i = 0; i < innerPoints.length; ++i) {\n const p1 = innerPoints[i];\n\n // polygon area updates easily ...\n polygonArea += (p2.x + p1.x) * (p1.y - p2.y);\n\n // updating the arc area is a little more involved\n const midPoint = { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 };\n let arc = null;\n\n for (let j = 0; j < p1.parentIndex.length; ++j) {\n if (p2.parentIndex.indexOf(p1.parentIndex[j]) > -1) {\n // figure out the angle halfway between the two points\n // on the current circle\n const circle = circles[p1.parentIndex[j]];\n const a1 = Math.atan2(p1.x - circle.x, p1.y - circle.y);\n const a2 = Math.atan2(p2.x - circle.x, p2.y - circle.y);\n\n let angleDiff = a2 - a1;\n if (angleDiff < 0) {\n angleDiff += 2 * Math.PI;\n }\n\n // and use that angle to figure out the width of the\n // arc\n const a = a2 - angleDiff / 2;\n let width = PointService.distancePP(midPoint, {\n x: circle.x + circle.radius * Math.sin(a),\n y: circle.y + circle.radius * Math.cos(a)\n });\n\n // clamp the width to the largest is can actually be\n // (sometimes slightly overflows because of FP errors)\n if (width > circle.radius * 2) {\n width = circle.radius * 2;\n }\n\n // pick the circle whose arc has the smallest width\n if (arc === null || arc.width > width) {\n arc = { circle: circle, width: width, p1: p1, p2: p2 };\n }\n }\n }\n\n if (arc !== null) {\n arcs.push(arc);\n arcArea += circleArea(arc.circle.radius, arc.width);\n p2 = p1;\n }\n }\n } else {\n // no intersection points, is either disjoint - or is completely\n // overlapped. figure out which by examining the smallest circle\n let smallest = circles[0];\n for (let i = 1; i < circles.length; ++i) {\n if (circles[i].radius < smallest.radius) {\n smallest = circles[i];\n }\n }\n\n // make sure the smallest circle is completely contained in all\n // the other circles\n let disjoint = false;\n for (let i = 0; i < circles.length; ++i) {\n if (PointService.distancePP(circles[i], smallest) > Math.abs(smallest.radius - circles[i].radius)) {\n disjoint = true;\n break;\n }\n }\n\n if (disjoint) {\n arcArea = polygonArea = 0;\n } else {\n arcArea = smallest.radius * smallest.radius * Math.PI;\n arcs.push({\n circle: smallest,\n p1: { x: smallest.x, y: smallest.y + smallest.radius },\n p2: { x: smallest.x - SMALL, y: smallest.y + smallest.radius },\n width: smallest.radius * 2\n });\n }\n }\n\n polygonArea /= 2;\n if (stats) {\n stats.area = arcArea + polygonArea;\n stats.arcArea = arcArea;\n stats.polygonArea = polygonArea;\n stats.arcs = arcs;\n stats.innerPoints = innerPoints;\n stats.intersectionPoints = intersectionPoints;\n }\n\n return arcArea + polygonArea;\n}\n\n/** returns whether a point is contained by all of a list of circles */\nexport function containedInCircles(point: IPointLike, circles: ICircle[]) {\n for (let i = 0; i < circles.length; ++i) {\n if (PointService.distancePP(point, circles[i]) > circles[i].radius + SMALL) {\n return false;\n }\n }\n return true;\n}\n\n/** Gets all intersection points between a bunch of circles */\nfunction getIntersectionPoints(circles: ICircle[]) {\n const ret = [];\n for (let i = 0; i < circles.length; ++i) {\n for (let j = i + 1; j < circles.length; ++j) {\n const intersect = circleCircleIntersection(circles[i], circles[j]);\n for (let k = 0; k < intersect.length; ++k) {\n const p = intersect[k];\n p.parentIndex = [i, j];\n ret.push(p);\n }\n }\n }\n return ret;\n}\n\n/** Circular segment area calculation. See http://mathworld.wolfram.com/CircularSegment.html */\nexport function circleArea(r: number, width: number) {\n return r * r * Math.acos(1 - width / r) - (r - width) * Math.sqrt(width * (2 * r - width));\n}\n\n/** Returns the overlap area of two circles of radius r1 and r2 - that\nhave their centers separated by distance d. Simpler faster\ncircle intersection for only two circles */\nexport function circleOverlap(r1: number, r2: number, d: number) {\n // no overlap\n if (d >= r1 + r2) {\n return 0;\n }\n\n // completely overlapped\n if (d <= Math.abs(r1 - r2)) {\n return Math.PI * Math.min(r1, r2) * Math.min(r1, r2);\n }\n\n const w1 = r1 - (d * d - r2 * r2 + r1 * r1) / (2 * d);\n const w2 = r2 - (d * d - r1 * r1 + r2 * r2) / (2 * d);\n return circleArea(r1, w1) + circleArea(r2, w2);\n}\n\n/** Given two circles (containing a x/y/radius attributes),\nreturns the intersecting points if possible.\nnote: doesn't handle cases where there are infinitely many\nintersection points (circles are equivalent):, or only one intersection point*/\nexport function circleCircleIntersection(p1: ICircle, p2: ICircle): IIntersectPoint[] {\n const d = PointService.distancePP(p1, p2);\n const r1 = p1.radius;\n const r2 = p2.radius;\n\n // if to far away, or self contained - can't be done\n if (d >= r1 + r2 || d <= Math.abs(r1 - r2)) {\n return [];\n }\n\n const a = (r1 * r1 - r2 * r2 + d * d) / (2 * d);\n const h = Math.sqrt(r1 * r1 - a * a);\n const x0 = p1.x + (a * (p2.x - p1.x)) / d;\n const y0 = p1.y + (a * (p2.y - p1.y)) / d;\n const rx = -(p2.y - p1.y) * (h / d);\n const ry = -(p2.x - p1.x) * (h / d);\n\n return [\n { x: x0 + rx, y: y0 - ry },\n { x: x0 - rx, y: y0 + ry }\n ];\n}\n\n/** Returns the center of a bunch of points */\nexport function getCenter(points: IPointLike[]) {\n const center = { x: 0, y: 0 };\n for (let i = 0; i < points.length; ++i) {\n center.x += points[i].x;\n center.y += points[i].y;\n }\n center.x /= points.length;\n center.y /= points.length;\n return center;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/geo/circle-intersection.ts"],"names":[],"mappings":"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","file":"circle-intersection.js","sourcesContent":["/* Adapted from venn.js by Ben Frederickson\n * https://github.com/benfred/venn.js\n * Licensed under the MIT\n\n * url: https://github.com/benfred/venn.js/blob/master/src/circleintersection.js\n * License: https://github.com/benfred/venn.js/blob/master/LICENSE\n * @license\n */\n\nimport type { IPointLike } from '../data-structure';\n// eslint-disable-next-line no-duplicate-imports\nimport { PointService } from '../data-structure';\nimport { SMALL } from './constant';\nimport type { ICircleArc, ICircle, IIntersectPoint, IOverlapAreaStats } from './interface';\n\n/** Returns the intersection area of a bunch of circles (where each circle\n is an object having an x,y and radius property) */\nexport function intersectionArea(circles: ICircle[], stats?: IOverlapAreaStats) {\n // get all the intersection points of the circles\n const intersectionPoints = getIntersectionPoints(circles);\n\n // filter out points that aren't included in all the circles\n const innerPoints = intersectionPoints.filter(function (p) {\n return containedInCircles(p, circles);\n });\n\n let arcArea = 0;\n let polygonArea = 0;\n const arcs: ICircleArc[] = [];\n\n // if we have intersection points that are within all the circles,\n // then figure out the area contained by them\n if (innerPoints.length > 1) {\n // sort the points by angle from the center of the polygon, which lets\n // us just iterate over points to get the edges\n const center = getCenter(innerPoints);\n for (let i = 0; i < innerPoints.length; ++i) {\n const p = innerPoints[i];\n p.angle = Math.atan2(p.x - center.x, p.y - center.y);\n }\n innerPoints.sort(function (a, b) {\n return b.angle - a.angle;\n });\n\n // iterate over all points, get arc between the points\n // and update the areas\n let p2 = innerPoints[innerPoints.length - 1];\n for (let i = 0; i < innerPoints.length; ++i) {\n const p1 = innerPoints[i];\n\n // polygon area updates easily ...\n polygonArea += (p2.x + p1.x) * (p1.y - p2.y);\n\n // updating the arc area is a little more involved\n const midPoint = { x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2 };\n let arc = null;\n\n for (let j = 0; j < p1.parentIndex.length; ++j) {\n if (p2.parentIndex.indexOf(p1.parentIndex[j]) > -1) {\n // figure out the angle halfway between the two points\n // on the current circle\n const circle = circles[p1.parentIndex[j]];\n const a1 = Math.atan2(p1.x - circle.x, p1.y - circle.y);\n const a2 = Math.atan2(p2.x - circle.x, p2.y - circle.y);\n\n let angleDiff = a2 - a1;\n if (angleDiff < 0) {\n angleDiff += 2 * Math.PI;\n }\n\n // and use that angle to figure out the width of the\n // arc\n const a = a2 - angleDiff / 2;\n let width = PointService.distancePP(midPoint, {\n x: circle.x + circle.radius * Math.sin(a),\n y: circle.y + circle.radius * Math.cos(a)\n });\n\n // clamp the width to the largest is can actually be\n // (sometimes slightly overflows because of FP errors)\n if (width > circle.radius * 2) {\n width = circle.radius * 2;\n }\n\n // pick the circle whose arc has the smallest width\n if (arc === null || arc.width > width) {\n arc = { circle: circle, width: width, p1: p1, p2: p2 };\n }\n }\n }\n\n if (arc !== null) {\n arcs.push(arc);\n arcArea += circleArea(arc.circle.radius, arc.width);\n p2 = p1;\n }\n }\n } else {\n // no intersection points, is either disjoint - or is completely\n // overlapped. figure out which by examining the smallest circle\n let smallest = circles[0];\n for (let i = 1; i < circles.length; ++i) {\n if (circles[i].radius < smallest.radius) {\n smallest = circles[i];\n }\n }\n\n // make sure the smallest circle is completely contained in all\n // the other circles\n let disjoint = false;\n for (let i = 0; i < circles.length; ++i) {\n if (PointService.distancePP(circles[i], smallest) > Math.abs(smallest.radius - circles[i].radius)) {\n disjoint = true;\n break;\n }\n }\n\n if (disjoint) {\n arcArea = polygonArea = 0;\n } else {\n arcArea = smallest.radius * smallest.radius * Math.PI;\n arcs.push({\n circle: smallest,\n p1: { x: smallest.x, y: smallest.y + smallest.radius },\n p2: { x: smallest.x - SMALL, y: smallest.y + smallest.radius },\n width: smallest.radius * 2\n });\n }\n }\n\n polygonArea /= 2;\n if (stats) {\n stats.area = arcArea + polygonArea;\n stats.arcArea = arcArea;\n stats.polygonArea = polygonArea;\n stats.arcs = arcs;\n stats.innerPoints = innerPoints;\n stats.intersectionPoints = intersectionPoints;\n }\n\n return arcArea + polygonArea;\n}\n\n/** returns whether a point is contained by all of a list of circles */\nexport function containedInCircles(point: IPointLike, circles: ICircle[]) {\n for (let i = 0; i < circles.length; ++i) {\n if (PointService.distancePP(point, circles[i]) > circles[i].radius + SMALL) {\n return false;\n }\n }\n return true;\n}\n\n/** Gets all intersection points between a bunch of circles */\nfunction getIntersectionPoints(circles: ICircle[]) {\n const ret = [];\n for (let i = 0; i < circles.length; ++i) {\n for (let j = i + 1; j < circles.length; ++j) {\n const intersect = circleCircleIntersection(circles[i], circles[j]);\n for (let k = 0; k < intersect.length; ++k) {\n const p = intersect[k];\n p.parentIndex = [i, j];\n ret.push(p);\n }\n }\n }\n return ret;\n}\n\n/** Circular segment area calculation. See http://mathworld.wolfram.com/CircularSegment.html */\nexport function circleArea(r: number, width: number) {\n return r * r * Math.acos(1 - width / r) - (r - width) * Math.sqrt(width * (2 * r - width));\n}\n\n/** Returns the overlap area of two circles of radius r1 and r2 - that\nhave their centers separated by distance d. Simpler faster\ncircle intersection for only two circles */\nexport function circleOverlap(r1: number, r2: number, d: number) {\n // no overlap\n if (d >= r1 + r2) {\n return 0;\n }\n\n // completely overlapped\n if (d <= Math.abs(r1 - r2)) {\n return Math.PI * Math.min(r1, r2) * Math.min(r1, r2);\n }\n\n const w1 = r1 - (d * d - r2 * r2 + r1 * r1) / (2 * d);\n const w2 = r2 - (d * d - r1 * r1 + r2 * r2) / (2 * d);\n return circleArea(r1, w1) + circleArea(r2, w2);\n}\n\n/** Given two circles (containing a x/y/radius attributes),\nreturns the intersecting points if possible.\nnote: doesn't handle cases where there are infinitely many\nintersection points (circles are equivalent):, or only one intersection point*/\nexport function circleCircleIntersection(p1: ICircle, p2: ICircle): IIntersectPoint[] {\n const d = PointService.distancePP(p1, p2);\n const r1 = p1.radius;\n const r2 = p2.radius;\n\n // if to far away, or self contained - can't be done\n if (d >= r1 + r2 || d <= Math.abs(r1 - r2)) {\n return [];\n }\n\n const a = (r1 * r1 - r2 * r2 + d * d) / (2 * d);\n const h = Math.sqrt(r1 * r1 - a * a);\n const x0 = p1.x + (a * (p2.x - p1.x)) / d;\n const y0 = p1.y + (a * (p2.y - p1.y)) / d;\n const rx = -(p2.y - p1.y) * (h / d);\n const ry = -(p2.x - p1.x) * (h / d);\n\n return [\n { x: x0 + rx, y: y0 - ry },\n { x: x0 - rx, y: y0 + ry }\n ];\n}\n\n/** Returns the center of a bunch of points */\nexport function getCenter(points: IPointLike[]) {\n const center = { x: 0, y: 0 };\n for (let i = 0; i < points.length; ++i) {\n center.x += points[i].x;\n center.y += points[i].y;\n }\n center.x /= points.length;\n center.y /= points.length;\n return center;\n}\n"]}
|
package/es/geo/constant.js
CHANGED
|
@@ -1,2 +1,10 @@
|
|
|
1
|
+
/* Adapted from venn.js by Ben Frederickson
|
|
2
|
+
* https://github.com/benfred/venn.js
|
|
3
|
+
* Licensed under the MIT
|
|
4
|
+
|
|
5
|
+
* url: https://github.com/benfred/venn.js/blob/master/src/circleintersection.js
|
|
6
|
+
* License: https://github.com/benfred/venn.js/blob/master/LICENSE
|
|
7
|
+
* @license
|
|
8
|
+
*/
|
|
1
9
|
export const SMALL = 1e-10;
|
|
2
10
|
//# sourceMappingURL=constant.js.map
|
package/es/geo/constant.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/geo/constant.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/geo/constant.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,CAAC,MAAM,KAAK,GAAG,KAAK,CAAC","file":"constant.js","sourcesContent":["/* Adapted from venn.js by Ben Frederickson\n * https://github.com/benfred/venn.js\n * Licensed under the MIT\n\n * url: https://github.com/benfred/venn.js/blob/master/src/circleintersection.js\n * License: https://github.com/benfred/venn.js/blob/master/LICENSE\n * @license\n */\n\nexport const SMALL = 1e-10;\n"]}
|
package/es/geo/invariant.d.ts
CHANGED
|
@@ -1,3 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The MIT License (MIT)
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2019 Morgan Herlocker
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
7
|
+
* this software and associated documentation files (the "Software"), to deal in
|
|
8
|
+
* the Software without restriction, including without limitation the rights to
|
|
9
|
+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
10
|
+
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
11
|
+
* subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
1
23
|
import type { Feature, MultiPolygon, Polygon, Units } from './interface';
|
|
2
24
|
import type { IPointLike } from '../data-structure';
|
|
3
25
|
export declare function isPointInPolygon<G extends Polygon | MultiPolygon>(point: IPointLike, polygon: Feature<G> | G): boolean;
|
package/es/geo/invariant.js
CHANGED
|
@@ -1,9 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The MIT License (MIT)
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2019 Morgan Herlocker
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
7
|
+
* this software and associated documentation files (the "Software"), to deal in
|
|
8
|
+
* the Software without restriction, including without limitation the rights to
|
|
9
|
+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
10
|
+
* the Software, and to permit persons to whom the Software is furnished to do so,
|
|
11
|
+
* subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software.
|
|
14
|
+
*
|
|
15
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
17
|
+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
18
|
+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
19
|
+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
20
|
+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
21
|
+
*
|
|
22
|
+
*/
|
|
1
23
|
import { lengthToRadians } from "@turf/helpers";
|
|
2
24
|
|
|
3
25
|
import { pointInRect, polygonContainPoint } from "../graphics";
|
|
4
26
|
|
|
5
27
|
import { degreeToRadian, radianToDegree } from "../angle";
|
|
6
28
|
|
|
29
|
+
// https://github.com/Turfjs/turf
|
|
7
30
|
function getGeom(geojson) {
|
|
8
31
|
return "Feature" === geojson.type ? geojson.geometry : geojson;
|
|
9
32
|
}
|
|
@@ -30,6 +53,7 @@ export function isPointInPolygon(point, polygon) {
|
|
|
30
53
|
return result;
|
|
31
54
|
}
|
|
32
55
|
|
|
56
|
+
// https://github.com/Turfjs/turf
|
|
33
57
|
export function destination(point, distance, bearing, options = {}) {
|
|
34
58
|
const longitude1 = degreeToRadian(point[0]), latitude1 = degreeToRadian(point[1]), bearingRad = degreeToRadian(bearing), radians = lengthToRadians(distance, options.units), latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) + Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad)), longitude2 = longitude1 + Math.atan2(Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1), Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2));
|
|
35
59
|
return {
|
package/es/geo/invariant.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/geo/invariant.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../src/geo/invariant.ts"],"names":[],"mappings":"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","file":"invariant.js","sourcesContent":["/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2019 Morgan Herlocker\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of\n * this software and associated documentation files (the \"Software\"), to deal in\n * the Software without restriction, including without limitation the rights to\n * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\n * the Software, and to permit persons to whom the Software is furnished to do so,\n * subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n */\n\nimport type { Feature, MultiPolygon, Polygon, Units } from './interface';\nimport { lengthToRadians } from '@turf/helpers';\nimport { pointInRect, polygonContainPoint } from '../graphics';\nimport type { IPointLike } from '../data-structure';\nimport { degreeToRadian, radianToDegree } from '../angle';\n\n// https://github.com/Turfjs/turf\nfunction getGeom(geojson: any): any {\n if (geojson.type === 'Feature') {\n return geojson.geometry;\n }\n return geojson;\n}\n\nexport function isPointInPolygon<G extends Polygon | MultiPolygon>(point: IPointLike, polygon: Feature<G> | G) {\n if (!point) {\n return false;\n }\n\n if (!polygon) {\n return false;\n }\n\n const geom = getGeom(polygon);\n const type = geom.type;\n // BBox [west, south, east, north]\n const bbox = polygon.bbox;\n let polys: any[] = geom.coordinates;\n\n if (bbox && pointInRect(point, { x1: bbox[0], x2: bbox[1], y1: bbox[1], y2: bbox[3] }, true) === true) {\n return false;\n }\n\n if (type === 'Polygon') {\n polys = [polys];\n }\n let result = false;\n\n for (let i = 0; i < polys.length; ++i) {\n for (let j = 0; j < polys[i].length; ++j) {\n const polyResult = polygonContainPoint(\n polys[i][j].map((p: number[]) => ({ x: p[0], y: p[1] })),\n point.x,\n point.y\n );\n if (polyResult) {\n result = true;\n return result;\n }\n }\n }\n\n return result;\n}\n\n// https://github.com/Turfjs/turf\nexport function destination(\n point: IPointLike,\n distance: number,\n bearing: number,\n options: {\n units?: Units;\n } = {}\n) {\n const longitude1 = degreeToRadian(point[0]);\n const latitude1 = degreeToRadian(point[1]);\n const bearingRad = degreeToRadian(bearing);\n const radians = lengthToRadians(distance, options.units);\n\n // Main\n const latitude2 = Math.asin(\n Math.sin(latitude1) * Math.cos(radians) + Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad)\n );\n const longitude2 =\n longitude1 +\n Math.atan2(\n Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1),\n Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2)\n );\n const lng = radianToDegree(longitude2);\n const lat = radianToDegree(latitude2);\n\n return { x: lng, y: lat };\n}\n"]}
|
|
@@ -3,7 +3,9 @@ import { pointInRect } from "./intersect";
|
|
|
3
3
|
let x1, y1, x2, y2;
|
|
4
4
|
|
|
5
5
|
export function getAABBFromPoints(points) {
|
|
6
|
-
return x1 = 1 / 0, y1 = 1 / 0, x2 = -1 / 0, y2 = -1 / 0,
|
|
6
|
+
return x1 = 1 / 0, y1 = 1 / 0, x2 = -1 / 0, y2 = -1 / 0,
|
|
7
|
+
// todo 有优化空间
|
|
8
|
+
points.forEach((point => {
|
|
7
9
|
x1 > point.x && (x1 = point.x), x2 < point.x && (x2 = point.x), y1 > point.y && (y1 = point.y),
|
|
8
10
|
y2 < point.y && (y2 = point.y);
|
|
9
11
|
})), {
|
|
@@ -26,7 +28,8 @@ export function unionAABB(bounds1, bounds2, buffer = 3, format = !1) {
|
|
|
26
28
|
y12 = temp), x21 > x22 && (temp = x21, x21 = x22, x22 = temp), y21 > y22 && (temp = y21,
|
|
27
29
|
y21 = y22, y22 = temp);
|
|
28
30
|
}
|
|
29
|
-
|
|
31
|
+
// 不相交直接跳过
|
|
32
|
+
if (x11 >= x22 || x12 <= x21 || y11 >= y22 || y12 <= y21) return [ bounds1, bounds2 ];
|
|
30
33
|
const area1 = (x12 - x11 + 2 * buffer) * (y12 - y11 + 2 * buffer), area2 = (x22 - x21 + 2 * buffer) * (y22 - y21 + 2 * buffer), x1 = Math.min(x11, x21), y1 = Math.min(y11, y21), x2 = Math.max(x12, x22), y2 = Math.max(y12, y22);
|
|
31
34
|
return area1 + area2 > (x2 - x1) * (y2 - y1) ? [ {
|
|
32
35
|
x1: x1,
|
|
@@ -42,7 +45,8 @@ export function mergeAABB(boundsList) {
|
|
|
42
45
|
const l = [];
|
|
43
46
|
list.forEach((b => {
|
|
44
47
|
let arr;
|
|
45
|
-
|
|
48
|
+
// 相交
|
|
49
|
+
(arr = unionAABB(baseBound, b)).length > 1 ? l.push(b) : baseBound = arr[0];
|
|
46
50
|
})), nextList.push(baseBound), l.length && _merge(l[0], l.slice(1));
|
|
47
51
|
}(boundsList[0], boundsList.slice(1)), nextList;
|
|
48
52
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graphics/algorithm/aabb.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,IAAI,EAAU,CAAC;AACf,IAAI,EAAU,CAAC;AACf,IAAI,EAAU,CAAC;AACf,IAAI,EAAU,CAAC;AACf,MAAM,UAAU,iBAAiB,CAAC,MAAe;IAC/C,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;
|
|
1
|
+
{"version":3,"sources":["../src/graphics/algorithm/aabb.ts"],"names":[],"mappings":"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","file":"aabb.js","sourcesContent":["import type { IBoundsLike } from '../../data-structure';\nimport type { Point } from './interface';\nimport { pointInRect } from './intersect';\n\nlet x1: number;\nlet y1: number;\nlet x2: number;\nlet y2: number;\nexport function getAABBFromPoints(points: Point[]): IBoundsLike {\n (x1 = Infinity), (y1 = Infinity), (x2 = -Infinity), (y2 = -Infinity);\n // todo 有优化空间\n points.forEach(point => {\n if (x1 > point.x) {\n x1 = point.x;\n }\n if (x2 < point.x) {\n x2 = point.x;\n }\n if (y1 > point.y) {\n y1 = point.y;\n }\n if (y2 < point.y) {\n y2 = point.y;\n }\n });\n\n return { x1, y1, x2, y2 };\n}\n\nexport function pointInAABB(point: Point, aabb: IBoundsLike): boolean {\n return pointInRect(point, aabb, false);\n}\n\nexport function unionAABB(\n bounds1: IBoundsLike,\n bounds2: IBoundsLike,\n buffer = 3,\n format = false\n): [IBoundsLike, IBoundsLike?] {\n let x11 = bounds1.x1;\n let x12 = bounds1.x2;\n let y11 = bounds1.y1;\n let y12 = bounds1.y2;\n let x21 = bounds2.x1;\n let x22 = bounds2.x2;\n let y21 = bounds2.y1;\n let y22 = bounds2.y2;\n if (format) {\n let temp;\n if (x11 > x12) {\n temp = x11;\n x11 = x12;\n x12 = temp;\n }\n if (y11 > y12) {\n temp = y11;\n y11 = y12;\n y12 = temp;\n }\n if (x21 > x22) {\n temp = x21;\n x21 = x22;\n x22 = temp;\n }\n if (y21 > y22) {\n temp = y21;\n y21 = y22;\n y22 = temp;\n }\n }\n // 不相交直接跳过\n if (x11 >= x22 || x12 <= x21 || y11 >= y22 || y12 <= y21) {\n return [bounds1, bounds2];\n }\n\n const area1 = (x12 - x11 + buffer * 2) * (y12 - y11 + buffer * 2);\n const area2 = (x22 - x21 + buffer * 2) * (y22 - y21 + buffer * 2);\n const x1 = Math.min(x11, x21);\n const y1 = Math.min(y11, y21);\n const x2 = Math.max(x12, x22);\n const y2 = Math.max(y12, y22);\n const unionArea = (x2 - x1) * (y2 - y1);\n if (area1 + area2 > unionArea) {\n return [{ x1, x2, y1, y2 }];\n }\n return [bounds1, bounds2];\n}\n\nexport function mergeAABB(boundsList: IBoundsLike[]) {\n const nextList: IBoundsLike[] = [];\n function _merge(baseBound: IBoundsLike, list: IBoundsLike[]) {\n const l: IBoundsLike[] = [];\n list.forEach(b => {\n let arr: [IBoundsLike, IBoundsLike?];\n // 相交\n if ((arr = unionAABB(baseBound, b)).length > 1) {\n l.push(b);\n return;\n }\n baseBound = arr[0];\n });\n nextList.push(baseBound);\n l.length && _merge(l[0], l.slice(1));\n }\n _merge(boundsList[0], boundsList.slice(1));\n return nextList;\n}\n"]}
|
|
@@ -1,20 +1,68 @@
|
|
|
1
1
|
import type { IBoundsLike } from '../../data-structure';
|
|
2
2
|
import type { vec2 } from '../../math';
|
|
3
3
|
import type { Point } from './interface';
|
|
4
|
+
/**
|
|
5
|
+
* 判断直线是否相交,投影法
|
|
6
|
+
* @param left1
|
|
7
|
+
* @param right1
|
|
8
|
+
* @param left2
|
|
9
|
+
* @param right2
|
|
10
|
+
*/
|
|
4
11
|
export declare function isIntersect(left1: vec2, right1: vec2, left2: vec2, right2: vec2): boolean;
|
|
12
|
+
/**
|
|
13
|
+
* 获取直线交点
|
|
14
|
+
* 不相交返回false,共线返回true,相交返回交点
|
|
15
|
+
* https://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect/565282#565282
|
|
16
|
+
* @param left1
|
|
17
|
+
* @param right1
|
|
18
|
+
* @param left2
|
|
19
|
+
* @param right2
|
|
20
|
+
*/
|
|
5
21
|
export declare function getIntersectPoint(left1: vec2, right1: vec2, left2: vec2, right2: vec2): boolean | vec2;
|
|
22
|
+
/**
|
|
23
|
+
* 获取两个rect的相交部分
|
|
24
|
+
* 如果有bbox为null,返回null,如果不相交返回{x1: 0, y1: 0, x2: 0, y2: 0}
|
|
25
|
+
* @param bbox1
|
|
26
|
+
* @param bbox2
|
|
27
|
+
* @param format
|
|
28
|
+
*/
|
|
6
29
|
export declare function getRectIntersect(bbox1: IBoundsLike | null, bbox2: IBoundsLike | null, format: boolean): IBoundsLike | null;
|
|
7
30
|
export declare enum InnerBBox {
|
|
8
31
|
NONE = 0,
|
|
9
32
|
BBOX1 = 1,
|
|
10
33
|
BBOX2 = 2
|
|
11
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* 矩形是否在另一个矩形内部
|
|
37
|
+
* 返回InnerBBox
|
|
38
|
+
* @param bbox1
|
|
39
|
+
* @param bbox2
|
|
40
|
+
* @param format
|
|
41
|
+
*/
|
|
12
42
|
export declare function rectInsideAnotherRect(bbox1: IBoundsLike | null, bbox2: IBoundsLike | null, format: boolean): InnerBBox;
|
|
43
|
+
/**
|
|
44
|
+
* 两个矩形是否相交
|
|
45
|
+
* 如果有矩形为null,判断为相交
|
|
46
|
+
* @param bbox1
|
|
47
|
+
* @param bbox2
|
|
48
|
+
* @param format
|
|
49
|
+
*/
|
|
13
50
|
export declare function isRectIntersect(bbox1: IBoundsLike | null, bbox2: IBoundsLike | null, format: boolean): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* 点在box内部
|
|
53
|
+
* 如果bbox为null返回true
|
|
54
|
+
* @param point
|
|
55
|
+
* @param bbox
|
|
56
|
+
*/
|
|
14
57
|
export declare function pointInRect(point: {
|
|
15
58
|
x: number;
|
|
16
59
|
y: number;
|
|
17
60
|
}, bbox: IBoundsLike | null, format: boolean): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* 逆时针旋转矩阵(从正 x 轴开始,旋转到正 y 轴的方向)
|
|
63
|
+
* [ cos(θ) -sin(θ) ]
|
|
64
|
+
* [ sin(θ) cos(θ) ]
|
|
65
|
+
*/
|
|
18
66
|
export declare function rotatePoint({ x, y }: Point, rad: number, origin?: {
|
|
19
67
|
x: number;
|
|
20
68
|
y: number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* 用于判断2d相交 */
|
|
1
2
|
import { degreeToRadian } from "../../angle";
|
|
2
3
|
|
|
3
4
|
import { pi2, halfPi, crossProduct, fuzzyEqualVec } from "../../math";
|
|
@@ -6,7 +7,13 @@ function sub(out, v1, v2) {
|
|
|
6
7
|
out[0] = v1[0] - v2[0], out[1] = v1[1] - v2[1];
|
|
7
8
|
}
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
/**
|
|
11
|
+
* 判断直线是否相交,投影法
|
|
12
|
+
* @param left1
|
|
13
|
+
* @param right1
|
|
14
|
+
* @param left2
|
|
15
|
+
* @param right2
|
|
16
|
+
*/ export function isIntersect(left1, right1, left2, right2) {
|
|
10
17
|
let min1 = left1[0], max1 = right1[0], min2 = left2[0], max2 = right2[0];
|
|
11
18
|
return max1 < min1 && ([min1, max1] = [ max1, min1 ]), max2 < min2 && ([max2, min2] = [ min2, max2 ]),
|
|
12
19
|
!(max1 < min2 || max2 < min1) && (min1 = left1[1], max1 = right1[1], min2 = left2[1],
|
|
@@ -14,16 +21,37 @@ export function isIntersect(left1, right1, left2, right2) {
|
|
|
14
21
|
!(max1 < min2 || max2 < min1));
|
|
15
22
|
}
|
|
16
23
|
|
|
17
|
-
|
|
24
|
+
/**
|
|
25
|
+
* 获取直线交点
|
|
26
|
+
* 不相交返回false,共线返回true,相交返回交点
|
|
27
|
+
* https://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect/565282#565282
|
|
28
|
+
* @param left1
|
|
29
|
+
* @param right1
|
|
30
|
+
* @param left2
|
|
31
|
+
* @param right2
|
|
32
|
+
*/ export function getIntersectPoint(left1, right1, left2, right2) {
|
|
18
33
|
if (!isIntersect(left1, right1, left2, right2)) return !1;
|
|
19
34
|
const dir1 = [ 0, 0 ], dir2 = [ 0, 0 ], tempVec = [ 0, 0 ];
|
|
35
|
+
// 判断共线
|
|
20
36
|
if (sub(dir1, right1, left1), sub(dir2, right2, left2), fuzzyEqualVec(dir1, dir2)) return !0;
|
|
21
|
-
|
|
37
|
+
// https://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect/565282#565282
|
|
38
|
+
// line1: left1 + dir1 * t
|
|
39
|
+
// line2: left2 + dir2 * u
|
|
40
|
+
// 当 left1 + dir1 * t = left2 + dir2 * u => (left1 + dir1 * t) x dir2 = (left2 + dir2 * u) x dir2
|
|
41
|
+
// => dir1 x dir2 * t = (left2 - left1) x dir2 => t = (left2 - left1) x dir2 / (dir1 x dir2)
|
|
42
|
+
// 直线不平行,dir1 x dir2 ≠ 0,当0 <= t <= 1时,可以求出交点
|
|
43
|
+
sub(tempVec, left2, left1);
|
|
22
44
|
const t = crossProduct(tempVec, dir2) / crossProduct(dir1, dir2);
|
|
23
45
|
return t >= 0 && t <= 1 && [ left1[0] + dir1[0] * t, left1[1] + dir1[1] * t ];
|
|
24
46
|
}
|
|
25
47
|
|
|
26
|
-
|
|
48
|
+
/**
|
|
49
|
+
* 获取两个rect的相交部分
|
|
50
|
+
* 如果有bbox为null,返回null,如果不相交返回{x1: 0, y1: 0, x2: 0, y2: 0}
|
|
51
|
+
* @param bbox1
|
|
52
|
+
* @param bbox2
|
|
53
|
+
* @param format
|
|
54
|
+
*/ export function getRectIntersect(bbox1, bbox2, format) {
|
|
27
55
|
if (null === bbox1) return bbox2;
|
|
28
56
|
if (null === bbox2) return bbox1;
|
|
29
57
|
const {x11: x11, x12: x12, y11: y11, y12: y12, x21: x21, x22: x22, y21: y21, y22: y22} = formatTwoBBox(bbox1, bbox2, format);
|
|
@@ -63,13 +91,28 @@ const formatTwoBBox = (bbox1, bbox2, format) => {
|
|
|
63
91
|
};
|
|
64
92
|
};
|
|
65
93
|
|
|
66
|
-
|
|
94
|
+
/**
|
|
95
|
+
* 矩形是否在另一个矩形内部
|
|
96
|
+
* 返回InnerBBox
|
|
97
|
+
* @param bbox1
|
|
98
|
+
* @param bbox2
|
|
99
|
+
* @param format
|
|
100
|
+
*/ export function rectInsideAnotherRect(bbox1, bbox2, format) {
|
|
67
101
|
if (!bbox1 || !bbox2) return InnerBBox.NONE;
|
|
68
102
|
const {x11: x11, x12: x12, y11: y11, y12: y12, x21: x21, x22: x22, y21: y21, y22: y22} = formatTwoBBox(bbox1, bbox2, format);
|
|
69
|
-
|
|
103
|
+
// bbox1在bbox2内部
|
|
104
|
+
return x11 > x21 && x12 < x22 && y11 > y21 && y12 < y22 ? InnerBBox.BBOX1 :
|
|
105
|
+
// bbox2在bbox1内部
|
|
106
|
+
x21 > x11 && x22 < x12 && y21 > y11 && y22 < y12 ? InnerBBox.BBOX2 : InnerBBox.NONE;
|
|
70
107
|
}
|
|
71
108
|
|
|
72
|
-
|
|
109
|
+
/**
|
|
110
|
+
* 两个矩形是否相交
|
|
111
|
+
* 如果有矩形为null,判断为相交
|
|
112
|
+
* @param bbox1
|
|
113
|
+
* @param bbox2
|
|
114
|
+
* @param format
|
|
115
|
+
*/ export function isRectIntersect(bbox1, bbox2, format) {
|
|
73
116
|
if (bbox1 && bbox2) {
|
|
74
117
|
if (!format) return !(bbox1.x1 > bbox2.x2 || bbox1.x2 < bbox2.x1 || bbox1.y1 > bbox2.y2 || bbox1.y2 < bbox2.y1);
|
|
75
118
|
const {x11: x11, x12: x12, y11: y11, y12: y12, x21: x21, x22: x22, y21: y21, y22: y22} = formatTwoBBox(bbox1, bbox2, !0);
|
|
@@ -78,7 +121,12 @@ export function isRectIntersect(bbox1, bbox2, format) {
|
|
|
78
121
|
return !0;
|
|
79
122
|
}
|
|
80
123
|
|
|
81
|
-
|
|
124
|
+
/**
|
|
125
|
+
* 点在box内部
|
|
126
|
+
* 如果bbox为null返回true
|
|
127
|
+
* @param point
|
|
128
|
+
* @param bbox
|
|
129
|
+
*/ export function pointInRect(point, bbox, format) {
|
|
82
130
|
if (!bbox) return !0;
|
|
83
131
|
if (!format) return point.x >= bbox.x1 && point.x <= bbox.x2 && point.y >= bbox.y1 && point.y <= bbox.y2;
|
|
84
132
|
let x11 = bbox.x1, x12 = bbox.x2, y11 = bbox.y1, y12 = bbox.y2;
|
|
@@ -86,11 +134,20 @@ export function pointInRect(point, bbox, format) {
|
|
|
86
134
|
point.x >= x11 && point.x <= x12 && point.y >= y11 && point.y <= y12;
|
|
87
135
|
}
|
|
88
136
|
|
|
89
|
-
|
|
137
|
+
// 参考https://github.com/francecil/leetcode/issues/1
|
|
138
|
+
/**
|
|
139
|
+
* 计算投影半径
|
|
140
|
+
* @param {Array(Number)} checkAxis 检测轴 [cosθ,sinθ]
|
|
141
|
+
* @param {Array} axis 目标轴 [x,y]
|
|
142
|
+
*/ function getProjectionRadius(checkAxis, axis) {
|
|
90
143
|
return Math.abs(axis[0] * checkAxis[0] + axis[1] * checkAxis[1]);
|
|
91
144
|
}
|
|
92
145
|
|
|
93
|
-
|
|
146
|
+
/**
|
|
147
|
+
* 逆时针旋转矩阵(从正 x 轴开始,旋转到正 y 轴的方向)
|
|
148
|
+
* [ cos(θ) -sin(θ) ]
|
|
149
|
+
* [ sin(θ) cos(θ) ]
|
|
150
|
+
*/ export function rotatePoint({x: x, y: y}, rad, origin = {
|
|
94
151
|
x: 0,
|
|
95
152
|
y: 0
|
|
96
153
|
}) {
|
|
@@ -107,7 +164,10 @@ function getCenterPoint(box) {
|
|
|
107
164
|
};
|
|
108
165
|
}
|
|
109
166
|
|
|
110
|
-
|
|
167
|
+
/**
|
|
168
|
+
* 转化为顶点坐标数组
|
|
169
|
+
* @param {Object} box
|
|
170
|
+
*/ function toRect(box, isDeg) {
|
|
111
171
|
const deg = isDeg ? degreeToRadian(box.angle) : box.angle, cp = getCenterPoint(box);
|
|
112
172
|
return [ rotatePoint({
|
|
113
173
|
x: box.x1,
|
|
@@ -127,11 +187,14 @@ function toRect(box, isDeg) {
|
|
|
127
187
|
export function isRotateAABBIntersect(box1, box2, isDeg = !1) {
|
|
128
188
|
const rect1 = toRect(box1, isDeg), rect2 = toRect(box2, isDeg), vector = (start, end) => [ end.x - start.x, end.y - start.y ], vp1p2 = vector(getCenterPoint(box1), getCenterPoint(box2)), AB = vector(rect1[0], rect1[1]), BC = vector(rect1[1], rect1[2]), A1B1 = vector(rect2[0], rect2[1]), B1C1 = vector(rect2[1], rect2[2]), deg11 = isDeg ? degreeToRadian(box1.angle) : box1.angle;
|
|
129
189
|
let deg12 = isDeg ? degreeToRadian(90 - box1.angle) : box1.angle + halfPi;
|
|
130
|
-
|
|
190
|
+
// 矩形2 的两个弧度
|
|
191
|
+
const deg21 = isDeg ? degreeToRadian(box2.angle) : box2.angle;
|
|
131
192
|
let deg22 = isDeg ? degreeToRadian(90 - box2.angle) : box2.angle + halfPi;
|
|
132
193
|
deg12 > pi2 && (deg12 -= pi2), deg22 > pi2 && (deg22 -= pi2);
|
|
194
|
+
// 投影重叠
|
|
133
195
|
const isCover = (checkAxisRadius, deg, targetAxis1, targetAxis2) => {
|
|
134
196
|
const checkAxis = [ Math.cos(deg), Math.sin(deg) ];
|
|
197
|
+
// console.log('abc', `checkAxis:${checkAxis},三个投影:${checkAxisRadius}, ${targetAxisRadius}, ${centerPointRadius}`)
|
|
135
198
|
return checkAxisRadius + (getProjectionRadius(checkAxis, targetAxis1) + getProjectionRadius(checkAxis, targetAxis2)) / 2 > getProjectionRadius(checkAxis, vp1p2);
|
|
136
199
|
};
|
|
137
200
|
return isCover((box1.x2 - box1.x1) / 2, deg11, A1B1, B1C1) && isCover((box1.y2 - box1.y1) / 2, deg12, A1B1, B1C1) && isCover((box2.x2 - box2.x1) / 2, deg21, AB, BC) && isCover((box2.y2 - box2.y1) / 2, deg22, AB, BC);
|