Browse Source

1.添加标绘工具类,2.场景飞行添加间隔

tags/1.9.4
Caven Chen 5 years ago
parent
commit
135958feee

+ 3
- 2
src/core/Loader.Base.js View File

@@ -3,7 +3,7 @@
* @Date: 2020-05-09 13:19:53
*/

import { DomUtil, Util } from './utils'
import { Util, DomUtil, PlotUtil } from './utils'
import { MouseEventType, SceneEventType, Event } from './event'
import { Layer, LayerType } from './layer'
import { Overlay, OverlayType } from './overlay'
@@ -15,8 +15,9 @@ import Transform from './transform/Transform'
import Parse from './parse/Parse'

const base = {
DomUtil,
Util,
DomUtil,
PlotUtil,
State,
Event,
ImageryType,

+ 4
- 0
src/core/layer/LayerGroup.js View File

@@ -0,0 +1,4 @@
/**
* @Author: Caven
* @Date: 2020-08-27 19:50:32
*/

+ 496
- 0
src/core/utils/PlotUtil.js View File

@@ -0,0 +1,496 @@
/**
* @Author: Caven
* @Date: 2020-08-21 18:05:39
*/

const TWO_PI = Math.PI * 2
const FITTING_COUNT = 100
const ZERO_TOLERANCE = 0.0001

class PlotUtil {
/**
* @param pnt1
* @param pnt2
* @returns {number}
*/
static distance(pnt1, pnt2) {
return Math.sqrt(
Math.pow(pnt1[0] - pnt2[0], 2) + Math.pow(pnt1[1] - pnt2[1], 2)
)
}

/**
* @param points
* @returns {number}
*/
static wholeDistance(points) {
let distance = 0
for (let i = 0; i < points.length - 1; i++)
distance += this.distance(points[i], points[i + 1])
return distance
}

/**
* @param points
* @returns {number}
*/
static getBaseLength(points) {
return Math.pow(this.wholeDistance(points), 0.99)
}

/**
* @param pnt1
* @param pnt2
* @returns {number[]}
*/
static mid(pnt1, pnt2) {
return [(pnt1[0] + pnt2[0]) / 2, (pnt1[1] + pnt2[1]) / 2]
}

/**
* @param pnt1
* @param pnt2
* @param pnt3
* @returns {[*, *]|[*, *]|[*, number]}
*/
static getCircleCenterOfThreePoints(pnt1, pnt2, pnt3) {
let pntA = [(pnt1[0] + pnt2[0]) / 2, (pnt1[1] + pnt2[1]) / 2]
let pntB = [pntA[0] - pnt1[1] + pnt2[1], pntA[1] + pnt1[0] - pnt2[0]]
let pntC = [(pnt1[0] + pnt3[0]) / 2, (pnt1[1] + pnt3[1]) / 2]
let pntD = [pntC[0] - pnt1[1] + pnt3[1], pntC[1] + pnt1[0] - pnt3[0]]
return this.getIntersectPoint(pntA, pntB, pntC, pntD)
}

/**
* @param pntA
* @param pntB
* @param pntC
* @param pntD
* @returns {(*|number)[]|*[]}
*/
static getIntersectPoint(pntA, pntB, pntC, pntD) {
let x, y, f, e
if (pntA[1] === pntB[1]) {
f = (pntD[0] - pntC[0]) / (pntD[1] - pntC[1])
x = f * (pntA[1] - pntC[1]) + pntC[0]
y = pntA[1]
return [x, y]
}
if (pntC[1] === pntD[1]) {
e = (pntB[0] - pntA[0]) / (pntB[1] - pntA[1])
x = e * (pntC[1] - pntA[1]) + pntA[0]
y = pntC[1]
return [x, y]
}
e = (pntB[0] - pntA[0]) / (pntB[1] - pntA[1])
f = (pntD[0] - pntC[0]) / (pntD[1] - pntC[1])
y = (e * pntA[1] - pntA[0] - f * pntC[1] + pntC[0]) / (e - f)
x = e * y - e * pntA[1] + pntA[0]
return [x, y]
}

/**
* @param startPnt
* @param endPnt
* @returns {number}
*/
static getAzimuth(startPnt, endPnt) {
let azimuth
let angle = Math.asin(
Math.abs(endPnt[1] - startPnt[1]) / this.distance(startPnt, endPnt)
)
if (endPnt[1] >= startPnt[1] && endPnt[0] >= startPnt[0])
azimuth = angle + Math.PI
else if (endPnt[1] >= startPnt[1] && endPnt[0] < startPnt[0])
azimuth = TWO_PI - angle
else if (endPnt[1] < startPnt[1] && endPnt[0] < startPnt[0]) azimuth = angle
else if (endPnt[1] < startPnt[1] && endPnt[0] >= startPnt[0])
azimuth = Math.PI - angle
return azimuth
}

/**
* @param pntA
* @param pntB
* @param pntC
* @returns {number}
*/
static getAngleOfThreePoints(pntA, pntB, pntC) {
let angle = this.getAzimuth(pntB, pntA) - this.getAzimuth(pntB, pntC)
return angle < 0 ? angle + TWO_PI : angle
}

/**
* @param pnt1
* @param pnt2
* @param pnt3
* @returns {boolean}
*/
static isClockWise(pnt1, pnt2, pnt3) {
return (
(pnt3[1] - pnt1[1]) * (pnt2[0] - pnt1[0]) >
(pnt2[1] - pnt1[1]) * (pnt3[0] - pnt1[0])
)
}

/**
* @param t
* @param startPnt
* @param endPnt
* @returns {*[]}
*/
static getPointOnLine(t, startPnt, endPnt) {
let x = startPnt[0] + t * (endPnt[0] - startPnt[0])
let y = startPnt[1] + t * (endPnt[1] - startPnt[1])
return [x, y]
}

/**
* @param t
* @param startPnt
* @param cPnt1
* @param cPnt2
* @param endPnt
* @returns {number[]}
*/
static getCubicValue(t, startPnt, cPnt1, cPnt2, endPnt) {
t = Math.max(Math.min(t, 1), 0)
let tp = 1 - t
let t2 = t * t
let t3 = t2 * t
let tp2 = tp * tp
let tp3 = tp2 * tp
let x =
tp3 * startPnt[0] +
3 * tp2 * t * cPnt1[0] +
3 * tp * t2 * cPnt2[0] +
t3 * endPnt[0]
let y =
tp3 * startPnt[1] +
3 * tp2 * t * cPnt1[1] +
3 * tp * t2 * cPnt2[1] +
t3 * endPnt[1]
return [x, y]
}

/**
* @param startPnt
* @param endPnt
* @param angle
* @param distance
* @param clockWise
* @returns {*[]}
*/
static getThirdPoint(startPnt, endPnt, angle, distance, clockWise) {
let azimuth = this.getAzimuth(startPnt, endPnt)
let alpha = clockWise ? azimuth + angle : azimuth - angle
let dx = distance * Math.cos(alpha)
let dy = distance * Math.sin(alpha)
return [endPnt[0] + dx, endPnt[1] + dy]
}

/**
* @param center
* @param radius
* @param startAngle
* @param endAngle
* @returns {[]}
*/
static getArcPoints(center, radius, startAngle, endAngle) {
let x,
y,
pnts = []
let angleDiff = endAngle - startAngle
angleDiff = angleDiff < 0 ? angleDiff + TWO_PI : angleDiff
for (let i = 0; i <= FITTING_COUNT; i++) {
let angle = startAngle + (angleDiff * i) / FITTING_COUNT
x = center[0] + radius * Math.cos(angle)
y = center[1] + radius * Math.sin(angle)
pnts.push([x, y])
}
return pnts
}

/**
* @param t
* @param pnt1
* @param pnt2
* @param pnt3
* @returns {*[][]}
*/
static getBisectorNormals(t, pnt1, pnt2, pnt3) {
let normal = this.getNormal(pnt1, pnt2, pnt3)
let dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1])
let uX = normal[0] / dist
let uY = normal[1] / dist
let d1 = this.distance(pnt1, pnt2)
let d2 = this.distance(pnt2, pnt3)
let dt, x, y, bisectorNormalLeft, bisectorNormalRight
if (dist > ZERO_TOLERANCE) {
if (this.isClockWise(pnt1, pnt2, pnt3)) {
dt = t * d1
x = pnt2[0] - dt * uY
y = pnt2[1] + dt * uX
bisectorNormalRight = [x, y]
dt = t * d2
x = pnt2[0] + dt * uY
y = pnt2[1] - dt * uX
bisectorNormalLeft = [x, y]
} else {
dt = t * d1
x = pnt2[0] + dt * uY
y = pnt2[1] - dt * uX
bisectorNormalRight = [x, y]
dt = t * d2
x = pnt2[0] - dt * uY
y = pnt2[1] + dt * uX
bisectorNormalLeft = [x, y]
}
} else {
x = pnt2[0] + t * (pnt1[0] - pnt2[0])
y = pnt2[1] + t * (pnt1[1] - pnt2[1])
bisectorNormalRight = [x, y]
x = pnt2[0] + t * (pnt3[0] - pnt2[0])
y = pnt2[1] + t * (pnt3[1] - pnt2[1])
bisectorNormalLeft = [x, y]
}
return [bisectorNormalRight, bisectorNormalLeft]
}

