@gitborlando/geo 4.1.0 → 5.1.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/src/obb.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { AABB } from './aabb'
2
2
  import { Angle } from './angle'
3
3
  import { IRect, IXY } from './types'
4
- import { XY, xy_, xy_dot, xy_minus, xy_rotate } from './xy'
4
+ import { XY } from './xy'
5
5
 
6
6
  type IAxis = { widthAxis: IXY; heightAxis: IXY }
7
7
 
@@ -25,19 +25,18 @@ export class OBB {
25
25
  }
26
26
 
27
27
  get xy() {
28
- return xy_(this.x, this.y)
28
+ return XY.$(this.x, this.y)
29
29
  }
30
30
 
31
31
  #calcCenter = () => {
32
- const center = xy_(this.x + this.width / 2, this.y + this.height / 2)
33
- return xy_rotate(center, xy_(this.x, this.y), this.rotation)
32
+ const center = XY.center(this)
33
+ return center.rotate(this.xy, this.rotation)
34
34
  }
35
35
 
36
36
  #calcAxis = () => {
37
- const cos = Angle.cos(this.rotation)
38
- const sin = Angle.sin(this.rotation)
39
- const widthAxis = xy_(cos, -sin)
40
- const heightAxis = xy_(sin, cos)
37
+ const { cos, sin } = Angle.cosSin(this.rotation)
38
+ const widthAxis = XY.$(cos, -sin)
39
+ const heightAxis = XY.$(sin, cos)
41
40
  return (this.axis = { widthAxis, heightAxis })
42
41
  }
43
42
 
@@ -48,10 +47,10 @@ export class OBB {
48
47
  const sinWidth = sin * this.width
49
48
  const cosHeight = cos * this.height
50
49
  const sinHeight = sin * this.height
51
- const TL = xy_(this.x, this.y)
52
- const TR = xy_(this.x + cosWidth, this.y + sinWidth)
53
- const BR = xy_(this.x + cosWidth - sinHeight, this.y + sinWidth + cosHeight)
54
- const BL = xy_(this.x - sinHeight, this.y + cosHeight)
50
+ const TL = XY.$(this.x, this.y)
51
+ const TR = XY.$(this.x + cosWidth, this.y + sinWidth)
52
+ const BR = XY.$(this.x + cosWidth - sinHeight, this.y + sinWidth + cosHeight)
53
+ const BL = XY.$(this.x - sinHeight, this.y + cosHeight)
55
54
  return (this.vertexes = [TL, TR, BR, BL])
56
55
  }
57
56
 
@@ -59,34 +58,34 @@ export class OBB {
59
58
  return new OBB(this.x, this.y, this.width, this.height, this.rotation)
60
59
  }
61
60
 
