isometric-physics 1.0.0 → 1.0.1
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.md +41 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -13
- package/dist/index.d.ts +3 -13
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# isometric-physics
|
|
2
|
+
|
|
3
|
+
[](https://github.com/TheFujirose/isometric-physics/actions/workflows/build.yml)
|
|
4
|
+
[](https://thefujirose.github.io/isometric-physics/)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
|
|
7
|
+
Zero-dependency isometric projection math, 2D/3D vector operations, and vessel position integration for TypeScript projects.
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm add isometric-physics
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import { isoTransform, vec3Cross, stepVesselPosition } from 'isometric-physics';
|
|
19
|
+
|
|
20
|
+
const screenPoint = isoTransform(4, 2, 1);
|
|
21
|
+
const normal = vec3Cross({ x: 1, y: 0, z: 0 }, { x: 0, y: 1, z: 0 });
|
|
22
|
+
const nextPosition = stepVesselPosition({ x: 0, y: 0 }, 12, 90, 0.016, 100);
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## API
|
|
26
|
+
|
|
27
|
+
The package exports three small modules:
|
|
28
|
+
|
|
29
|
+
- `isometric` for projection helpers and compass labels
|
|
30
|
+
- `vectors` for 2D and 3D vector math
|
|
31
|
+
- `physics` for world-wrapping vessel integration
|
|
32
|
+
|
|
33
|
+
Full API documentation is generated with Typedoc and published through the docs workflow.
|
|
34
|
+
|
|
35
|
+
## Development
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pnpm install
|
|
39
|
+
pnpm build
|
|
40
|
+
pnpm run docs
|
|
41
|
+
```
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/isometric.ts","../src/vectors.ts","../src/physics.ts"],"sourcesContent":["export * from './isometric.js';\nexport * from './vectors.js';\nexport * from './physics.js';\n","/**\n *
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/isometric.ts","../src/vectors.ts","../src/physics.ts"],"sourcesContent":["export * from './isometric.js';\nexport * from './vectors.js';\nexport * from './physics.js';\n","/**\n * Isometric projection math for the standard 2:1 dimetric projection.\n */\n\nexport type Point = { x: number; y: number };\n\nconst ISO_ANGLE = Math.PI / 6;\nconst COS_30 = Math.cos(ISO_ANGLE);\nconst SIN_30 = Math.sin(ISO_ANGLE);\n\n/**\n * Standard isometric projection (X right-down, Y left-down, Z up).\n */\nexport const isoTransform = (x: number, y: number, z = 0): Point => ({\n x: (x - y) * COS_30,\n y: (x + y) * SIN_30 - z,\n});\n\n/**\n * Creates a projection function bound to a specific canvas origin and scale.\n */\nexport const getToScreen = (centerX: number, centerY: number, scale = 1) =>\n (x: number, y: number, z: number): Point => {\n const iso = isoTransform(x * scale, y * scale, z * scale);\n return { x: centerX + iso.x, y: centerY + iso.y };\n };\n\n/**\n * Returns a cardinal direction label for a heading in degrees (0–360).\n */\nexport const getCardinalLabel = (heading: number): string => {\n const directions = [\n { min: 337.5, max: 360, label: 'N' },\n { min: 0, max: 22.5, label: 'N' },\n { min: 22.5, max: 67.5, label: 'NE' },\n { min: 67.5, max: 112.5, label: 'E' },\n { min: 112.5, max: 157.5, label: 'SE' },\n { min: 157.5, max: 202.5, label: 'S' },\n { min: 202.5, max: 247.5, label: 'SW' },\n { min: 247.5, max: 292.5, label: 'W' },\n { min: 292.5, max: 337.5, label: 'NW' },\n ];\n for (const dir of directions) {\n if (heading >= dir.min && heading < dir.max) return dir.label;\n }\n return 'N';\n};\n","/**\n * Lightweight 2D and 3D vector types and operations.\n */\n\nexport type Vector2 = { x: number; y: number };\nexport type Vector3 = { x: number; y: number; z: number };\n\nexport const vec2Add = (a: Vector2, b: Vector2): Vector2 => ({ x: a.x + b.x, y: a.y + b.y });\nexport const vec2Sub = (a: Vector2, b: Vector2): Vector2 => ({ x: a.x - b.x, y: a.y - b.y });\nexport const vec2Scale = (v: Vector2, s: number): Vector2 => ({ x: v.x * s, y: v.y * s });\nexport const vec2Length = (v: Vector2): number => Math.sqrt(v.x ** 2 + v.y ** 2);\nexport const vec2Normalize = (v: Vector2): Vector2 => {\n const l = vec2Length(v) || 1;\n return vec2Scale(v, 1 / l);\n};\nexport const vec2Dot = (a: Vector2, b: Vector2): number => a.x * b.x + a.y * b.y;\n\nexport const vec3Add = (a: Vector3, b: Vector3): Vector3 => ({ x: a.x + b.x, y: a.y + b.y, z: a.z + b.z });\nexport const vec3Sub = (a: Vector3, b: Vector3): Vector3 => ({ x: a.x - b.x, y: a.y - b.y, z: a.z - b.z });\nexport const vec3Scale = (v: Vector3, s: number): Vector3 => ({ x: v.x * s, y: v.y * s, z: v.z * s });\nexport const vec3Length = (v: Vector3): number => Math.sqrt(v.x ** 2 + v.y ** 2 + v.z ** 2);\nexport const vec3Normalize = (v: Vector3): Vector3 => {\n const l = vec3Length(v) || 1;\n return vec3Scale(v, 1 / l);\n};\nexport const vec3Dot = (a: Vector3, b: Vector3): number => a.x * b.x + a.y * b.y + a.z * b.z;\nexport const vec3Cross = (a: Vector3, b: Vector3): Vector3 => ({\n x: a.y * b.z - a.z * b.y,\n y: a.z * b.x - a.x * b.z,\n z: a.x * b.y - a.y * b.x,\n});\n","/**\n * Pure vessel-position integration step, detached from React.\n */\nimport type { Point } from './isometric.js';\n\n/**\n * Advances a vessel's position by one physics step.\n * @param pos - Current { x, y } position in world units.\n * @param velocity - Current velocity in world units per second.\n * @param rotationDeg - Current heading in degrees (0 = north, 90 = east).\n * @param deltaTime - Elapsed time since the last step, in seconds.\n * @param gridSize - Total span of the (square) world; position wraps at ±gridSize/2.\n * @returns The new { x, y } position, wrapped to stay within the world bounds.\n */\nexport const stepVesselPosition = (\n pos: Point,\n velocity: number,\n rotationDeg: number,\n deltaTime: number,\n gridSize: number,\n): Point => {\n if (velocity === 0) return pos;\n\n const limit = gridSize / 2;\n const rad = (-rotationDeg * Math.PI) / 180;\n const dx = -velocity * Math.sin(rad) * deltaTime;\n const dy = -velocity * Math.cos(rad) * deltaTime;\n\n let newX = pos.x + dx;\n let newY = pos.y + dy;\n if (newX > limit) newX -= gridSize;\n if (newX < -limit) newX += gridSize;\n if (newY > limit) newY -= gridSize;\n if (newY < -limit) newY += gridSize;\n\n return { x: newX, y: newY };\n};\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @description Isometric projection math: standard 2:1 dimetric projection (X right-down, Y left-down, Z up).
|
|
4
|
-
* @version 1.0.0
|
|
2
|
+
* Isometric projection math for the standard 2:1 dimetric projection.
|
|
5
3
|
*/
|
|
6
4
|
type Point = {
|
|
7
5
|
x: number;
|
|
@@ -9,7 +7,6 @@ type Point = {
|
|
|
9
7
|
};
|
|
10
8
|
/**
|
|
11
9
|
* Standard isometric projection (X right-down, Y left-down, Z up).
|
|
12
|
-
* @version 1.0.0
|
|
13
10
|
*/
|
|
14
11
|
declare const isoTransform: (x: number, y: number, z?: number) => Point;
|
|
15
12
|
/**
|
|
@@ -22,9 +19,7 @@ declare const getToScreen: (centerX: number, centerY: number, scale?: number) =>
|
|
|
22
19
|
declare const getCardinalLabel: (heading: number) => string;
|
|
23
20
|
|
|
24
21
|
/**
|
|
25
|
-
*
|
|
26
|
-
* @description Lightweight 2D and 3D vector types and operations.
|
|
27
|
-
* @version 1.0.0
|
|
22
|
+
* Lightweight 2D and 3D vector types and operations.
|
|
28
23
|
*/
|
|
29
24
|
type Vector2 = {
|
|
30
25
|
x: number;
|
|
@@ -50,11 +45,7 @@ declare const vec3Dot: (a: Vector3, b: Vector3) => number;
|
|
|
50
45
|
declare const vec3Cross: (a: Vector3, b: Vector3) => Vector3;
|
|
51
46
|
|
|
52
47
|
/**
|
|
53
|
-
*
|
|
54
|
-
* @description Pure vessel-position integration step, detached from React. Given a current
|
|
55
|
-
* position, velocity, and heading, advances the position by one timestep and wraps it around
|
|
56
|
-
* a square world of the given size.
|
|
57
|
-
* @version 1.0.0
|
|
48
|
+
* Pure vessel-position integration step, detached from React.
|
|
58
49
|
*/
|
|
59
50
|
|
|
60
51
|
/**
|
|
@@ -65,7 +56,6 @@ declare const vec3Cross: (a: Vector3, b: Vector3) => Vector3;
|
|
|
65
56
|
* @param deltaTime - Elapsed time since the last step, in seconds.
|
|
66
57
|
* @param gridSize - Total span of the (square) world; position wraps at ±gridSize/2.
|
|
67
58
|
* @returns The new { x, y } position, wrapped to stay within the world bounds.
|
|
68
|
-
* @version 1.0.0
|
|
69
59
|
*/
|
|
70
60
|
declare const stepVesselPosition: (pos: Point, velocity: number, rotationDeg: number, deltaTime: number, gridSize: number) => Point;
|
|
71
61
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* @description Isometric projection math: standard 2:1 dimetric projection (X right-down, Y left-down, Z up).
|
|
4
|
-
* @version 1.0.0
|
|
2
|
+
* Isometric projection math for the standard 2:1 dimetric projection.
|
|
5
3
|
*/
|
|
6
4
|
type Point = {
|
|
7
5
|
x: number;
|
|
@@ -9,7 +7,6 @@ type Point = {
|
|
|
9
7
|
};
|
|
10
8
|
/**
|
|
11
9
|
* Standard isometric projection (X right-down, Y left-down, Z up).
|
|
12
|
-
* @version 1.0.0
|
|
13
10
|
*/
|
|
14
11
|
declare const isoTransform: (x: number, y: number, z?: number) => Point;
|
|
15
12
|
/**
|
|
@@ -22,9 +19,7 @@ declare const getToScreen: (centerX: number, centerY: number, scale?: number) =>
|
|
|
22
19
|
declare const getCardinalLabel: (heading: number) => string;
|
|
23
20
|
|
|
24
21
|
/**
|
|
25
|
-
*
|
|
26
|
-
* @description Lightweight 2D and 3D vector types and operations.
|
|
27
|
-
* @version 1.0.0
|
|
22
|
+
* Lightweight 2D and 3D vector types and operations.
|
|
28
23
|
*/
|
|
29
24
|
type Vector2 = {
|
|
30
25
|
x: number;
|
|
@@ -50,11 +45,7 @@ declare const vec3Dot: (a: Vector3, b: Vector3) => number;
|
|
|
50
45
|
declare const vec3Cross: (a: Vector3, b: Vector3) => Vector3;
|
|
51
46
|
|
|
52
47
|
/**
|
|
53
|
-
*
|
|
54
|
-
* @description Pure vessel-position integration step, detached from React. Given a current
|
|
55
|
-
* position, velocity, and heading, advances the position by one timestep and wraps it around
|
|
56
|
-
* a square world of the given size.
|
|
57
|
-
* @version 1.0.0
|
|
48
|
+
* Pure vessel-position integration step, detached from React.
|
|
58
49
|
*/
|
|
59
50
|
|
|
60
51
|
/**
|
|
@@ -65,7 +56,6 @@ declare const vec3Cross: (a: Vector3, b: Vector3) => Vector3;
|
|
|
65
56
|
* @param deltaTime - Elapsed time since the last step, in seconds.
|
|
66
57
|
* @param gridSize - Total span of the (square) world; position wraps at ±gridSize/2.
|
|
67
58
|
* @returns The new { x, y } position, wrapped to stay within the world bounds.
|
|
68
|
-
* @version 1.0.0
|
|
69
59
|
*/
|
|
70
60
|
declare const stepVesselPosition: (pos: Point, velocity: number, rotationDeg: number, deltaTime: number, gridSize: number) => Point;
|
|
71
61
|
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/isometric.ts","../src/vectors.ts","../src/physics.ts"],"sourcesContent":["/**\n *
|
|
1
|
+
{"version":3,"sources":["../src/isometric.ts","../src/vectors.ts","../src/physics.ts"],"sourcesContent":["/**\n * Isometric projection math for the standard 2:1 dimetric projection.\n */\n\nexport type Point = { x: number; y: number };\n\nconst ISO_ANGLE = Math.PI / 6;\nconst COS_30 = Math.cos(ISO_ANGLE);\nconst SIN_30 = Math.sin(ISO_ANGLE);\n\n/**\n * Standard isometric projection (X right-down, Y left-down, Z up).\n */\nexport const isoTransform = (x: number, y: number, z = 0): Point => ({\n x: (x - y) * COS_30,\n y: (x + y) * SIN_30 - z,\n});\n\n/**\n * Creates a projection function bound to a specific canvas origin and scale.\n */\nexport const getToScreen = (centerX: number, centerY: number, scale = 1) =>\n (x: number, y: number, z: number): Point => {\n const iso = isoTransform(x * scale, y * scale, z * scale);\n return { x: centerX + iso.x, y: centerY + iso.y };\n };\n\n/**\n * Returns a cardinal direction label for a heading in degrees (0–360).\n */\nexport const getCardinalLabel = (heading: number): string => {\n const directions = [\n { min: 337.5, max: 360, label: 'N' },\n { min: 0, max: 22.5, label: 'N' },\n { min: 22.5, max: 67.5, label: 'NE' },\n { min: 67.5, max: 112.5, label: 'E' },\n { min: 112.5, max: 157.5, label: 'SE' },\n { min: 157.5, max: 202.5, label: 'S' },\n { min: 202.5, max: 247.5, label: 'SW' },\n { min: 247.5, max: 292.5, label: 'W' },\n { min: 292.5, max: 337.5, label: 'NW' },\n ];\n for (const dir of directions) {\n if (heading >= dir.min && heading < dir.max) return dir.label;\n }\n return 'N';\n};\n","/**\n * Lightweight 2D and 3D vector types and operations.\n */\n\nexport type Vector2 = { x: number; y: number };\nexport type Vector3 = { x: number; y: number; z: number };\n\nexport const vec2Add = (a: Vector2, b: Vector2): Vector2 => ({ x: a.x + b.x, y: a.y + b.y });\nexport const vec2Sub = (a: Vector2, b: Vector2): Vector2 => ({ x: a.x - b.x, y: a.y - b.y });\nexport const vec2Scale = (v: Vector2, s: number): Vector2 => ({ x: v.x * s, y: v.y * s });\nexport const vec2Length = (v: Vector2): number => Math.sqrt(v.x ** 2 + v.y ** 2);\nexport const vec2Normalize = (v: Vector2): Vector2 => {\n const l = vec2Length(v) || 1;\n return vec2Scale(v, 1 / l);\n};\nexport const vec2Dot = (a: Vector2, b: Vector2): number => a.x * b.x + a.y * b.y;\n\nexport const vec3Add = (a: Vector3, b: Vector3): Vector3 => ({ x: a.x + b.x, y: a.y + b.y, z: a.z + b.z });\nexport const vec3Sub = (a: Vector3, b: Vector3): Vector3 => ({ x: a.x - b.x, y: a.y - b.y, z: a.z - b.z });\nexport const vec3Scale = (v: Vector3, s: number): Vector3 => ({ x: v.x * s, y: v.y * s, z: v.z * s });\nexport const vec3Length = (v: Vector3): number => Math.sqrt(v.x ** 2 + v.y ** 2 + v.z ** 2);\nexport const vec3Normalize = (v: Vector3): Vector3 => {\n const l = vec3Length(v) || 1;\n return vec3Scale(v, 1 / l);\n};\nexport const vec3Dot = (a: Vector3, b: Vector3): number => a.x * b.x + a.y * b.y + a.z * b.z;\nexport const vec3Cross = (a: Vector3, b: Vector3): Vector3 => ({\n x: a.y * b.z - a.z * b.y,\n y: a.z * b.x - a.x * b.z,\n z: a.x * b.y - a.y * b.x,\n});\n","/**\n * Pure vessel-position integration step, detached from React.\n */\nimport type { Point } from './isometric.js';\n\n/**\n * Advances a vessel's position by one physics step.\n * @param pos - Current { x, y } position in world units.\n * @param velocity - Current velocity in world units per second.\n * @param rotationDeg - Current heading in degrees (0 = north, 90 = east).\n * @param deltaTime - Elapsed time since the last step, in seconds.\n * @param gridSize - Total span of the (square) world; position wraps at ±gridSize/2.\n * @returns The new { x, y } position, wrapped to stay within the world bounds.\n */\nexport const stepVesselPosition = (\n pos: Point,\n velocity: number,\n rotationDeg: number,\n deltaTime: number,\n gridSize: number,\n): Point => {\n if (velocity === 0) return pos;\n\n const limit = gridSize / 2;\n const rad = (-rotationDeg * Math.PI) / 180;\n const dx = -velocity * Math.sin(rad) * deltaTime;\n const dy = -velocity * Math.cos(rad) * deltaTime;\n\n let newX = pos.x + dx;\n let newY = pos.y + dy;\n if (newX > limit) newX -= gridSize;\n if (newX < -limit) newX += gridSize;\n if (newY > limit) newY -= gridSize;\n if (newY < -limit) newY += gridSize;\n\n return { x: newX, y: newY };\n};\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "isometric-physics",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Zero-dependency isometric projection math, 2D/3D vector operations, and vessel position integration.",
|
|
5
5
|
"author": "Carson Fujita <carsonfujita@gmail.com>",
|
|
6
6
|
"repository": "https://github.com/TheFujirose/isometric-physics",
|
|
@@ -28,11 +28,13 @@
|
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
30
|
"devDependencies": {
|
|
31
|
+
"typedoc": "^0.28.13",
|
|
31
32
|
"tsup": "^8.5.1",
|
|
32
33
|
"typescript": "^6.0.3"
|
|
33
34
|
},
|
|
34
35
|
"scripts": {
|
|
35
36
|
"build": "tsup",
|
|
36
|
-
"dev": "tsup --watch"
|
|
37
|
+
"dev": "tsup --watch",
|
|
38
|
+
"docs": "typedoc"
|
|
37
39
|
}
|
|
38
40
|
}
|