/**
* @param pnt1
* @param pnt2
* @param pnt3
* @returns {number[]}
*/
static getNormal(pnt1, pnt2, pnt3) {
let dX1 = pnt1[0] - pnt2[0]
let dY1 = pnt1[1] - pnt2[1]
let d1 = Math.sqrt(dX1 * dX1 + dY1 * dY1)
dX1 /= d1
dY1 /= d1

let dX2 = pnt3[0] - pnt2[0]
let dY2 = pnt3[1] - pnt2[1]
let d2 = Math.sqrt(dX2 * dX2 + dY2 * dY2)
dX2 /= d2
dY2 /= d2

let uX = dX1 + dX2
let uY = dY1 + dY2
return [uX, uY]
}

/**
* @param t
* @param controlPoints
* @returns {[]}
*/
static getCurvePoints(t, controlPoints) {
let leftControl = this.getLeftMostControlPoint(t, controlPoints)
let normals = [leftControl]
let pnt1, pnt2, pnt3, normalPoints
for (let i = 0; i < controlPoints.length - 2; i++) {
pnt1 = controlPoints[i]
pnt2 = controlPoints[i + 1]
pnt3 = controlPoints[i + 2]
normalPoints = this.getBisectorNormals(t, pnt1, pnt2, pnt3)
normals = normals.concat(normalPoints)
}
let rightControl = this.getRightMostControlPoint(t, controlPoints)
normals.push(rightControl)
let points = []
for (let i = 0; i < controlPoints.length - 1; i++) {
pnt1 = controlPoints[i]
pnt2 = controlPoints[i + 1]
points.push(pnt1)
for (let t = 0; t < FITTING_COUNT; t++) {
let pnt = this.getCubicValue(
t / FITTING_COUNT,
pnt1,
normals[i * 2],
normals[i * 2 + 1],
pnt2
)
points.push(pnt)
}
points.push(pnt2)
}
return points
}