62
- projectionLengthAt = (anotherAxis: IXY) => {
61
+ projectAt = (anotherAxis: IXY) => {
63
62
  const { widthAxis, heightAxis } = this.axis
64
63
  return (
65
- Math.abs(xy_dot(widthAxis, anotherAxis)) * this.width +
66
- Math.abs(xy_dot(heightAxis, anotherAxis)) * this.height
64
+ Math.abs(XY.dot(widthAxis, anotherAxis)) * this.width +
65
+ Math.abs(XY.dot(heightAxis, anotherAxis)) * this.height
67
66
  )
68
67
  }
69
68
 
70
69
  collide = (another: OBB) => {
71
- const centerVector = xy_minus(this.center, another.center)
70
+ const centerVector = XY.vector(this.center, another.center)
72
71
  if (
73
- this.projectionLengthAt(another.axis.widthAxis) + another.width <=
74
- 2 * Math.abs(xy_dot(centerVector, another.axis.widthAxis))
72
+ this.projectAt(another.axis.widthAxis) + another.width <=
73
+ 2 * Math.abs(XY.dot(centerVector, another.axis.widthAxis))
75
74
  )
76
75
  return false
77
76
  if (
78
- this.projectionLengthAt(another.axis.heightAxis) + another.height <=
79
- 2 * Math.abs(xy_dot(centerVector, another.axis.heightAxis))
77
+ this.projectAt(another.axis.heightAxis) + another.height <=
78
+ 2 * Math.abs(XY.dot(centerVector, another.axis.heightAxis))
80
79
  )
81
80
  return false
82
81
  if (
83
- another.projectionLengthAt(this.axis.widthAxis) + this.width <=
84
- 2 * Math.abs(xy_dot(centerVector, this.axis.widthAxis))
82
+ another.projectAt(this.axis.widthAxis) + this.width <=
83
+ 2 * Math.abs(XY.dot(centerVector, this.axis.widthAxis))
85
84
  )
86
85
  return false
87
86
  if (
88
- another.projectionLengthAt(this.axis.heightAxis) + this.height <=
89
- 2 * Math.abs(xy_dot(centerVector, this.axis.heightAxis))
87
+ another.projectAt(this.axis.heightAxis) + this.height <=
88
+ 2 * Math.abs(XY.dot(centerVector, this.axis.heightAxis))
90
89
  )
91
90
  return false
92
91
  return true
@@ -104,7 +103,7 @@ export class OBB {
104
103
  static fromCenter(center: IXY, width: number, height: number, rotation = 0) {
105
104
  const dx = center.x - width / 2
106
105
  const dy = center.y - height / 2
107
- const xy = XY.of(dx, dy).rotate(center, rotation)
106
+ const xy = XY.from(dx, dy).rotate(center, rotation)
108
107
  return new OBB(xy.x, xy.y, width, height, rotation)
109
108
  }
110
109
 
package/src/xy.ts CHANGED
@@ -1,108 +1,13 @@
1
1
  import { Angle } from './angle'
2
- import { sqrt } from './math'
3
2
  import { IXY } from './types'
4
3
 
5
- export function xy_(x: number = 0, y: number = 0) {
6
- return { x, y }
7
- }
8
-
9
- export function xy_client(e: any) {
10
- return { x: e.clientX, y: e.clientY }
11
- }
12
-
13
- export function xy_from(xy: IXY) {
14
- return { x: xy.x, y: xy.y }
15
- }
16
-
17
- export function xy_center(xy: { centerX: number; centerY: number }) {
18
- return { x: xy.centerX, y: xy.centerY }
19
- }
20
-
21
- export function xy_mutate(self: IXY, another: IXY) {
22
- self.x = another.x
23
- self.y = another.y
24
- }
25
-
26
- export function xy_plus(self: IXY, another: IXY) {
27
- return { x: self.x + another.x, y: self.y + another.y }
28
- }
29
- export function xy_plus_mutate(self: IXY, another: IXY) {
30
- self.x = self.x + another.x
31
- self.y = self.y + another.y
32
- }
33
- export function xy_plus_all(...xys: IXY[]) {
34
- return xys.reduce((a, b) => xy_plus(a, b))
35
- }
36
-
37
- export function xy_minus(self: IXY, another: IXY) {
38
- return { x: self.x - another.x, y: self.y - another.y }
39
- }
40
- export function xy_minus_mutate(self: IXY, another: IXY) {
41
- self.x = self.x - another.x
42
- self.y = self.y - another.y
43
- }
44
-
45
- export function xy_multiply(self: IXY, ...numbers: number[]) {
46
- const n = numbers.reduce((a, b) => a * b, 1)
47
- return { x: self.x * n, y: self.y * n }
48
- }
49
- export function xy_multiply_mutate(self: IXY, ...numbers: number[]) {
50
- const n = numbers.reduce((a, b) => a * b, 1)
51
- self.x = self.x * n
52
- self.y = self.y * n
53
- }
54
-
55
- export function xy_divide(self: IXY, ...numbers: number[]) {
56
- const n = numbers.reduce((a, b) => a * b, 1)
57
- return { x: self.x / n, y: self.y / n }
58
- }
59
-
60
- export function xy_distance(self: IXY, another: IXY = xy_(0, 0)) {
61
- return Math.sqrt((self.x - another.x) ** 2 + (self.y - another.y) ** 2)
62
- }
63
-
64
- export function xy_rotate(self: IXY, origin: IXY, rotation: number) {
65
- if (rotation === 0) return self
66
- return Angle.rotatePoint(self.x, self.y, origin.x, origin.y, rotation)
67
- }
68
-
69
- export function xy_dot(self: IXY, another: IXY) {
70
- return self.x * another.x + self.y * another.y
71
- }
72
-
73
- export function xy_symmetric(self: IXY, origin: IXY) {
74
- return { x: 2 * origin.x - self.x, y: 2 * origin.y - self.y }
75
- }
76
-
77
- export function xy_opposite(self: IXY) {
78
- return { x: -self.x, y: -self.y }
79
- }
80
-
81
- export function xy_getRotation(self: IXY, another: IXY, origin: IXY) {
82
- return Angle.angleFy(
83
- Math.atan2(self.y - origin.y, self.x - origin.x) -
84
- Math.atan2(another.y - origin.y, another.x - origin.x),
85
- )
86
- }
87
-
88
- export function xy_toArray(self: IXY) {
89
- return [self.x, self.y] as [number, number]
90
- }
91
-
92
- export function xy_xAxis(rotation: number) {
93
- return { x: Angle.cos(rotation), y: Angle.sin(rotation) }
94
- }
95
-
96
- export function xy_yAxis(rotation: number) {
97
- return { x: -Angle.sin(rotation), y: Angle.cos(rotation) }
98
- }
99
-
100
4
  export class XY {
101
5
  constructor(
102
6
  public x: number,
103
7
  public y: number,
104
8
  ) {}
105
- plain() {
9
+
10
+ $() {
106
11
  return { x: this.x, y: this.y }
107
12
  }
108
13
 
@@ -111,91 +16,107 @@ export class XY {
111
16
  }
112
17
 
113
18
  plus(...others: IXY[]) {
114
- const x = others.reduce((sum, cur) => sum + cur.x, this.x)
115
- const y = others.reduce((sum, cur) => sum + cur.y, this.y)
116
- return XY.of(x, y)
19
+ this.x = others.reduce((sum, cur) => sum + cur.x, this.x)
20
+ this.y = others.reduce((sum, cur) => sum + cur.y, this.y)
21
+ return this
22
+ }
23
+
24
+ plusNum(num: number) {
25
+ this.x += num
26
+ this.y += num
27
+ return this
117
28
  }
118
29
 
119
30
  minus(...others: IXY[]) {
120
- const x = others.reduce((sum, cur) => sum - cur.x, this.x)
121
- const y = others.reduce((sum, cur) => sum - cur.y, this.y)
122
- return XY.of(x, y)
31
+ this.x = others.reduce((sum, cur) => sum - cur.x, this.x)
32
+ this.y = others.reduce((sum, cur) => sum - cur.y, this.y)
33
+ return this
123
34
  }
124
35
 
125
36
  multiply(...numbers: number[]) {
126
37
  const n = numbers.reduce((a, b) => a * b, 1)
127
- return XY.of(this.x * n, this.y * n)
38
+ this.x *= n
39
+ this.y *= n
40
+ return this
41
+ }
42
+
43
+ multiplyNum(num: number) {
44
+ this.x *= num
45
+ this.y *= num
46
+ return this
128
47
  }
129
48
 
130
49
  divide(...numbers: number[]) {
131
50
  const n = numbers.reduce((a, b) => a * b, 1)
132
- return XY.of(this.x / n, this.y / n)
51
+ this.x /= n
52
+ this.y /= n
53
+ return this
133
54
  }
134
55
 
135
56
  rotate(origin: IXY, rotation: number) {
136
- if (rotation === 0) return XY.from(this)
137
- return XY.from(Angle.rotatePoint(this.x, this.y, origin.x, origin.y, rotation))
138
- }
139
-
140
- symmetric(origin: IXY) {
141
- return XY.of(2 * origin.x - this.x, 2 * origin.y - this.y)
57
+ const { cos, sin } = Angle.cosSin(rotation)
58
+ const dx = this.x - origin.x
59
+ const dy = this.y - origin.y
60
+ this.x = dx * cos - dy * sin + origin.x
61
+ this.y = dx * sin + dy * cos + origin.y
62
+ return this
142
63
  }
143
64
 
144
- ratio(another: IXY, t: number) {
145
- const x = this.x + (another.x - this.x) * t
146
- const y = this.y + (another.y - this.y) * t
147
- return XY.of(x, y)
65
+ static $(x = 0, y = 0) {
66
+ return { x, y }
148
67
  }
149
68
 
150
- getDot(another: IXY) {
151
- return this.x * another.x + this.y * another.y
69
+ static of(xy: IXY) {
70
+ return new XY(xy.x, xy.y)
152
71
  }
153
72
 
154
- getDistance(another: IXY) {
155
- return sqrt((this.x - another.x) ** 2 + (this.y - another.y) ** 2)
73
+ static from(x: number, y: number) {
74
+ return new XY(x, y)
156
75
  }
157
76
 
158
- getAngle(another: IXY, origin: IXY) {
159
- return Angle.angleFy(
160
- Math.atan2(this.y - origin.y, this.x - origin.x) -
161
- Math.atan2(another.y - origin.y, another.x - origin.x),
162
- )
77
+ static center(wh: { width: number; height: number }) {
78
+ return new XY(wh.width / 2, wh.height / 2)
163
79
  }
164
80
 
165
- static _(x: number = 0, y: number = 0) {
166
- return { x, y }
81
+ static leftTop(e: { left: number; top: number }) {
82
+ return new XY(e.left, e.top)
167
83
  }
168
84
 
169
- static of(x: number, y: number) {
170
- return new XY(x, y)
85
+ static client(e: { clientX: number; clientY: number }) {
86
+ return new XY(e.clientX, e.clientY)
171
87
  }
172
88
 
173
- static from(xy: IXY) {
174
- if (xy instanceof XY) return xy
175
- return XY.of(xy.x, xy.y)
89
+ static xAxis(rotation: number = 0) {
90
+ const { cos, sin } = Angle.cosSin(rotation)
91
+ return new XY(cos, sin)
176
92
  }
177
93
 
178
- static center(xy: { centerX: number; centerY: number }) {
179
- return XY.of(xy.centerX, xy.centerY)
94
+ static yAxis(rotation: number = 0) {
95
+ const { cos, sin } = Angle.cosSin(rotation)
96
+ return new XY(-sin, cos)
180
97
  }
181
98
 
182
- static leftTop(e: { left: number; top: number }) {
183
- return XY.of(e.left, e.top)
99
+ static dot(self: IXY, another: IXY) {
100
+ return self.x * another.x + self.y * another.y
184
101
  }
185
102
 
186
- static client(e: { clientX: number; clientY: number }) {
187
- return XY.of(e.clientX, e.clientY)
103
+ static distance(self: IXY, another: IXY) {
104
+ return Math.hypot(self.x - another.x, self.y - another.y)
188
105
  }
189
106
 
190
- static tuple(arr: [number, number]) {
191
- return XY.of(arr[0], arr[1])
107
+ static vector(self: IXY, another: IXY) {
108
+ return new XY(self.x - another.x, self.y - another.y)
192
109
  }
193
110
 
194
- static xAxis(rotation: number) {
195
- return XY.of(Angle.cos(rotation), Angle.sin(rotation))
111
+ static symmetric(self: IXY, origin = XY.$()) {
112
+ return new XY(2 * origin.x - self.x, 2 * origin.y - self.y)
196
113
  }
197
114
 
198
- static yAxis(rotation: number) {
199
- return XY.of(-Angle.sin(rotation), Angle.cos(rotation))
115
+ static lerp(self: IXY, origin: IXY, t: number) {
116
+ const distance = XY.distance(self, origin)
117
+ return new XY(
118
+ self.x + (self.x - origin.x) * (t / distance),
119
+ self.y + (self.y - origin.y) * (t / distance),
120
+ )
200
121
  }
201
122
  }
@@ -1,36 +0,0 @@
1
- name: 发布包
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
-
8
- jobs:
9
- publish:
10
- runs-on: ubuntu-latest
11
-
12
- steps:
13
- - name: 检出代码
14
- uses: actions/checkout@v4
15
-
16
- - name: 设置 Node.js
17
- uses: actions/setup-node@v4
18
- with:
19
- node-version: '20'
20
- registry-url: 'https://registry.npmjs.org'
21
-
22
- - name: 安装 pnpm
23
- uses: pnpm/action-setup@v2
24
- with:
25
- version: 8
26
-
27
- - name: 安装依赖
28
- run: pnpm install
29
-
30
- - name: 构建项目
31
- run: pnpm build
32
-
33
- - name: 发布到 npm
34
- run: pnpm publish --no-git-checks
35
- env:
36
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
@@ -1,44 +0,0 @@
1
- name: Release
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
-
8
- jobs:
9
- release:
10
- name: Release
11
- runs-on: ubuntu-latest
12
- steps:
13
- - name: Checkout
14
- uses: actions/checkout@v3
15
- with:
16
- fetch-depth: 0
17
-
18
- - name: Setup Node.js
19
- uses: actions/setup-node@v3
20
- with:
21
- node-version: 20
22
-
23
- - name: Setup PNPM
24
- uses: pnpm/action-setup@v2
25
- with:
26
- version: 8
27
-
28
- - name: Install Dependencies
29
- run: pnpm install
30
-
31
- # 添加构建步骤
32
- - name: Build Packages
33
- run: pnpm build
34
-
35
- - name: Create Release Pull Request or Publish
36
- id: changeset
37
- uses: changesets/action@v1
38
- with:
39
- publish: pnpm changeset publish
40
- commit: 'chore: version packages'
41
- title: 'chore: version packages'
42
- env:
43
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
package/.husky/pre-commit DELETED
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env sh
2
-
3
- npx pretty-quick --staged
@@ -1,3 +0,0 @@
1
- {
2
- "cSpell.words": ["aabb"]
3
- }
@@ -1,84 +0,0 @@
1
- // 测试轴对齐包围盒功能
2
-
3
- import { describe, expect, it } from 'vitest'
4
- import { AABB } from '../aabb'
5
- import { OBB } from '../obb'
6
-
7
- describe('AABB', () => {
8
- it('should create AABB correctly', () => {
9
- const aabb = new AABB(0, 0, 10, 10)
10
- expect(aabb.minX).toBe(0)
11
- expect(aabb.minY).toBe(0)
12
- expect(aabb.maxX).toBe(10)
13
- expect(aabb.maxY).toBe(10)
14
- })
15
-
16
- it('should convert to rect correctly', () => {
17
- const aabb = new AABB(5, 10, 15, 25)
18
- const rect = AABB.rect(aabb)
19
- expect(rect.x).toBe(5)
20
- expect(rect.y).toBe(10)
21
- expect(rect.width).toBe(10)
22
- expect(rect.height).toBe(15)
23
- expect(rect.centerX).toBe(10)
24
- expect(rect.centerY).toBe(17.5)
25
- })
26
-
27
- it('should detect collision correctly', () => {
28
- const aabb1 = new AABB(0, 0, 10, 10)
29
- const aabb2 = new AABB(5, 5, 15, 15)
30
- const aabb3 = new AABB(20, 20, 30, 30)
31
-
32
- expect(AABB.collide(aabb1, aabb2)).toBe(true)
33
- expect(AABB.collide(aabb1, aabb3)).toBe(false)
34
- })
35
-
36
- it('should detect inclusion correctly', () => {
37
- const large = new AABB(0, 0, 20, 20)
38
- const small = new AABB(5, 5, 15, 15)
39
- const outside = new AABB(25, 25, 35, 35)
40
-
41
- expect(AABB.include(large, small)).toBe(1) // large包含small
42
- expect(AABB.include(small, large)).toBe(0) // small被large包含
43
- expect(AABB.include(large, outside)).toBe(-1) // 不包含
44
- })
45
-
46
- it('should expand correctly with single value', () => {
47
- const aabb = new AABB(5, 5, 15, 15)
48
- const expanded = AABB.extend(aabb, 2)
49
- expect(expanded.minX).toBe(3)
50
- expect(expanded.minY).toBe(3)
51
- expect(expanded.maxX).toBe(17)
52
- expect(expanded.maxY).toBe(17)
53
- })
54
-
55
- it('should expand correctly with four values', () => {
56
- const aabb = new AABB(5, 5, 15, 15)
57
- const expanded = AABB.extend(aabb, 1, 2, 3, 4)
58
- expect(expanded.minX).toBe(4)
59
- expect(expanded.minY).toBe(3)
60
- expect(expanded.maxX).toBe(18)
61
- expect(expanded.maxY).toBe(19)
62
- })
63
-
64
- it('should merge multiple AABBs correctly', () => {
65
- const aabb1 = new AABB(0, 0, 5, 5)
66
- const aabb2 = new AABB(10, 10, 15, 15)
67
- const aabb3 = new AABB(-5, -5, 0, 0)
68
-
69
- const merged = AABB.merge(aabb1, aabb2, aabb3)
70
- expect(merged.minX).toBe(-5)
71
- expect(merged.minY).toBe(-5)
72
- expect(merged.maxX).toBe(15)
73
- expect(merged.maxY).toBe(15)
74
- })
75
-
76
- it('should create from OBB correctly', () => {
77
- const obb = new OBB(0, 0, 10, 20, 0)
78
- const aabb = AABB.fromOBB(obb)
79
- expect(aabb.minX).toBe(0)
80
- expect(aabb.minY).toBe(0)
81
- expect(aabb.maxX).toBe(10)
82
- expect(aabb.maxY).toBe(20)
83
- })
84
- })
@@ -1,58 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { Angle, PI } from '../angle'
3
-
4
- describe('Angle', () => {
5
- it('should export PI constant correctly', () => {
6
- expect(PI).toBe(Math.PI)
7
- })
8
-
9
- it('should calculate cosine correctly', () => {
10
- expect(Angle.cos(0)).toBe(1)
11
- expect(Angle.cos(90)).toBeCloseTo(0, 10)
12
- expect(Angle.cos(180)).toBeCloseTo(-1, 10)
13
- })
14
-
15
- it('should calculate sine correctly', () => {
16
- expect(Angle.sin(0)).toBe(0)
17
- expect(Angle.sin(90)).toBeCloseTo(1, 10)
18
- expect(Angle.sin(180)).toBeCloseTo(0, 10)
19
- })
20
-
21
- it('should calculate tangent correctly', () => {
22
- expect(Angle.tan(0)).toBe(0)
23
- expect(Angle.tan(45)).toBeCloseTo(1, 10)
24
- })
25
-
26
- it('should convert radians to degrees correctly', () => {
27
- expect(Angle.angleFy(Math.PI)).toBe(180)
28
- expect(Angle.angleFy(Math.PI / 2)).toBe(90)
29
- expect(Angle.angleFy(0)).toBe(0)
30
- })
31
-
32
- it('should convert degrees to radians correctly', () => {
33
- expect(Angle.radianFy(180)).toBe(Math.PI)
34
- expect(Angle.radianFy(90)).toBe(Math.PI / 2)
35
- expect(Angle.radianFy(0)).toBe(0)
36
- })
37
-
38
- it('should normalize angles correctly', () => {
39
- expect(Angle.normal(370)).toBe(10)
40
- expect(Angle.normal(-10)).toBe(350)
41
- expect(Angle.normal(0)).toBe(0)
42
- })
43
-
44
- it('should snap angles to steps correctly', () => {
45
- expect(Angle.snap(45)).toBe(90) // 45度四舍五入到90度
46
- expect(Angle.snap(80)).toBe(90)
47
- expect(Angle.snap(120)).toBe(90)
48
- expect(Angle.snap(135)).toBe(180)
49
- expect(Angle.snap(0)).toBe(0)
50
- expect(Angle.snap(30)).toBe(0) // 30度四舍五入到0度
51
- })
52
-
53
- it('should rotate point correctly', () => {
54
- const result = Angle.rotatePoint(1, 0, 0, 0, 90)
55
- expect(result.x).toBeCloseTo(0, 10)
56
- expect(result.y).toBeCloseTo(1, 10)
57
- })
58
- })
@@ -1,85 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import * as Geo from '../index'
3
-
4
- describe('Index exports', () => {
5
- it('should export all modules correctly', () => {
6
- // 验证AABB相关导出
7
- expect(typeof Geo.AABB).toBe('function')
8
-
9
- // 验证Angle相关导出
10
- expect(typeof Geo.Angle).toBe('function')
11
- expect(typeof Geo.PI).toBe('number')
12
-
13
- // 验证数学函数导出
14
- expect(typeof Geo.sqrt).toBe('function')
15
- expect(typeof Geo.abs).toBe('function')
16
- expect(typeof Geo.pow2).toBe('function')
17
- expect(typeof Geo.pow3).toBe('function')
18
- expect(typeof Geo.multiply).toBe('function')
19
- expect(typeof Geo.divide).toBe('function')
20
- expect(typeof Geo.numberHalfFix).toBe('function')
21
-
22
- // 验证Matrix相关导出
23
- expect(typeof Geo.Matrix).toBe('function')
24
-
25
- // 验证OBB相关导出
26
- expect(typeof Geo.OBB).toBe('function')
27
-
28
- // 验证贝塞尔曲线相关导出
29
- expect(typeof Geo.pointsOnBezierCurves).toBe('function')
30
- expect(typeof Geo.simplify).toBe('function')
31
- expect(typeof Geo.simplifyPoints).toBe('function')
32
-
33
- // 验证XY相关导出
34
- expect(typeof Geo.xy_).toBe('function')
35
- expect(typeof Geo.xy_client).toBe('function')
36
- expect(typeof Geo.xy_from).toBe('function')
37
- expect(typeof Geo.xy_plus).toBe('function')
38
- expect(typeof Geo.xy_minus).toBe('function')
39
- expect(typeof Geo.xy_multiply).toBe('function')
40
- expect(typeof Geo.xy_divide).toBe('function')
41
- expect(typeof Geo.xy_distance).toBe('function')
42
- expect(typeof Geo.xy_dot).toBe('function')
43
- expect(typeof Geo.XY).toBe('function')
44
- })
45
-
46
- it('should export type interfaces', () => {
47
- // 验证可以使用导出的类型
48
- const point: Geo.IXY = { x: 10, y: 20 }
49
- const rect: Geo.IRect = { x: 0, y: 0, width: 100, height: 50 }
50
- const rectWithCenter: Geo.IRectWithCenter = {
51
- x: 0,
52
- y: 0,
53
- width: 100,
54
- height: 50,
55
- centerX: 50,
56
- centerY: 25,
57
- }
58
-
59
- expect(point.x).toBe(10)
60
- expect(rect.width).toBe(100)
61
- expect(rectWithCenter.centerX).toBe(50)
62
- })
63
-
64
- it('should allow creating instances from exported classes', () => {
65
- // 测试能够创建实例
66
- const aabb = new Geo.AABB(0, 0, 10, 10)
67
- const obb = new Geo.OBB(0, 0, 10, 10, 0)
68
- const xy = new Geo.XY(5, 5)
69
-
70
- expect(aabb.minX).toBe(0)
71
- expect(obb.width).toBe(10)
72
- expect(xy.x).toBe(5)
73
- })
74
-
75
- it('should allow using static methods from exported classes', () => {
76
- // 测试静态方法
77
- const matrix = Geo.Matrix.create()
78
- const normalizedAngle = Geo.Angle.normal(370)
79
- const distance = Geo.xy_distance({ x: 0, y: 0 }, { x: 3, y: 4 })
80
-
81
- expect(matrix).toEqual([1, 0, 0, 1, 0, 0])
82
- expect(normalizedAngle).toBe(10)
83
- expect(distance).toBe(5)
84
- })
85
- })