@quenty/convexhull 4.9.1 → 4.9.2
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.md
CHANGED
|
@@ -3,6 +3,17 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [4.9.2](https://github.com/Quenty/NevermoreEngine/compare/@quenty/convexhull@4.9.1...@quenty/convexhull@4.9.2) (2025-04-05)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Add types to packages ([2374fb2](https://github.com/Quenty/NevermoreEngine/commit/2374fb2b043cfbe0e9b507b3316eec46a4e353a0))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
6
17
|
## [4.9.1](https://github.com/Quenty/NevermoreEngine/compare/@quenty/convexhull@4.9.0...@quenty/convexhull@4.9.1) (2025-03-21)
|
|
7
18
|
|
|
8
19
|
**Note:** Version bump only for package @quenty/convexhull
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quenty/convexhull",
|
|
3
|
-
"version": "4.9.
|
|
3
|
+
"version": "4.9.2",
|
|
4
4
|
"description": "Convex hull computation algorithms",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Roblox",
|
|
@@ -26,13 +26,13 @@
|
|
|
26
26
|
"Quenty"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@quenty/draw": "^7.8.
|
|
30
|
-
"@quenty/loader": "^10.8.
|
|
31
|
-
"@quenty/queue": "^2.3.
|
|
32
|
-
"@quenty/vector3utils": "^10.8.
|
|
29
|
+
"@quenty/draw": "^7.8.2",
|
|
30
|
+
"@quenty/loader": "^10.8.1",
|
|
31
|
+
"@quenty/queue": "^2.3.1",
|
|
32
|
+
"@quenty/vector3utils": "^10.8.2"
|
|
33
33
|
},
|
|
34
34
|
"publishConfig": {
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
|
-
"gitHead": "
|
|
37
|
+
"gitHead": "78c3ac0ab08dd18085b6e6e6e4f745e76ed99f68"
|
|
38
38
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
@class ConvexHull2DUtils
|
|
3
4
|
]=]
|
|
@@ -11,7 +12,7 @@ local ConvexHull2DUtils = {}
|
|
|
11
12
|
]=]
|
|
12
13
|
function ConvexHull2DUtils.convexHull(points: { Vector2 }): { Vector2 }
|
|
13
14
|
table.sort(points, function(a, b)
|
|
14
|
-
return a.
|
|
15
|
+
return a.X < b.X
|
|
15
16
|
end)
|
|
16
17
|
|
|
17
18
|
local pointOnHull = points[1]
|
|
@@ -22,7 +23,7 @@ function ConvexHull2DUtils.convexHull(points: { Vector2 }): { Vector2 }
|
|
|
22
23
|
|
|
23
24
|
local endpoint = points[1]
|
|
24
25
|
|
|
25
|
-
for i=1, #points do
|
|
26
|
+
for i = 1, #points do
|
|
26
27
|
local point = points[i]
|
|
27
28
|
|
|
28
29
|
-- endpoint == pointOnHull is a rare case and can happen only when j == 1 and a better endpoint has not yet been set for the loop
|
|
@@ -40,7 +41,7 @@ end
|
|
|
40
41
|
Retrns whether these 3 points are in a clockwise turn
|
|
41
42
|
]=]
|
|
42
43
|
function ConvexHull2DUtils.isClockWiseTurn(p1: Vector2, p2: Vector2, p3: Vector2): boolean
|
|
43
|
-
return (p3.
|
|
44
|
+
return (p3.Y - p1.Y) * (p2.X - p1.X) < (p2.Y - p1.Y) * (p3.X - p1.X)
|
|
44
45
|
end
|
|
45
46
|
|
|
46
47
|
--[=[
|
|
@@ -49,9 +50,9 @@ end
|
|
|
49
50
|
function ConvexHull2DUtils.lineIntersect(a: Vector2, b: Vector2, c: Vector2, d: Vector2): Vector2 | nil
|
|
50
51
|
local r = b - a
|
|
51
52
|
local s = d - c
|
|
52
|
-
local dot = r.
|
|
53
|
-
local u = ((c.
|
|
54
|
-
local t = ((c.
|
|
53
|
+
local dot = r.X * s.Y - r.Y * s.X
|
|
54
|
+
local u = ((c.X - a.X) * r.Y - (c.Y - a.Y) * r.X) / dot
|
|
55
|
+
local t = ((c.X - a.X) * s.Y - (c.Y - a.Y) * s.X) / dot
|
|
55
56
|
return (0 <= u and u <= 1 and 0 <= t and t <= 1) and a + t * r or nil
|
|
56
57
|
end
|
|
57
58
|
|
|
@@ -64,21 +65,21 @@ function ConvexHull2DUtils.raycast(from: Vector2, to: Vector2, hull: { Vector2 }
|
|
|
64
65
|
|
|
65
66
|
for i = 1, n do
|
|
66
67
|
local current = hull[i]
|
|
67
|
-
local after = hull[i%n + 1]
|
|
68
|
+
local after = hull[i % n + 1]
|
|
68
69
|
local point = ConvexHull2DUtils.lineIntersect(current, after, from, to)
|
|
69
70
|
if point then
|
|
70
71
|
table.insert(candidates, {
|
|
71
|
-
point = point
|
|
72
|
-
startPoint = current
|
|
73
|
-
finishPoint = after
|
|
72
|
+
point = point,
|
|
73
|
+
startPoint = current,
|
|
74
|
+
finishPoint = after,
|
|
74
75
|
})
|
|
75
76
|
end
|
|
76
77
|
end
|
|
77
78
|
|
|
78
79
|
local closest
|
|
79
80
|
local closestDist = math.huge
|
|
80
|
-
for _, data in
|
|
81
|
-
local dist = (data.point - from).
|
|
81
|
+
for _, data in candidates do
|
|
82
|
+
local dist = (data.point - from).Magnitude
|
|
82
83
|
if dist < closestDist then
|
|
83
84
|
closest = data
|
|
84
85
|
closestDist = dist
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
--!strict
|
|
1
2
|
--[=[
|
|
2
3
|
3D convex hull computation using gift wrappling algorithm
|
|
3
4
|
|
|
@@ -13,15 +14,17 @@ local Draw = require("Draw")
|
|
|
13
14
|
|
|
14
15
|
local ConvexHull3DUtils = {}
|
|
15
16
|
|
|
17
|
+
type Edge = { number }
|
|
18
|
+
|
|
16
19
|
--[=[
|
|
17
20
|
Computes the convex hull for a given set of points
|
|
18
21
|
|
|
19
22
|
https://en.wikipedia.org/wiki/Gift_wrapping_algorithm
|
|
20
23
|
|
|
21
|
-
@param points Vector3
|
|
24
|
+
@param points { Vector3 }
|
|
22
25
|
@return { Vector3 }
|
|
23
26
|
]=]
|
|
24
|
-
function ConvexHull3DUtils.convexHull(points)
|
|
27
|
+
function ConvexHull3DUtils.convexHull(points: { Vector3 }): { Vector3 }
|
|
25
28
|
assert(type(points) == "table", "Bad points")
|
|
26
29
|
|
|
27
30
|
if #points <= 3 then
|
|
@@ -39,7 +42,7 @@ function ConvexHull3DUtils.convexHull(points)
|
|
|
39
42
|
|
|
40
43
|
local visited = {} -- Set to keep track of visited edges
|
|
41
44
|
|
|
42
|
-
local agenda = Queue.new() -- Queue to process edgeSet
|
|
45
|
+
local agenda: Queue.Queue<Edge> = Queue.new() -- Queue to process edgeSet
|
|
43
46
|
agenda:PushRight({ leftMost, secondPoint })
|
|
44
47
|
|
|
45
48
|
while not agenda:IsEmpty() do
|
|
@@ -59,20 +62,20 @@ function ConvexHull3DUtils.convexHull(points)
|
|
|
59
62
|
end
|
|
60
63
|
|
|
61
64
|
local vertices = {}
|
|
62
|
-
for index, _ in
|
|
65
|
+
for index, _ in meshIndexSet do
|
|
63
66
|
table.insert(vertices, points[index])
|
|
64
67
|
end
|
|
65
68
|
|
|
66
69
|
return vertices
|
|
67
70
|
end
|
|
68
71
|
|
|
69
|
-
function ConvexHull3DUtils._pickMostConvex(points, edge)
|
|
72
|
+
function ConvexHull3DUtils._pickMostConvex(points: { Vector3 }, edge: Edge): number
|
|
70
73
|
local bestIndex = 0
|
|
71
74
|
local bestAngle = -math.huge
|
|
72
|
-
local diffEdge = (points[edge[2]] - points[edge[1]]).
|
|
75
|
+
local diffEdge = (points[edge[2]] - points[edge[1]]).Unit
|
|
73
76
|
|
|
74
|
-
for index, point in
|
|
75
|
-
local diff = (points[edge[2]] - point).
|
|
77
|
+
for index, point in points do
|
|
78
|
+
local diff = (points[edge[2]] - point).Unit
|
|
76
79
|
local angle = math.acos(diff:Dot(diffEdge))
|
|
77
80
|
|
|
78
81
|
if angle > bestAngle and angle < math.pi then
|
|
@@ -84,26 +87,26 @@ function ConvexHull3DUtils._pickMostConvex(points, edge)
|
|
|
84
87
|
return bestIndex
|
|
85
88
|
end
|
|
86
89
|
|
|
87
|
-
function ConvexHull3DUtils._pickLeftMost(points)
|
|
90
|
+
function ConvexHull3DUtils._pickLeftMost(points: { Vector3 }): number
|
|
88
91
|
local leftmostIndex = 1
|
|
89
92
|
local leftMostX = math.huge
|
|
90
|
-
for index, point in
|
|
91
|
-
if point.
|
|
93
|
+
for index, point in points do
|
|
94
|
+
if point.X < leftMostX then
|
|
92
95
|
leftmostIndex = index
|
|
93
|
-
leftMostX = point.
|
|
96
|
+
leftMostX = point.X
|
|
94
97
|
end
|
|
95
98
|
end
|
|
96
99
|
|
|
97
100
|
return leftmostIndex
|
|
98
101
|
end
|
|
99
102
|
|
|
100
|
-
function ConvexHull3DUtils._pickSecondPoint(points, leftMost)
|
|
103
|
+
function ConvexHull3DUtils._pickSecondPoint(points: { Vector3 }, leftMost: number): number
|
|
101
104
|
local v0 = Vector3.new(1, 0, 0)
|
|
102
105
|
local bestAngle = -math.huge
|
|
103
106
|
local bestIndex = 1
|
|
104
107
|
|
|
105
|
-
for index, point in
|
|
106
|
-
local diff = (point - points[leftMost]).
|
|
108
|
+
for index, point in points do
|
|
109
|
+
local diff = (point - points[leftMost]).Unit
|
|
107
110
|
local angle = math.acos(diff:Dot(v0))
|
|
108
111
|
|
|
109
112
|
if angle > bestAngle and angle < math.pi then
|
|
@@ -115,16 +118,16 @@ function ConvexHull3DUtils._pickSecondPoint(points, leftMost)
|
|
|
115
118
|
return bestIndex
|
|
116
119
|
end
|
|
117
120
|
|
|
118
|
-
function ConvexHull3DUtils._edgeKey(edge)
|
|
121
|
+
function ConvexHull3DUtils._edgeKey(edge: Edge): string
|
|
119
122
|
return edge[1] .. "-" .. edge[2]
|
|
120
123
|
end
|
|
121
124
|
|
|
122
|
-
function ConvexHull3DUtils.drawVertices(points, color)
|
|
125
|
+
function ConvexHull3DUtils.drawVertices(points: { Vector3 }, color: Color3?): Folder
|
|
123
126
|
local folder = Instance.new("Folder")
|
|
124
127
|
folder.Name = "ConvexHullPoints"
|
|
125
128
|
folder.Archivable = false
|
|
126
129
|
|
|
127
|
-
for _, point in
|
|
130
|
+
for _, point in points do
|
|
128
131
|
Draw.point(point, color, folder)
|
|
129
132
|
end
|
|
130
133
|
|
|
@@ -41,7 +41,7 @@ local function drawBlockCast(cframe, size, direction)
|
|
|
41
41
|
box2.Parent = folder
|
|
42
42
|
|
|
43
43
|
local points = {}
|
|
44
|
-
for _, corner in
|
|
44
|
+
for _, corner in CORNERS do
|
|
45
45
|
local beginPoint = beginCFrame:PointToWorldSpace(corner * size)
|
|
46
46
|
local finishPoint = finishCFrame:PointToWorldSpace(corner * size)
|
|
47
47
|
|