/**
* @param t
* @param controlPoints
* @returns {number[]}
*/
static getLeftMostControlPoint(t, controlPoints) {
let pnt1 = controlPoints[0]
let pnt2 = controlPoints[1]
let pnt3 = controlPoints[2]
let pnts = this.getBisectorNormals(0, pnt1, pnt2, pnt3)
let normalRight = pnts[0]
let normal = this.getNormal(pnt1, pnt2, pnt3)
let dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1])
let controlX, controlY
if (dist > ZERO_TOLERANCE) {
let mid = this.mid(pnt1, pnt2)
let pX = pnt1[0] - mid[0]
let pY = pnt1[1] - mid[1]
let d1 = this.distance(pnt1, pnt2)
// normal at midpoint
let n = 2.0 / d1
let nX = -n * pY
let nY = n * pX
// upper triangle of symmetric transform matrix
let a11 = nX * nX - nY * nY
let a12 = 2 * nX * nY
let a22 = nY * nY - nX * nX
let dX = normalRight[0] - mid[0]
let dY = normalRight[1] - mid[1]
// coordinates of reflected vector
controlX = mid[0] + a11 * dX + a12 * dY
controlY = mid[1] + a12 * dX + a22 * dY
} else {
controlX = pnt1[0] + t * (pnt2[0] - pnt1[0])
controlY = pnt1[1] + t * (pnt2[1] - pnt1[1])
}
return [controlX, controlY]
}

