scax-engine 0.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/LICENSE +21 -0
- package/README.md +182 -0
- package/dist/scax-engine.cjs +9441 -0
- package/dist/scax-engine.js +9437 -0
- package/dist/scax-engine.umd.js +9447 -0
- package/dist/types/affine/affine.d.ts +45 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/light-sources/light-source.d.ts +57 -0
- package/dist/types/optics/refractive-index.d.ts +11 -0
- package/dist/types/parameters/constants.d.ts +194 -0
- package/dist/types/parameters/eye/eyemodel-parameter.d.ts +36 -0
- package/dist/types/parameters/eye/gullstrand-parameter.d.ts +6 -0
- package/dist/types/parameters/eye/navarro-parameter.d.ts +6 -0
- package/dist/types/ray/ray.d.ts +27 -0
- package/dist/types/scax-engine.d.ts +441 -0
- package/dist/types/sturm/sturm.d.ts +81 -0
- package/dist/types/surfaces/aperture-stop-surface.d.ts +35 -0
- package/dist/types/surfaces/aspherical-surface.d.ts +70 -0
- package/dist/types/surfaces/paraxial-surface.d.ts +61 -0
- package/dist/types/surfaces/spherical-image.d.ts +42 -0
- package/dist/types/surfaces/spherical-surface.d.ts +58 -0
- package/dist/types/surfaces/st-surface.d.ts +91 -0
- package/dist/types/surfaces/surface.d.ts +32 -0
- package/dist/types/surfaces/toric-surface.d.ts +68 -0
- package/dist/types/utils/deg-to-tabo.d.ts +3 -0
- package/dist/types/utils/tabo-to-deg.d.ts +3 -0
- package/package.json +64 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Vector3 } from "three";
|
|
2
|
+
import Ray from "../ray/ray";
|
|
3
|
+
import Surface from "./surface";
|
|
4
|
+
export type SphericalImageSurfaceProps = {
|
|
5
|
+
type: "spherical-image";
|
|
6
|
+
name: string;
|
|
7
|
+
r: number;
|
|
8
|
+
position: {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
z: number;
|
|
12
|
+
};
|
|
13
|
+
tilt: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
};
|
|
17
|
+
retina_extra_after: boolean;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* 곡면 표현만 하고 굴절 효과는 없습니다.
|
|
21
|
+
* 망막 위치를 표현하는 데 사용됩니다.
|
|
22
|
+
*/
|
|
23
|
+
export default class SphericalImageSurface extends Surface {
|
|
24
|
+
private r;
|
|
25
|
+
private retina_extra_after;
|
|
26
|
+
private hitPoints;
|
|
27
|
+
constructor(props: SphericalImageSurfaceProps);
|
|
28
|
+
/**
|
|
29
|
+
* 반경 값이 비정상이면 평면(z = position.z)으로 처리합니다.
|
|
30
|
+
*/
|
|
31
|
+
private isPlanar;
|
|
32
|
+
/**
|
|
33
|
+
* 구면 중심: 꼭지점(position)에서 반경만큼 z축 이동한 점
|
|
34
|
+
*/
|
|
35
|
+
private sphereCenter;
|
|
36
|
+
getHitPoints(): Vector3[];
|
|
37
|
+
clearHitPoints(): void;
|
|
38
|
+
clearTraceHistory(): void;
|
|
39
|
+
incident(ray: Ray): Vector3 | null;
|
|
40
|
+
refract(ray: Ray): Ray | null;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=spherical-image.d.ts.map
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Vector3 } from "three";
|
|
2
|
+
import { RefractiveIndexSpec } from "../optics/refractive-index";
|
|
3
|
+
import Ray from "../ray/ray";
|
|
4
|
+
import Surface from "./surface";
|
|
5
|
+
export type SphericalSurfaceProps = {
|
|
6
|
+
type: "spherical";
|
|
7
|
+
name: string;
|
|
8
|
+
r: number;
|
|
9
|
+
position: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
z: number;
|
|
13
|
+
};
|
|
14
|
+
tilt: {
|
|
15
|
+
x: number;
|
|
16
|
+
y: number;
|
|
17
|
+
};
|
|
18
|
+
n_before: RefractiveIndexSpec;
|
|
19
|
+
n_after: RefractiveIndexSpec;
|
|
20
|
+
};
|
|
21
|
+
export default class SphericalSurface extends Surface {
|
|
22
|
+
private r;
|
|
23
|
+
private n_before;
|
|
24
|
+
private n_after;
|
|
25
|
+
constructor(props: SphericalSurfaceProps);
|
|
26
|
+
private refractiveIndicesForRay;
|
|
27
|
+
/**
|
|
28
|
+
* 반경이 너무 크거나 비정상 값이면 평면으로 간주합니다.
|
|
29
|
+
* (legacy 코드의 planar fallback 동작을 그대로 반영)
|
|
30
|
+
*/
|
|
31
|
+
private isPlanar;
|
|
32
|
+
private worldQuaternion;
|
|
33
|
+
private worldPointToLocal;
|
|
34
|
+
private localPointToWorld;
|
|
35
|
+
private worldDirToLocal;
|
|
36
|
+
private localDirToWorld;
|
|
37
|
+
/**
|
|
38
|
+
* 구면의 중심점입니다.
|
|
39
|
+
* 이 프로젝트의 구면은 +Z 축을 기준으로 배치되며,
|
|
40
|
+
* 중심은 꼭지점(position)에서 반경만큼 Z 방향으로 이동한 위치입니다.
|
|
41
|
+
*/
|
|
42
|
+
private sphereCenterLocal;
|
|
43
|
+
/**
|
|
44
|
+
* 굴절 계산에 사용할 "2번째 매질 방향" 법선을 계산합니다.
|
|
45
|
+
* - 평면: +Z 법선 사용
|
|
46
|
+
* - 구면: 반경 부호에 따라 중심-입사점 벡터 방향을 맞춰 사용
|
|
47
|
+
*/
|
|
48
|
+
private normalIntoSecondMediumLocal;
|
|
49
|
+
/**
|
|
50
|
+
* 주어진 XY에서 구면의 z 위치를 계산합니다.
|
|
51
|
+
* - 반경이 매우 큰 경우(평면)에는 평면 z를 반환합니다.
|
|
52
|
+
* - 구면 정의역 밖이면 null을 반환합니다.
|
|
53
|
+
*/
|
|
54
|
+
private surfaceZAtXY;
|
|
55
|
+
incident(ray: Ray): Vector3 | null;
|
|
56
|
+
refract(ray: Ray): Ray | null;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=spherical-surface.d.ts.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Vector3 } from "three";
|
|
2
|
+
import { RefractiveIndexSpec } from "../optics/refractive-index";
|
|
3
|
+
import Ray from "../ray/ray";
|
|
4
|
+
import Surface from "./surface";
|
|
5
|
+
export type STSurfaceProps = {
|
|
6
|
+
type: "compound";
|
|
7
|
+
name: string;
|
|
8
|
+
position: {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
z: number;
|
|
12
|
+
};
|
|
13
|
+
tilt: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
};
|
|
17
|
+
r?: number;
|
|
18
|
+
s: number;
|
|
19
|
+
c: number;
|
|
20
|
+
ax: number;
|
|
21
|
+
n_before: RefractiveIndexSpec;
|
|
22
|
+
n: RefractiveIndexSpec;
|
|
23
|
+
n_after: RefractiveIndexSpec;
|
|
24
|
+
referencePoint?: {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
z: number;
|
|
28
|
+
};
|
|
29
|
+
thickness?: number;
|
|
30
|
+
};
|
|
31
|
+
export default class STSurface extends Surface {
|
|
32
|
+
private static readonly POWER_EPS_D;
|
|
33
|
+
private s;
|
|
34
|
+
private c;
|
|
35
|
+
private ax;
|
|
36
|
+
private n_before;
|
|
37
|
+
private n;
|
|
38
|
+
private n_after;
|
|
39
|
+
private thickness;
|
|
40
|
+
/** 구면. vertex z = position.z + thickness (+z 쪽, 광이 나가는 쪽). */
|
|
41
|
+
private sphericalSurface;
|
|
42
|
+
/** 토릭(원통). vertex z = position.z (−z 쪽, +z 진행 시 광이 먼저 맞는 쪽). 없으면 null. */
|
|
43
|
+
private toricSurface;
|
|
44
|
+
private sphericalRadiusMm;
|
|
45
|
+
private toricRadiusPerpMm;
|
|
46
|
+
constructor(props: STSurfaceProps);
|
|
47
|
+
/**
|
|
48
|
+
* 디옵터(D)로부터 반경(mm)을 계산합니다.
|
|
49
|
+
*
|
|
50
|
+
* power(D) = (n2 - n1) / R(m)
|
|
51
|
+
* -> R(mm) = 1000 * (n2 - n1) / power(D)
|
|
52
|
+
*
|
|
53
|
+
* 굴절력이 사실상 0이면 평면으로 간주하기 위해 +Infinity를 반환합니다.
|
|
54
|
+
*/
|
|
55
|
+
private radiusFromPower;
|
|
56
|
+
private refractiveIndexAtD;
|
|
57
|
+
/**
|
|
58
|
+
* ST 구면 측: z가 더 큰 꼭지( +z 진행 시 출사 쪽 ).
|
|
59
|
+
*/
|
|
60
|
+
private buildSphericalSurface;
|
|
61
|
+
/**
|
|
62
|
+
* ST 토릭 측: cylinder가 있을 때만. z가 더 작은 꼭지( +z 진행 시 입사 쪽 ).
|
|
63
|
+
*/
|
|
64
|
+
private buildToricSurface;
|
|
65
|
+
private applyChromaticIndicesToSubSurfaces;
|
|
66
|
+
/**
|
|
67
|
+
* 구면/토릭 곡면의 z 교차(토릭이 구면을 관통) 방지를 위해
|
|
68
|
+
* 샘플링 영역에서 필요한 최소 중심두께를 계산합니다.
|
|
69
|
+
*/
|
|
70
|
+
private optimizeThickness;
|
|
71
|
+
/**
|
|
72
|
+
* 기준점(referencePoint.z)으로부터 토릭 꼭지(z)까지의 최소 간격을 확보합니다.
|
|
73
|
+
* - 기준점과 반대 방향으로 현재 토릭 꼭지가 놓인 쪽(sign)을 유지합니다.
|
|
74
|
+
* - 최소 간격은 "토릭–구면 거리(thickness) + 안전여유"입니다.
|
|
75
|
+
*/
|
|
76
|
+
private optimizeToricVertexZFromReference;
|
|
77
|
+
private samplingRadiusMm;
|
|
78
|
+
/**
|
|
79
|
+
* 구면 측 꼭지점 기준 sag(mm)
|
|
80
|
+
*/
|
|
81
|
+
private sphericalSagAtXY;
|
|
82
|
+
/**
|
|
83
|
+
* 토릭 측 꼭지점 기준 sag(mm)
|
|
84
|
+
*/
|
|
85
|
+
private toricSagAtXY;
|
|
86
|
+
private isOpticallyNeutral;
|
|
87
|
+
refract(ray: Ray): Ray | null;
|
|
88
|
+
incident(ray: Ray): Vector3 | null;
|
|
89
|
+
getOptimizedThicknessMm(): number;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=st-surface.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Vector2, Vector3 } from "three";
|
|
2
|
+
import Ray from "../ray/ray";
|
|
3
|
+
export type SurfaceProps = {
|
|
4
|
+
type: string;
|
|
5
|
+
name: string;
|
|
6
|
+
position: {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
z: number;
|
|
10
|
+
};
|
|
11
|
+
tilt: {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export default abstract class Surface {
|
|
17
|
+
protected type: string;
|
|
18
|
+
protected name: string;
|
|
19
|
+
protected incidentRays: Ray[];
|
|
20
|
+
protected refractedRays: Ray[];
|
|
21
|
+
protected position: Vector3;
|
|
22
|
+
protected tilt: Vector2;
|
|
23
|
+
protected meridians: {
|
|
24
|
+
angle: number;
|
|
25
|
+
d: number;
|
|
26
|
+
}[];
|
|
27
|
+
constructor(props: SurfaceProps);
|
|
28
|
+
abstract incident(ray: Ray): Vector3 | null;
|
|
29
|
+
abstract refract(ray: Ray): Ray | null;
|
|
30
|
+
clearTraceHistory(): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=surface.d.ts.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { Vector3 } from "three";
|
|
2
|
+
import { RefractiveIndexSpec } from "../optics/refractive-index";
|
|
3
|
+
import Ray from "../ray/ray";
|
|
4
|
+
import Surface from "./surface";
|
|
5
|
+
export type ToricSurfaceProps = {
|
|
6
|
+
type: "toric";
|
|
7
|
+
name: string;
|
|
8
|
+
position: {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
z: number;
|
|
12
|
+
};
|
|
13
|
+
tilt: {
|
|
14
|
+
x: number;
|
|
15
|
+
y: number;
|
|
16
|
+
};
|
|
17
|
+
r_axis: number;
|
|
18
|
+
r_perp: number;
|
|
19
|
+
axis_deg?: number;
|
|
20
|
+
n_before: RefractiveIndexSpec;
|
|
21
|
+
n_after: RefractiveIndexSpec;
|
|
22
|
+
};
|
|
23
|
+
export default class ToricSurface extends Surface {
|
|
24
|
+
private r_axis;
|
|
25
|
+
private r_perp;
|
|
26
|
+
private n_before;
|
|
27
|
+
private n_after;
|
|
28
|
+
private axisDeg;
|
|
29
|
+
constructor(props: ToricSurfaceProps);
|
|
30
|
+
private refractiveIndicesForRay;
|
|
31
|
+
/**
|
|
32
|
+
* Toric 면의 축(meridian) 회전을 위해 사용하는 삼각함수 값입니다.
|
|
33
|
+
* 축(axis) 회전은 axisDeg(도 단위)를 사용합니다.
|
|
34
|
+
*/
|
|
35
|
+
private axisTrig;
|
|
36
|
+
private worldQuaternion;
|
|
37
|
+
private worldPointToLocal;
|
|
38
|
+
private localPointToWorld;
|
|
39
|
+
private worldDirToLocal;
|
|
40
|
+
private localDirToWorld;
|
|
41
|
+
/**
|
|
42
|
+
* 월드 좌표계 (x, y)를 토릭 로컬 좌표계 (u, v)로 변환합니다.
|
|
43
|
+
* - u: 축 방향 meridian
|
|
44
|
+
* - v: 축에 수직인 meridian
|
|
45
|
+
*/
|
|
46
|
+
private toLocalUV;
|
|
47
|
+
/**
|
|
48
|
+
* 로컬 좌표계에서 계산한 sag 미분(dz/du, dz/dv)을
|
|
49
|
+
* 월드 좌표계의 기울기(dz/dx, dz/dy)로 다시 매핑합니다.
|
|
50
|
+
*/
|
|
51
|
+
private localDerivativesToWorld;
|
|
52
|
+
/**
|
|
53
|
+
* 반경으로부터 곡률(1/R)을 계산합니다.
|
|
54
|
+
* - 반경이 너무 크거나 무한대면 평면으로 간주하여 0 반환
|
|
55
|
+
* - 반경이 0에 너무 가까우면 비정상 값으로 NaN 반환
|
|
56
|
+
*/
|
|
57
|
+
private curvature;
|
|
58
|
+
/**
|
|
59
|
+
* 주어진 XY에서 토릭면의 기하정보를 계산합니다.
|
|
60
|
+
* - sag: 꼭지점 대비 z 높이
|
|
61
|
+
* - dzdx/dzdy: 면 기울기
|
|
62
|
+
* - normal: 2번째 매질 방향을 만들 때 사용할 기본 법선
|
|
63
|
+
*/
|
|
64
|
+
private geometryAtXY;
|
|
65
|
+
incident(ray: Ray): Vector3 | null;
|
|
66
|
+
refract(ray: Ray): Ray | null;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=toric-surface.d.ts.map
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "scax-engine",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Optical calculation engine for an eye model, with ESM, CJS, and UMD builds.",
|
|
5
|
+
"main": "./dist/scax-engine.cjs",
|
|
6
|
+
"module": "./dist/scax-engine.js",
|
|
7
|
+
"types": "./dist/types/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"!dist/**/*.map"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"clean": "rimraf dist",
|
|
14
|
+
"build": "npm run clean && tsc -p tsconfig.types.json && rollup -c rollup.config.mjs",
|
|
15
|
+
"test": "vitest run",
|
|
16
|
+
"test:watch": "vitest",
|
|
17
|
+
"prepublishOnly": "npm run test && npm run build"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/vizyman/scax-engine.git"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"math",
|
|
25
|
+
"calculator",
|
|
26
|
+
"typescript",
|
|
27
|
+
"library"
|
|
28
|
+
],
|
|
29
|
+
"author": "vizyman",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"type": "module",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./dist/types/index.d.ts",
|
|
35
|
+
"import": "./dist/scax-engine.js",
|
|
36
|
+
"require": "./dist/scax-engine.cjs",
|
|
37
|
+
"default": "./dist/scax-engine.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"unpkg": "./dist/scax-engine.umd.js",
|
|
41
|
+
"jsdelivr": "./dist/scax-engine.umd.js",
|
|
42
|
+
"bugs": {
|
|
43
|
+
"url": "https://github.com/vizyman/scax-engine/issues"
|
|
44
|
+
},
|
|
45
|
+
"homepage": "https://github.com/vizyman/scax-engine#readme",
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=20"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@rollup/plugin-commonjs": "^29.0.2",
|
|
51
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
52
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
53
|
+
"@types/node": "^25.6.0",
|
|
54
|
+
"@types/three": "^0.184.0",
|
|
55
|
+
"rimraf": "^6.1.3",
|
|
56
|
+
"rollup": "^4.60.2",
|
|
57
|
+
"tslib": "^2.8.1",
|
|
58
|
+
"typescript": "^6.0.3",
|
|
59
|
+
"vitest": "^4.1.5"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"three": "^0.184.0"
|
|
63
|
+
}
|
|
64
|
+
}
|