vislite 0.7.0 → 0.7.1-alpha.0
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/CHANGELOG +177 -171
- package/README.md +135 -135
- package/lib/Buffer/index.umd.js +2 -2
- package/lib/Buffer/index.umd.min.js +2 -2
- package/lib/Canvas/index.umd.js +2 -2
- package/lib/Canvas/index.umd.min.js +2 -2
- package/lib/Cardinal/index.umd.js +2 -2
- package/lib/Cardinal/index.umd.min.js +2 -2
- package/lib/Eoap/index.umd.js +2 -2
- package/lib/Eoap/index.umd.min.js +2 -2
- package/lib/Geometry/index.umd.js +2 -2
- package/lib/Geometry/index.umd.min.js +2 -2
- package/lib/Hermite/index.umd.js +2 -2
- package/lib/Hermite/index.umd.min.js +2 -2
- package/lib/Matrix4/index.umd.js +2 -2
- package/lib/Matrix4/index.umd.min.js +2 -2
- package/lib/Mercator/index.umd.js +2 -2
- package/lib/Mercator/index.umd.min.js +2 -2
- package/lib/OralCanvas/index.es.js +2 -2
- package/lib/OralCanvas/index.es.min.js +2 -2
- package/lib/OralWebGL/index.es.js +2 -3
- package/lib/OralWebGL/index.es.min.js +3 -3
- package/lib/SVG/index.umd.js +2 -2
- package/lib/SVG/index.umd.min.js +2 -2
- package/lib/Shader/index.umd.js +2 -3
- package/lib/Shader/index.umd.min.js +3 -3
- package/lib/Texture/index.umd.js +2 -2
- package/lib/Texture/index.umd.min.js +2 -2
- package/lib/TreeLayout/index.umd.js +2 -2
- package/lib/TreeLayout/index.umd.min.js +2 -2
- package/lib/WebGL/index.umd.js +2 -3
- package/lib/WebGL/index.umd.min.js +3 -3
- package/lib/animation/index.umd.js +2 -2
- package/lib/animation/index.umd.min.js +2 -2
- package/lib/formatColor/index.umd.js +2 -2
- package/lib/formatColor/index.umd.min.js +2 -2
- package/lib/getLoopColors/index.umd.js +2 -2
- package/lib/getLoopColors/index.umd.min.js +2 -2
- package/lib/getWebGLContext/index.umd.js +2 -2
- package/lib/getWebGLContext/index.umd.min.js +2 -2
- package/lib/index.umd.js +2 -3
- package/lib/index.umd.min.js +3 -3
- package/lib/move/index.umd.js +2 -2
- package/lib/move/index.umd.min.js +2 -2
- package/lib/resizeObserver/index.umd.js +2 -2
- package/lib/resizeObserver/index.umd.min.js +2 -2
- package/lib/rotate/index.umd.js +2 -2
- package/lib/rotate/index.umd.min.js +2 -2
- package/lib/ruler/index.umd.js +2 -2
- package/lib/ruler/index.umd.min.js +2 -2
- package/lib/scale/index.umd.js +2 -2
- package/lib/scale/index.umd.min.js +2 -2
- package/lib/throttle/index.umd.js +2 -2
- package/lib/throttle/index.umd.min.js +2 -2
- package/lib/viewHandler/index.umd.js +2 -2
- package/lib/viewHandler/index.umd.min.js +2 -2
- package/package.json +70 -70
- package/src/Canvas.ts +70 -70
- package/src/Geometry.ts +126 -126
- package/src/Matrix4/rotate.ts +15 -15
- package/src/Matrix4/transform.ts +64 -64
- package/src/WebGL.ts +66 -66
- package/src/common/assemble.ts +22 -22
- package/src/common/canvas/index.ts +177 -177
- package/src/common/canvas/painter.ts +419 -419
- package/src/common/geometry/prism-vertical.ts +40 -40
- package/src/common/geometry/tool/rotateLine.ts +35 -35
- package/src/common/setStyle.ts +5 -5
- package/src/common/svg/config.ts +190 -190
- package/src/common/svg/index.ts +356 -356
- package/src/common/svg/tool.ts +44 -44
- package/src/common/tree/toInnerTree.ts +59 -59
- package/src/common/tree/toPlainTree.ts +132 -132
- package/src/common/webgl/buffer.ts +79 -79
- package/src/common/webgl/doDraw.ts +108 -108
- package/src/common/webgl/getWebGLContext.ts +28 -28
- package/src/common/webgl/index.ts +226 -226
- package/src/common/webgl/shader.ts +75 -75
- package/src/common/webgl/texture.ts +97 -97
- package/src/layout/TreeLayout.ts +188 -188
- package/src/resizeObserver.ts +37 -37
- package/src/ruler.ts +209 -209
- package/src/viewHandler.ts +160 -160
- package/types/Canvas.d.ts +308 -308
- package/types/Geometry.d.ts +65 -65
- package/types/Object3D.d.ts +1 -1
- package/types/SVGConfig.d.ts +79 -79
- package/types/Shader.d.ts +2 -0
- package/types/TreeConfig.d.ts +36 -36
- package/uni-app/ui-canvas.vue +237 -237
package/package.json
CHANGED
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "vislite",
|
|
3
|
-
"version": "0.7.0",
|
|
4
|
-
"description": "灵活、快速、简单的数据可视化交互式跨端前端库",
|
|
5
|
-
"main": "./lib/index.umd.min.js",
|
|
6
|
-
"typings": "./types/index.d.ts",
|
|
7
|
-
"unpkg": "./lib/index.umd.min.js",
|
|
8
|
-
"sideEffects": false,
|
|
9
|
-
"scripts": {
|
|
10
|
-
"dev": "webpack serve --config ./build/webpack.config.js",
|
|
11
|
-
"build": "devby --delete ./lib && node ./build/pkg.js",
|
|
12
|
-
"test": "karma start ./build/karma.config.js",
|
|
13
|
-
"lint": "eslint src/**/*.{js,ts} --fix"
|
|
14
|
-
},
|
|
15
|
-
"miniprogram": ".",
|
|
16
|
-
"repository": {
|
|
17
|
-
"type": "git",
|
|
18
|
-
"url": "git+https://github.com/oi-contrib/VISLite.git"
|
|
19
|
-
},
|
|
20
|
-
"keywords": [
|
|
21
|
-
"svg",
|
|
22
|
-
"webgl",
|
|
23
|
-
"typescript",
|
|
24
|
-
"canvas",
|
|
25
|
-
"vue",
|
|
26
|
-
"uniapp",
|
|
27
|
-
"miniprogram",
|
|
28
|
-
"image2d",
|
|
29
|
-
"image3d",
|
|
30
|
-
"oi-contrib",
|
|
31
|
-
"vislite",
|
|
32
|
-
"d3",
|
|
33
|
-
"zxl20070701",
|
|
34
|
-
"three",
|
|
35
|
-
"echarts",
|
|
36
|
-
"datav",
|
|
37
|
-
"webgpu",
|
|
38
|
-
"layout",
|
|
39
|
-
"algorithm"
|
|
40
|
-
],
|
|
41
|
-
"author": {
|
|
42
|
-
"name": "zxl20070701",
|
|
43
|
-
"url": "https://zxl20070701.github.io/notebook/home.html"
|
|
44
|
-
},
|
|
45
|
-
"license": "MIT",
|
|
46
|
-
"bugs": {
|
|
47
|
-
"url": "https://github.com/oi-contrib/VISLite/issues"
|
|
48
|
-
},
|
|
49
|
-
"homepage": "https://oi-contrib.github.io/VISLite",
|
|
50
|
-
"devDependencies": {
|
|
51
|
-
"@rollup/plugin-typescript": "^11.1.0",
|
|
52
|
-
"@types/jasmine": "^4.3.1",
|
|
53
|
-
"@typescript-eslint/eslint-plugin": "^6.14.0",
|
|
54
|
-
"@typescript-eslint/parser": "^6.14.0",
|
|
55
|
-
"devby": "^0.4.6",
|
|
56
|
-
"eslint": "^8.56.0",
|
|
57
|
-
"karma": "^6.3.10",
|
|
58
|
-
"karma-chrome-launcher": "^3.1.0",
|
|
59
|
-
"karma-jasmine": "^4.0.1",
|
|
60
|
-
"karma-webpack": "^5.0.0",
|
|
61
|
-
"rollup": "^3.20.6",
|
|
62
|
-
"terser": "^5.17.1",
|
|
63
|
-
"ts-loader": "^9.2.8",
|
|
64
|
-
"tslib": "^2.5.0",
|
|
65
|
-
"typescript": "^4.6.2",
|
|
66
|
-
"webpack": "^5.70.0",
|
|
67
|
-
"webpack-cli": "^4.9.2",
|
|
68
|
-
"webpack-dev-server": "^4.7.4"
|
|
69
|
-
}
|
|
70
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "vislite",
|
|
3
|
+
"version": "0.7.1-alpha.0",
|
|
4
|
+
"description": "灵活、快速、简单的数据可视化交互式跨端前端库",
|
|
5
|
+
"main": "./lib/index.umd.min.js",
|
|
6
|
+
"typings": "./types/index.d.ts",
|
|
7
|
+
"unpkg": "./lib/index.umd.min.js",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "webpack serve --config ./build/webpack.config.js",
|
|
11
|
+
"build": "devby --delete ./lib && node ./build/pkg.js",
|
|
12
|
+
"test": "karma start ./build/karma.config.js",
|
|
13
|
+
"lint": "eslint src/**/*.{js,ts} --fix"
|
|
14
|
+
},
|
|
15
|
+
"miniprogram": ".",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/oi-contrib/VISLite.git"
|
|
19
|
+
},
|
|
20
|
+
"keywords": [
|
|
21
|
+
"svg",
|
|
22
|
+
"webgl",
|
|
23
|
+
"typescript",
|
|
24
|
+
"canvas",
|
|
25
|
+
"vue",
|
|
26
|
+
"uniapp",
|
|
27
|
+
"miniprogram",
|
|
28
|
+
"image2d",
|
|
29
|
+
"image3d",
|
|
30
|
+
"oi-contrib",
|
|
31
|
+
"vislite",
|
|
32
|
+
"d3",
|
|
33
|
+
"zxl20070701",
|
|
34
|
+
"three",
|
|
35
|
+
"echarts",
|
|
36
|
+
"datav",
|
|
37
|
+
"webgpu",
|
|
38
|
+
"layout",
|
|
39
|
+
"algorithm"
|
|
40
|
+
],
|
|
41
|
+
"author": {
|
|
42
|
+
"name": "zxl20070701",
|
|
43
|
+
"url": "https://zxl20070701.github.io/notebook/home.html"
|
|
44
|
+
},
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"bugs": {
|
|
47
|
+
"url": "https://github.com/oi-contrib/VISLite/issues"
|
|
48
|
+
},
|
|
49
|
+
"homepage": "https://oi-contrib.github.io/VISLite",
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@rollup/plugin-typescript": "^11.1.0",
|
|
52
|
+
"@types/jasmine": "^4.3.1",
|
|
53
|
+
"@typescript-eslint/eslint-plugin": "^6.14.0",
|
|
54
|
+
"@typescript-eslint/parser": "^6.14.0",
|
|
55
|
+
"devby": "^0.4.6",
|
|
56
|
+
"eslint": "^8.56.0",
|
|
57
|
+
"karma": "^6.3.10",
|
|
58
|
+
"karma-chrome-launcher": "^3.1.0",
|
|
59
|
+
"karma-jasmine": "^4.0.1",
|
|
60
|
+
"karma-webpack": "^5.0.0",
|
|
61
|
+
"rollup": "^3.20.6",
|
|
62
|
+
"terser": "^5.17.1",
|
|
63
|
+
"ts-loader": "^9.2.8",
|
|
64
|
+
"tslib": "^2.5.0",
|
|
65
|
+
"typescript": "^4.6.2",
|
|
66
|
+
"webpack": "^5.70.0",
|
|
67
|
+
"webpack-cli": "^4.9.2",
|
|
68
|
+
"webpack-dev-server": "^4.7.4"
|
|
69
|
+
}
|
|
70
|
+
}
|
package/src/Canvas.ts
CHANGED
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
import type CanvasType from '../types/Canvas'
|
|
2
|
-
import type CanvasOptionType from '../types/CanvasOption'
|
|
3
|
-
|
|
4
|
-
import OralCanvas from './common/canvas/index'
|
|
5
|
-
import mergeOption from './common/mergeOption'
|
|
6
|
-
|
|
7
|
-
class Canvas extends OralCanvas implements CanvasType {
|
|
8
|
-
private __canvas: HTMLCanvasElement
|
|
9
|
-
constructor(el: HTMLElement | null, option: CanvasOptionType = {}) {
|
|
10
|
-
if (!el) {
|
|
11
|
-
throw new Error("VISLite Canvas:The mount point requires an HTMLElement type but encountered null.")
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
option = mergeOption(option, {
|
|
15
|
-
region: true,
|
|
16
|
-
willReadFrequently: false
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
const width = el.clientWidth, height = el.clientHeight
|
|
20
|
-
|
|
21
|
-
let ViewCanvas: HTMLCanvasElement, RegionCanvas: HTMLCanvasElement | null = null
|
|
22
|
-
|
|
23
|
-
const _el = el as any
|
|
24
|
-
|
|
25
|
-
// 如果已经初始化过了
|
|
26
|
-
if (_el._vislite_canvas_) {
|
|
27
|
-
ViewCanvas = _el._vislite_canvas_[0]
|
|
28
|
-
RegionCanvas = _el._vislite_canvas_[1]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// 否则就初始化
|
|
32
|
-
else {
|
|
33
|
-
ViewCanvas = document.createElement('canvas')
|
|
34
|
-
el.appendChild(ViewCanvas)
|
|
35
|
-
|
|
36
|
-
if (option.region) {
|
|
37
|
-
RegionCanvas = document.createElement('canvas')
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
_el._vislite_canvas_ = [ViewCanvas, RegionCanvas]
|
|
41
|
-
|
|
42
|
-
el.setAttribute('vislite', 'Canvas')
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// 设置画布大小
|
|
46
|
-
for (const canvas of [ViewCanvas, RegionCanvas]) {
|
|
47
|
-
|
|
48
|
-
if (canvas) {
|
|
49
|
-
canvas.style.width = width + "px"
|
|
50
|
-
canvas.setAttribute('width', width + "")
|
|
51
|
-
|
|
52
|
-
canvas.style.height = height + "px"
|
|
53
|
-
canvas.setAttribute('height', height + "")
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
super(ViewCanvas, RegionCanvas, {
|
|
58
|
-
willReadFrequently: option.willReadFrequently
|
|
59
|
-
})
|
|
60
|
-
|
|
61
|
-
this.__canvas = ViewCanvas
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
toDataURL(): Promise<string> {
|
|
65
|
-
return new Promise(resolve => {
|
|
66
|
-
resolve(this.__canvas.toDataURL())
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
1
|
+
import type CanvasType from '../types/Canvas'
|
|
2
|
+
import type CanvasOptionType from '../types/CanvasOption'
|
|
3
|
+
|
|
4
|
+
import OralCanvas from './common/canvas/index'
|
|
5
|
+
import mergeOption from './common/mergeOption'
|
|
6
|
+
|
|
7
|
+
class Canvas extends OralCanvas implements CanvasType {
|
|
8
|
+
private __canvas: HTMLCanvasElement
|
|
9
|
+
constructor(el: HTMLElement | null, option: CanvasOptionType = {}) {
|
|
10
|
+
if (!el) {
|
|
11
|
+
throw new Error("VISLite Canvas:The mount point requires an HTMLElement type but encountered null.")
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
option = mergeOption(option, {
|
|
15
|
+
region: true,
|
|
16
|
+
willReadFrequently: false
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
const width = el.clientWidth, height = el.clientHeight
|
|
20
|
+
|
|
21
|
+
let ViewCanvas: HTMLCanvasElement, RegionCanvas: HTMLCanvasElement | null = null
|
|
22
|
+
|
|
23
|
+
const _el = el as any
|
|
24
|
+
|
|
25
|
+
// 如果已经初始化过了
|
|
26
|
+
if (_el._vislite_canvas_) {
|
|
27
|
+
ViewCanvas = _el._vislite_canvas_[0]
|
|
28
|
+
RegionCanvas = _el._vislite_canvas_[1]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// 否则就初始化
|
|
32
|
+
else {
|
|
33
|
+
ViewCanvas = document.createElement('canvas')
|
|
34
|
+
el.appendChild(ViewCanvas)
|
|
35
|
+
|
|
36
|
+
if (option.region) {
|
|
37
|
+
RegionCanvas = document.createElement('canvas')
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
_el._vislite_canvas_ = [ViewCanvas, RegionCanvas]
|
|
41
|
+
|
|
42
|
+
el.setAttribute('vislite', 'Canvas')
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// 设置画布大小
|
|
46
|
+
for (const canvas of [ViewCanvas, RegionCanvas]) {
|
|
47
|
+
|
|
48
|
+
if (canvas) {
|
|
49
|
+
canvas.style.width = width + "px"
|
|
50
|
+
canvas.setAttribute('width', width + "")
|
|
51
|
+
|
|
52
|
+
canvas.style.height = height + "px"
|
|
53
|
+
canvas.setAttribute('height', height + "")
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
super(ViewCanvas, RegionCanvas, {
|
|
58
|
+
willReadFrequently: option.willReadFrequently
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
this.__canvas = ViewCanvas
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
toDataURL(): Promise<string> {
|
|
65
|
+
return new Promise(resolve => {
|
|
66
|
+
resolve(this.__canvas.toDataURL())
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
71
|
export default Canvas
|
package/src/Geometry.ts
CHANGED
|
@@ -1,127 +1,127 @@
|
|
|
1
|
-
import type GeometryType from "../types/Geometry"
|
|
2
|
-
import type GeometryOptionType from "../types/GeometryOption"
|
|
3
|
-
import type GeometryResultType from "../types/GeometryResult"
|
|
4
|
-
|
|
5
|
-
type rotateLineType = (x0: number, y0: number, z0: number, isNormal: boolean) => Array<number>
|
|
6
|
-
|
|
7
|
-
import { splitNum } from './common/geometry/tool/circle'
|
|
8
|
-
import prismHorizontal from './common/geometry/prism-horizontal'
|
|
9
|
-
import prismVertical from './common/geometry/prism-vertical'
|
|
10
|
-
import sphereFragment from './common/geometry/sphere-fragment'
|
|
11
|
-
import mergeOption from './common/mergeOption'
|
|
12
|
-
import rotateLineFactory from "./common/geometry/tool/rotateLine"
|
|
13
|
-
|
|
14
|
-
class Geometry implements GeometryType {
|
|
15
|
-
readonly name: string = 'Geometry'
|
|
16
|
-
|
|
17
|
-
private __option: GeometryOptionType
|
|
18
|
-
|
|
19
|
-
constructor(option: GeometryOptionType = {}) {
|
|
20
|
-
this.__option = mergeOption(option, {
|
|
21
|
-
precision: 0.1, // 精度
|
|
22
|
-
normal: false, // 是否需要法向量
|
|
23
|
-
})
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
config(option: GeometryOptionType) {
|
|
27
|
-
for (const key in option) {
|
|
28
|
-
this.__option[key] = option[key]
|
|
29
|
-
}
|
|
30
|
-
return this
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// 圆柱体
|
|
34
|
-
cylinder(x: number, y: number, z: number, radius: number, x2: number, y2?: number, z2?: number): Array<GeometryResultType> {
|
|
35
|
-
|
|
36
|
-
// 求解出需要切割多少份比较合理
|
|
37
|
-
const num = splitNum(this.__option.precision as number, radius)
|
|
38
|
-
|
|
39
|
-
if (arguments.length == 5) {
|
|
40
|
-
return this.prism(x, y, z, radius, x2, num)
|
|
41
|
-
} else {
|
|
42
|
-
return this.prism(x, y, z, radius, x2, y2 as number, z2, num)
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// 棱柱体
|
|
47
|
-
prism(x: number, y: number, z: number, radius: number, x2: number, y2: number, z2?: number, num?: number): Array<GeometryResultType> {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
let height: number, rotateLine: rotateLineType | null = null
|
|
51
|
-
|
|
52
|
-
if (arguments.length == 6) {
|
|
53
|
-
height = x2
|
|
54
|
-
num = y2
|
|
55
|
-
} else {
|
|
56
|
-
height = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y) + (z2 as number - z) * (z2 as number - z))
|
|
57
|
-
rotateLine = rotateLineFactory(x, y, z, x2, y2, z2 as number)
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const result = [{
|
|
61
|
-
name: "bottom",
|
|
62
|
-
points: [],
|
|
63
|
-
length: 0,
|
|
64
|
-
method: "TRIANGLES" as const
|
|
65
|
-
}, {
|
|
66
|
-
name: "top",
|
|
67
|
-
points: [],
|
|
68
|
-
length: 0,
|
|
69
|
-
method: "TRIANGLES" as const
|
|
70
|
-
}, {
|
|
71
|
-
name: "side",
|
|
72
|
-
points: [],
|
|
73
|
-
length: 0,
|
|
74
|
-
method: "TRIANGLES" as const
|
|
75
|
-
}]
|
|
76
|
-
|
|
77
|
-
// 绘制底部的盖子
|
|
78
|
-
; (result[0].points as Array<number>).push(...prismHorizontal(this.__option.normal as boolean, x, y, z, radius, num as number, height > 0 ? -1 : 1))
|
|
79
|
-
|
|
80
|
-
// 绘制顶部的盖子
|
|
81
|
-
; (result[1].points as Array<number>).push(...prismHorizontal(this.__option.normal as boolean, x, y + height, z, radius, num as number, height > 0 ? 1 : -1))
|
|
82
|
-
|
|
83
|
-
// 绘制侧边部分
|
|
84
|
-
; (result[2].points as Array<number>).push(...prismVertical(this.__option.normal as boolean, x, y, z, radius, height, num as number))
|
|
85
|
-
|
|
86
|
-
for (let i = 0; i < result.length; i++) {
|
|
87
|
-
if (rotateLine) {
|
|
88
|
-
|
|
89
|
-
const points = []
|
|
90
|
-
let isNormal = false
|
|
91
|
-
for (let index = 0; index < result[i].points.length; index += 3) {
|
|
92
|
-
points.push(...rotateLine(result[i].points[index], result[i].points[index + 1], result[i].points[index + 2], (this.__option.normal as boolean) && isNormal))
|
|
93
|
-
isNormal = !isNormal
|
|
94
|
-
}
|
|
95
|
-
(result[i].points as Array<number>) = points
|
|
96
|
-
}
|
|
97
|
-
result[i].length = result[i].points.length / (this.__option.normal ? 6 : 3)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
return result
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// 球体
|
|
104
|
-
sphere(cx: number, cy: number, cz: number, radius: number): Array<GeometryResultType> {
|
|
105
|
-
|
|
106
|
-
// 求解出需要切割多少份比较合理
|
|
107
|
-
const num = splitNum(this.__option.precision as number, radius)
|
|
108
|
-
|
|
109
|
-
// 然后一瓣瓣的绘制
|
|
110
|
-
const result = [{
|
|
111
|
-
name: "surface",
|
|
112
|
-
points: [],
|
|
113
|
-
length: 0,
|
|
114
|
-
method: "TRIANGLES" as const
|
|
115
|
-
}]
|
|
116
|
-
for (let i = 0; i < num; i++) {
|
|
117
|
-
; (result[0].points as Array<number>).push(...sphereFragment(this.__option.normal as boolean, cx, cy, cz, radius, num, i))
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
result[0].length = result[0].points.length / (this.__option.normal ? 6 : 3)
|
|
121
|
-
|
|
122
|
-
return result
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
|
|
1
|
+
import type GeometryType from "../types/Geometry"
|
|
2
|
+
import type GeometryOptionType from "../types/GeometryOption"
|
|
3
|
+
import type GeometryResultType from "../types/GeometryResult"
|
|
4
|
+
|
|
5
|
+
type rotateLineType = (x0: number, y0: number, z0: number, isNormal: boolean) => Array<number>
|
|
6
|
+
|
|
7
|
+
import { splitNum } from './common/geometry/tool/circle'
|
|
8
|
+
import prismHorizontal from './common/geometry/prism-horizontal'
|
|
9
|
+
import prismVertical from './common/geometry/prism-vertical'
|
|
10
|
+
import sphereFragment from './common/geometry/sphere-fragment'
|
|
11
|
+
import mergeOption from './common/mergeOption'
|
|
12
|
+
import rotateLineFactory from "./common/geometry/tool/rotateLine"
|
|
13
|
+
|
|
14
|
+
class Geometry implements GeometryType {
|
|
15
|
+
readonly name: string = 'Geometry'
|
|
16
|
+
|
|
17
|
+
private __option: GeometryOptionType
|
|
18
|
+
|
|
19
|
+
constructor(option: GeometryOptionType = {}) {
|
|
20
|
+
this.__option = mergeOption(option, {
|
|
21
|
+
precision: 0.1, // 精度
|
|
22
|
+
normal: false, // 是否需要法向量
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
config(option: GeometryOptionType) {
|
|
27
|
+
for (const key in option) {
|
|
28
|
+
this.__option[key] = option[key]
|
|
29
|
+
}
|
|
30
|
+
return this
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// 圆柱体
|
|
34
|
+
cylinder(x: number, y: number, z: number, radius: number, x2: number, y2?: number, z2?: number): Array<GeometryResultType> {
|
|
35
|
+
|
|
36
|
+
// 求解出需要切割多少份比较合理
|
|
37
|
+
const num = splitNum(this.__option.precision as number, radius)
|
|
38
|
+
|
|
39
|
+
if (arguments.length == 5) {
|
|
40
|
+
return this.prism(x, y, z, radius, x2, num)
|
|
41
|
+
} else {
|
|
42
|
+
return this.prism(x, y, z, radius, x2, y2 as number, z2, num)
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// 棱柱体
|
|
47
|
+
prism(x: number, y: number, z: number, radius: number, x2: number, y2: number, z2?: number, num?: number): Array<GeometryResultType> {
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
let height: number, rotateLine: rotateLineType | null = null
|
|
51
|
+
|
|
52
|
+
if (arguments.length == 6) {
|
|
53
|
+
height = x2
|
|
54
|
+
num = y2
|
|
55
|
+
} else {
|
|
56
|
+
height = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y) + (z2 as number - z) * (z2 as number - z))
|
|
57
|
+
rotateLine = rotateLineFactory(x, y, z, x2, y2, z2 as number)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const result = [{
|
|
61
|
+
name: "bottom",
|
|
62
|
+
points: [],
|
|
63
|
+
length: 0,
|
|
64
|
+
method: "TRIANGLES" as const
|
|
65
|
+
}, {
|
|
66
|
+
name: "top",
|
|
67
|
+
points: [],
|
|
68
|
+
length: 0,
|
|
69
|
+
method: "TRIANGLES" as const
|
|
70
|
+
}, {
|
|
71
|
+
name: "side",
|
|
72
|
+
points: [],
|
|
73
|
+
length: 0,
|
|
74
|
+
method: "TRIANGLES" as const
|
|
75
|
+
}]
|
|
76
|
+
|
|
77
|
+
// 绘制底部的盖子
|
|
78
|
+
; (result[0].points as Array<number>).push(...prismHorizontal(this.__option.normal as boolean, x, y, z, radius, num as number, height > 0 ? -1 : 1))
|
|
79
|
+
|
|
80
|
+
// 绘制顶部的盖子
|
|
81
|
+
; (result[1].points as Array<number>).push(...prismHorizontal(this.__option.normal as boolean, x, y + height, z, radius, num as number, height > 0 ? 1 : -1))
|
|
82
|
+
|
|
83
|
+
// 绘制侧边部分
|
|
84
|
+
; (result[2].points as Array<number>).push(...prismVertical(this.__option.normal as boolean, x, y, z, radius, height, num as number))
|
|
85
|
+
|
|
86
|
+
for (let i = 0; i < result.length; i++) {
|
|
87
|
+
if (rotateLine) {
|
|
88
|
+
|
|
89
|
+
const points = []
|
|
90
|
+
let isNormal = false
|
|
91
|
+
for (let index = 0; index < result[i].points.length; index += 3) {
|
|
92
|
+
points.push(...rotateLine(result[i].points[index], result[i].points[index + 1], result[i].points[index + 2], (this.__option.normal as boolean) && isNormal))
|
|
93
|
+
isNormal = !isNormal
|
|
94
|
+
}
|
|
95
|
+
(result[i].points as Array<number>) = points
|
|
96
|
+
}
|
|
97
|
+
result[i].length = result[i].points.length / (this.__option.normal ? 6 : 3)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return result
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// 球体
|
|
104
|
+
sphere(cx: number, cy: number, cz: number, radius: number): Array<GeometryResultType> {
|
|
105
|
+
|
|
106
|
+
// 求解出需要切割多少份比较合理
|
|
107
|
+
const num = splitNum(this.__option.precision as number, radius)
|
|
108
|
+
|
|
109
|
+
// 然后一瓣瓣的绘制
|
|
110
|
+
const result = [{
|
|
111
|
+
name: "surface",
|
|
112
|
+
points: [],
|
|
113
|
+
length: 0,
|
|
114
|
+
method: "TRIANGLES" as const
|
|
115
|
+
}]
|
|
116
|
+
for (let i = 0; i < num; i++) {
|
|
117
|
+
; (result[0].points as Array<number>).push(...sphereFragment(this.__option.normal as boolean, cx, cy, cz, radius, num, i))
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
result[0].length = result[0].points.length / (this.__option.normal ? 6 : 3)
|
|
121
|
+
|
|
122
|
+
return result
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
}
|
|
126
|
+
|
|
127
127
|
export default Geometry
|
package/src/Matrix4/rotate.ts
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 围绕OZ轴旋转
|
|
3
|
-
* 其它的旋转可以借助transform实现
|
|
4
|
-
* 旋转角度单位采用弧度制
|
|
5
|
-
*/
|
|
6
|
-
export default function (deg: number) {
|
|
7
|
-
const sin = Math.sin(deg),
|
|
8
|
-
cos = Math.cos(deg)
|
|
9
|
-
return [
|
|
10
|
-
cos, sin, 0, 0,
|
|
11
|
-
-sin, cos, 0, 0,
|
|
12
|
-
0, 0, 1, 0,
|
|
13
|
-
0, 0, 0, 1
|
|
14
|
-
]
|
|
15
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* 围绕OZ轴旋转
|
|
3
|
+
* 其它的旋转可以借助transform实现
|
|
4
|
+
* 旋转角度单位采用弧度制
|
|
5
|
+
*/
|
|
6
|
+
export default function (deg: number) {
|
|
7
|
+
const sin = Math.sin(deg),
|
|
8
|
+
cos = Math.cos(deg)
|
|
9
|
+
return [
|
|
10
|
+
cos, sin, 0, 0,
|
|
11
|
+
-sin, cos, 0, 0,
|
|
12
|
+
0, 0, 1, 0,
|
|
13
|
+
0, 0, 0, 1
|
|
14
|
+
]
|
|
15
|
+
}
|