/**
* @param t
* @param controlPoints
* @returns {number[]}
*/
static getRightMostControlPoint(t, controlPoints) {
let count = controlPoints.length
let pnt1 = controlPoints[count - 3]
let pnt2 = controlPoints[count - 2]
let pnt3 = controlPoints[count - 1]
let pnts = this.getBisectorNormals(0, pnt1, pnt2, pnt3)
let normalLeft = pnts[1]
let normal = this.getNormal(pnt1, pnt2, pnt3)
let dist = Math.sqrt(normal[0] * normal[0] + normal[1] * normal[1])
let controlX, controlY
if (dist > ZERO_TOLERANCE) {
let mid = this.mid(pnt2, pnt3)
let pX = pnt3[0] - mid[0]
let pY = pnt3[1] - mid[1]

let d1 = this.distance(pnt2, pnt3)
// normal at midpoint
let n = 2.0 / d1
let nX = -n * pY
let nY = n * pX

// upper triangle of symmetric transform matrix
let a11 = nX * nX - nY * nY
let a12 = 2 * nX * nY
let a22 = nY * nY - nX * nX

let dX = normalLeft[0] - mid[0]
let dY = normalLeft[1] - mid[1]

// coordinates of reflected vector
controlX = mid[0] + a11 * dX + a12 * dY
controlY = mid[1] + a12 * dX + a22 * dY
} else {
controlX = pnt3[0] + t * (pnt2[0] - pnt3[0])
controlY = pnt3[1] + t * (pnt2[1] - pnt3[1])
}
return [controlX, controlY]
}

/**
* @param points
* @returns {[]|*}
*/
static getBezierPoints(points) {
if (points.length <= 2) return points
let bezierPoints = []
let n = points.length - 1
for (let t = 0; t <= 1; t += 0.01) {
let x = 0
let y = 0
for (let index = 0; index <= n; index++) {
let factor = this.getBinomialFactor(n, index)
let a = Math.pow(t, index)
let b = Math.pow(1 - t, n - index)
x += factor * a * b * points[index][0]
y += factor * a * b * points[index][1]
}
bezierPoints.push([x, y])
}
bezierPoints.push(points[n])
return bezierPoints
}

/**
*
* @param n
* @param index
* @returns {number}
*/
static getBinomialFactor(n, index) {
return (
this.getFactorial(n) /
(this.getFactorial(index) * this.getFactorial(n - index))
)
}

/**
* @param n
* @returns {number}
*/
static getFactorial(n) {
if (n <= 1) return 1
if (n === 2) return 2
if (n === 3) return 6
if (n === 4) return 24
if (n === 5) return 120
let result = 1
for (let i = 1; i <= n; i++) result *= i
return result
}

/**
* @param points
* @returns {[]|*}
*/
static getQBSplinePoints(points) {
if (points.length <= 2) return points
let n = 2
let bSplinePoints = []
let m = points.length - n - 1
bSplinePoints.push(points[0])
for (let i = 0; i <= m; i++) {
for (let t = 0; t <= 1; t += 0.05) {
let x = 0
let y = 0
for (let k = 0; k <= n; k++) {
let factor = this.getQuadricBSplineFactor(k, t)
x += factor * points[i + k][0]
y += factor * points[i + k][1]
}
bSplinePoints.push([x, y])
}
}
bSplinePoints.push(points[points.length - 1])
return bSplinePoints
}

/**
* @param k
* @param t
* @returns {number}
*/
static getQuadricBSplineFactor(k, t) {
if (k === 0) return Math.pow(t - 1, 2) / 2
if (k === 1) return (-2 * Math.pow(t, 2) + 2 * t + 1) / 2
if (k === 2) return Math.pow(t, 2) / 2
return 0
}
}

export default PlotUtil

+ 2
- 2
src/core/utils/index.js View File

@@ -2,6 +2,6 @@
* @Author: Caven
* @Date: 2020-01-06 16:38:49
*/

export { default as DomUtil } from './DomUtil'
export { default as Util } from './Util'
export { default as DomUtil } from './DomUtil'
export { default as PlotUtil } from './PlotUtil'

+ 5
- 2
src/core/viewer/Viewer.js View File

@@ -475,10 +475,13 @@ class Viewer {

/**
* @param target
* @param duration
* @returns {Viewer}
*/
flyTo(target) {
this._delegate.flyTo(target?.delegate || target)
flyTo(target, duration) {
this._delegate.flyTo(target?.delegate || target, {
duration
})
return this
}


Loading…
Cancel
Save