@vib3code/sdk 2.0.1 → 2.0.3-canary.0a63e71
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 +36 -0
- package/DOCS/AGENT_HARNESS_ARCHITECTURE.md +245 -0
- package/DOCS/ANDROID_DEPLOYMENT.md +59 -0
- package/DOCS/ARCHITECTURE.md +1 -0
- package/DOCS/CI_TESTING.md +2 -0
- package/DOCS/CLI_ONBOARDING.md +3 -1
- package/DOCS/CONTROL_REFERENCE.md +2 -0
- package/DOCS/CROSS_SITE_DESIGN_PATTERNS.md +119 -0
- package/DOCS/ENV_SETUP.md +2 -0
- package/DOCS/EPIC_SCROLL_EVENTS.md +775 -0
- package/DOCS/EXPANSION_DESIGN.md +979 -0
- package/DOCS/EXPANSION_DESIGN_ULTRA.md +389 -0
- package/DOCS/EXPORT_FORMATS.md +2 -0
- package/DOCS/GPU_DISPOSAL_GUIDE.md +2 -0
- package/DOCS/HANDOFF_LANDING_PAGE.md +156 -0
- package/DOCS/HANDOFF_SDK_DEVELOPMENT.md +495 -0
- package/DOCS/LICENSING_TIERS.md +2 -0
- package/DOCS/MASTER_PLAN_2026-01-31.md +4 -2
- package/DOCS/MULTIVIZ_CHOREOGRAPHY_PATTERNS.md +939 -0
- package/DOCS/OBS_SETUP_GUIDE.md +2 -0
- package/DOCS/OPTIMIZATION_PLAN_MATH.md +119 -0
- package/DOCS/PRODUCT_STRATEGY.md +65 -0
- package/DOCS/PROJECT_SETUP.md +2 -0
- package/DOCS/README.md +105 -0
- package/DOCS/REFERENCE_SCROLL_ANALYSIS.md +99 -0
- package/DOCS/RENDERER_LIFECYCLE.md +2 -0
- package/DOCS/REPO_MANIFEST.md +2 -0
- package/DOCS/ROADMAP.md +113 -0
- package/DOCS/SCROLL_TIMELINE_v3.md +271 -0
- package/DOCS/SITE_REFACTOR_PLAN.md +102 -0
- package/DOCS/STATUS.md +26 -0
- package/DOCS/SYSTEM_INVENTORY.md +37 -32
- package/DOCS/TELEMETRY_EXPORTS.md +2 -0
- package/DOCS/VISUAL_ANALYSIS_CLICKERSS.md +87 -0
- package/DOCS/VISUAL_ANALYSIS_FACETAD.md +135 -0
- package/DOCS/VISUAL_ANALYSIS_SIMONE.md +97 -0
- package/DOCS/VISUAL_ANALYSIS_TABLESIDE.md +88 -0
- package/DOCS/WEBGPU_STATUS.md +121 -38
- package/DOCS/XR_BENCHMARKS.md +2 -0
- package/DOCS/archive/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +1 -0
- package/DOCS/archive/DEV_TRACK_ANALYSIS.md +1 -0
- package/DOCS/archive/DEV_TRACK_PLAN_2026-01-07.md +1 -0
- package/DOCS/archive/SESSION_014_PLAN.md +1 -0
- package/DOCS/archive/SESSION_LOG_2026-01-07.md +1 -0
- package/DOCS/archive/STRATEGIC_BLUEPRINT_2026-01-07.md +1 -0
- package/DOCS/archive/SYSTEM_AUDIT_2026-01-30.md +1 -0
- package/DOCS/archive/WEBGPU_STATUS_2026-02-15_STALE.md +1 -0
- package/DOCS/{DEV_TRACK_SESSION_2026-01-31.md → dev-tracks/DEV_TRACK_SESSION_2026-01-31.md} +3 -1
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-06.md +233 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-13.md +129 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-15.md +144 -0
- package/DOCS/dev-tracks/DEV_TRACK_SESSION_2026-02-16.md +110 -0
- package/DOCS/dev-tracks/PERF_UPGRADE_2026-02-16.md +310 -0
- package/DOCS/dev-tracks/README.md +12 -0
- package/README.md +26 -13
- package/cpp/CMakeLists.txt +236 -0
- package/cpp/bindings/embind.cpp +269 -0
- package/cpp/build.sh +129 -0
- package/cpp/geometry/Crystal.cpp +103 -0
- package/cpp/geometry/Fractal.cpp +136 -0
- package/cpp/geometry/GeometryGenerator.cpp +262 -0
- package/cpp/geometry/KleinBottle.cpp +71 -0
- package/cpp/geometry/Sphere.cpp +134 -0
- package/cpp/geometry/Tesseract.cpp +94 -0
- package/cpp/geometry/Tetrahedron.cpp +83 -0
- package/cpp/geometry/Torus.cpp +65 -0
- package/cpp/geometry/WarpFunctions.cpp +238 -0
- package/cpp/geometry/Wave.cpp +85 -0
- package/cpp/include/vib3_ffi.h +238 -0
- package/cpp/math/Mat4x4.cpp +409 -0
- package/cpp/math/Mat4x4.hpp +209 -0
- package/cpp/math/Projection.cpp +142 -0
- package/cpp/math/Projection.hpp +148 -0
- package/cpp/math/Rotor4D.cpp +322 -0
- package/cpp/math/Rotor4D.hpp +204 -0
- package/cpp/math/Vec4.cpp +303 -0
- package/cpp/math/Vec4.hpp +225 -0
- package/cpp/src/vib3_ffi.cpp +607 -0
- package/cpp/tests/Geometry_test.cpp +213 -0
- package/cpp/tests/Mat4x4_test.cpp +494 -0
- package/cpp/tests/Projection_test.cpp +298 -0
- package/cpp/tests/Rotor4D_test.cpp +423 -0
- package/cpp/tests/Vec4_test.cpp +489 -0
- package/docs/webgpu-live.html +1 -1
- package/package.json +41 -30
- package/src/agent/index.js +1 -3
- package/src/agent/mcp/MCPServer.js +1220 -144
- package/src/agent/mcp/index.js +1 -1
- package/src/agent/mcp/stdio-server.js +264 -0
- package/src/agent/mcp/tools.js +498 -31
- package/src/cli/index.js +431 -47
- package/src/core/CanvasManager.js +97 -204
- package/src/core/ErrorReporter.js +1 -1
- package/src/core/Parameters.js +1 -1
- package/src/core/VIB3Engine.js +93 -4
- package/src/core/VitalitySystem.js +53 -0
- package/src/core/index.js +18 -0
- package/src/core/renderers/FacetedRendererAdapter.js +10 -9
- package/src/core/renderers/HolographicRendererAdapter.js +13 -9
- package/src/core/renderers/QuantumRendererAdapter.js +11 -7
- package/src/creative/AestheticMapper.js +628 -0
- package/src/creative/ChoreographyPlayer.js +481 -0
- package/src/creative/index.js +11 -0
- package/src/experimental/GameLoop.js +72 -0
- package/src/experimental/LatticePhysics.js +100 -0
- package/src/experimental/LiveDirector.js +143 -0
- package/src/experimental/PlayerController4D.js +154 -0
- package/src/experimental/VIB3Actor.js +138 -0
- package/src/experimental/VIB3Compositor.js +117 -0
- package/src/experimental/VIB3Link.js +122 -0
- package/src/experimental/VIB3Orchestrator.js +146 -0
- package/src/experimental/VIB3Universe.js +109 -0
- package/src/experimental/demos/CrystalLabyrinth.js +202 -0
- package/src/export/TradingCardManager.js +3 -4
- package/src/export/index.js +11 -1
- package/src/faceted/FacetedSystem.js +260 -394
- package/src/games/glyph-war/GlyphWarVisualizer.js +641 -0
- package/src/geometry/generators/Crystal.js +2 -2
- package/src/geometry/warp/HypersphereCore.js +53 -24
- package/src/holograms/HolographicVisualizer.js +84 -98
- package/src/holograms/RealHolographicSystem.js +194 -43
- package/src/math/Mat4x4.js +308 -105
- package/src/math/Rotor4D.js +124 -40
- package/src/math/Vec4.js +200 -103
- package/src/math/index.js +7 -7
- package/src/polychora/PolychoraSystem.js +77 -0
- package/src/quantum/QuantumEngine.js +103 -66
- package/src/quantum/QuantumVisualizer.js +31 -22
- package/src/reactivity/index.js +3 -5
- package/src/render/LayerPresetManager.js +372 -0
- package/src/render/LayerReactivityBridge.js +344 -0
- package/src/render/LayerRelationshipGraph.js +610 -0
- package/src/render/MultiCanvasBridge.js +148 -25
- package/src/render/ShaderLoader.js +38 -0
- package/src/render/ShaderProgram.js +4 -4
- package/src/render/UnifiedRenderBridge.js +4 -1
- package/src/render/backends/WebGPUBackend.js +8 -4
- package/src/render/index.js +27 -2
- package/src/scene/Node4D.js +74 -24
- package/src/scene/index.js +4 -4
- package/src/shaders/common/geometry24.glsl +65 -0
- package/src/shaders/common/geometry24.wgsl +54 -0
- package/src/shaders/common/rotation4d.glsl +4 -4
- package/src/shaders/common/rotation4d.wgsl +2 -2
- package/src/shaders/common/uniforms.wgsl +15 -8
- package/src/shaders/faceted/faceted.frag.glsl +220 -80
- package/src/shaders/faceted/faceted.frag.wgsl +144 -90
- package/src/shaders/holographic/holographic.frag.glsl +28 -9
- package/src/shaders/holographic/holographic.frag.wgsl +112 -41
- package/src/shaders/quantum/quantum.frag.glsl +1 -0
- package/src/shaders/quantum/quantum.frag.wgsl +6 -4
- package/src/testing/ParallelTestFramework.js +2 -2
- package/src/ui/adaptive/renderers/webgpu/WebGPURenderer.ts +2 -2
- package/src/viewer/GalleryUI.js +17 -0
- package/src/viewer/ViewerPortal.js +2 -2
- package/src/viewer/index.js +1 -1
- package/tools/headless-renderer.js +258 -0
- package/tools/shader-sync-verify.js +14 -8
- package/tools/site-analysis/all-reports.json +32 -0
- package/tools/site-analysis/combined-analysis.md +50 -0
- package/tools/site-analyzer.mjs +779 -0
- package/tools/visual-catalog/capture.js +276 -0
- package/tools/visual-catalog/composite.js +138 -0
- package/types/adaptive-sdk.d.ts +204 -5
- package/types/agent/cli.d.ts +78 -0
- package/types/agent/index.d.ts +18 -0
- package/types/agent/mcp.d.ts +87 -0
- package/types/agent/telemetry.d.ts +190 -0
- package/types/core/VIB3Engine.d.ts +26 -0
- package/types/core/index.d.ts +261 -0
- package/types/creative/AestheticMapper.d.ts +72 -0
- package/types/creative/ChoreographyPlayer.d.ts +96 -0
- package/types/creative/index.d.ts +17 -0
- package/types/export/index.d.ts +243 -0
- package/types/geometry/index.d.ts +164 -0
- package/types/math/index.d.ts +214 -0
- package/types/render/LayerPresetManager.d.ts +78 -0
- package/types/render/LayerReactivityBridge.d.ts +85 -0
- package/types/render/LayerRelationshipGraph.d.ts +174 -0
- package/types/render/index.d.ts +3 -0
- package/types/scene/index.d.ts +204 -0
- package/types/systems/index.d.ts +244 -0
- package/types/variations/index.d.ts +62 -0
- package/types/viewer/index.d.ts +225 -0
- package/DOCS/BLUEPRINT_EXECUTION_PLAN_2026-01-07.md +0 -34
- package/DOCS/DEV_TRACK_ANALYSIS.md +0 -77
- package/DOCS/DEV_TRACK_PLAN_2026-01-07.md +0 -42
- package/DOCS/SESSION_014_PLAN.md +0 -195
- package/DOCS/SESSION_LOG_2026-01-07.md +0 -56
- package/DOCS/STRATEGIC_BLUEPRINT_2026-01-07.md +0 -72
- package/DOCS/SYSTEM_AUDIT_2026-01-30.md +0 -738
- /package/src/viewer/{ReactivityManager.js → ViewerInputHandler.js} +0 -0
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GeometryGenerator.cpp - Main Geometry Factory
|
|
3
|
+
*
|
|
4
|
+
* Dispatches to individual geometry generators based on geometry index.
|
|
5
|
+
* Uses the VIB3+ encoding: index = coreType * 8 + baseGeometry
|
|
6
|
+
*
|
|
7
|
+
* Core types:
|
|
8
|
+
* 0 = Base (index 0-7) - Pure base geometry
|
|
9
|
+
* 1 = Hypersphere (index 8-15) - Projected onto 3-sphere
|
|
10
|
+
* 2 = Hypertetrahedron (index 16-23) - Warped toward pentatope
|
|
11
|
+
*
|
|
12
|
+
* Base geometries (0-7):
|
|
13
|
+
* 0 = Tetrahedron 4 = Klein Bottle
|
|
14
|
+
* 1 = Hypercube 5 = Fractal
|
|
15
|
+
* 2 = Sphere 6 = Wave
|
|
16
|
+
* 3 = Torus 7 = Crystal
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
#include "math/Vec4.hpp"
|
|
20
|
+
#include <vector>
|
|
21
|
+
#include <algorithm>
|
|
22
|
+
|
|
23
|
+
namespace vib3 {
|
|
24
|
+
|
|
25
|
+
// ---- Forward declarations of individual generators ----
|
|
26
|
+
|
|
27
|
+
// geometry/Tetrahedron.cpp
|
|
28
|
+
std::vector<Vec4> generateTetrahedron(int resolution) noexcept;
|
|
29
|
+
|
|
30
|
+
// geometry/Tesseract.cpp
|
|
31
|
+
std::vector<Vec4> generateTesseract(int resolution) noexcept;
|
|
32
|
+
|
|
33
|
+
// geometry/Sphere.cpp
|
|
34
|
+
std::vector<Vec4> generateSphere(int resolution) noexcept;
|
|
35
|
+
|
|
36
|
+
// geometry/Torus.cpp
|
|
37
|
+
std::vector<Vec4> generateTorus(int resolution) noexcept;
|
|
38
|
+
|
|
39
|
+
// geometry/KleinBottle.cpp
|
|
40
|
+
std::vector<Vec4> generateKleinBottle(int resolution) noexcept;
|
|
41
|
+
|
|
42
|
+
// geometry/Fractal.cpp
|
|
43
|
+
std::vector<Vec4> generateFractal(int resolution) noexcept;
|
|
44
|
+
|
|
45
|
+
// geometry/Wave.cpp
|
|
46
|
+
std::vector<Vec4> generateWave(int resolution) noexcept;
|
|
47
|
+
|
|
48
|
+
// geometry/Crystal.cpp
|
|
49
|
+
std::vector<Vec4> generateCrystal(int resolution) noexcept;
|
|
50
|
+
|
|
51
|
+
// geometry/WarpFunctions.cpp
|
|
52
|
+
Vec4 warpHypersphere(Vec4 point, float radius) noexcept;
|
|
53
|
+
std::vector<Vec4> warpHypersphereBatch(const std::vector<Vec4>& points, float radius) noexcept;
|
|
54
|
+
Vec4 warpHypertetra(Vec4 point) noexcept;
|
|
55
|
+
std::vector<Vec4> warpHypertetraBatch(const std::vector<Vec4>& points) noexcept;
|
|
56
|
+
|
|
57
|
+
// ---- Geometry index encoding ----
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Maximum valid geometry index (3 core types x 8 base geometries - 1).
|
|
61
|
+
*/
|
|
62
|
+
constexpr int kMaxGeometryIndex = 23;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Number of base geometry types.
|
|
66
|
+
*/
|
|
67
|
+
constexpr int kBaseGeometryCount = 8;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Decompose a geometry index into core type and base geometry.
|
|
71
|
+
*
|
|
72
|
+
* @param geometryIndex Combined index (0-23)
|
|
73
|
+
* @param coreType Output: 0=Base, 1=Hypersphere, 2=Hypertetrahedron
|
|
74
|
+
* @param baseGeometry Output: 0-7 base geometry type
|
|
75
|
+
*/
|
|
76
|
+
constexpr void decodeGeometryIndex(int geometryIndex,
|
|
77
|
+
int& coreType,
|
|
78
|
+
int& baseGeometry) noexcept {
|
|
79
|
+
coreType = geometryIndex / kBaseGeometryCount;
|
|
80
|
+
baseGeometry = geometryIndex % kBaseGeometryCount;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Encode core type and base geometry into a geometry index.
|
|
85
|
+
*
|
|
86
|
+
* @param coreType 0=Base, 1=Hypersphere, 2=Hypertetrahedron
|
|
87
|
+
* @param baseGeometry 0-7 base geometry type
|
|
88
|
+
* @return Combined geometry index (0-23)
|
|
89
|
+
*/
|
|
90
|
+
constexpr int encodeGeometryIndex(int coreType, int baseGeometry) noexcept {
|
|
91
|
+
return coreType * kBaseGeometryCount + baseGeometry;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ---- Internal dispatch ----
|
|
95
|
+
|
|
96
|
+
namespace {
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Generate base geometry vertices for a given base type.
|
|
100
|
+
*/
|
|
101
|
+
std::vector<Vec4> generateBaseGeometry(int baseGeometry, int resolution) noexcept {
|
|
102
|
+
switch (baseGeometry) {
|
|
103
|
+
case 0: return generateTetrahedron(resolution);
|
|
104
|
+
case 1: return generateTesseract(resolution);
|
|
105
|
+
case 2: return generateSphere(resolution);
|
|
106
|
+
case 3: return generateTorus(resolution);
|
|
107
|
+
case 4: return generateKleinBottle(resolution);
|
|
108
|
+
case 5: return generateFractal(resolution);
|
|
109
|
+
case 6: return generateWave(resolution);
|
|
110
|
+
case 7: return generateCrystal(resolution);
|
|
111
|
+
default:
|
|
112
|
+
// Unknown base geometry, return empty
|
|
113
|
+
return {};
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Apply core type warp to a set of base vertices.
|
|
119
|
+
*/
|
|
120
|
+
std::vector<Vec4> applyWarp(int coreType, std::vector<Vec4> vertices) noexcept {
|
|
121
|
+
switch (coreType) {
|
|
122
|
+
case 0:
|
|
123
|
+
// Base: no warp
|
|
124
|
+
return vertices;
|
|
125
|
+
|
|
126
|
+
case 1:
|
|
127
|
+
// Hypersphere: project all vertices onto S3
|
|
128
|
+
return warpHypersphereBatch(vertices, 1.0f);
|
|
129
|
+
|
|
130
|
+
case 2:
|
|
131
|
+
// Hypertetrahedron: warp toward pentatope vertices
|
|
132
|
+
return warpHypertetraBatch(vertices);
|
|
133
|
+
|
|
134
|
+
default:
|
|
135
|
+
// Unknown core type, return unmodified
|
|
136
|
+
return vertices;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
} // anonymous namespace
|
|
141
|
+
|
|
142
|
+
// ---- Public API ----
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Generate 4D geometry for a given geometry index.
|
|
146
|
+
*
|
|
147
|
+
* This is the main entry point for the geometry library. It decodes the
|
|
148
|
+
* geometry index into a base geometry type and core type warp, generates
|
|
149
|
+
* the base geometry, and then applies the appropriate warp transformation.
|
|
150
|
+
*
|
|
151
|
+
* @param geometryIndex Combined geometry index (0-23)
|
|
152
|
+
* - 0-7: Base geometries (no warp)
|
|
153
|
+
* - 8-15: Hypersphere-warped geometries
|
|
154
|
+
* - 16-23: Hypertetrahedron-warped geometries
|
|
155
|
+
*
|
|
156
|
+
* @param resolution Controls the level of detail. Higher values produce
|
|
157
|
+
* more vertices. The exact meaning varies by geometry type but generally
|
|
158
|
+
* represents subdivisions per dimension. Typical range: 4-100.
|
|
159
|
+
*
|
|
160
|
+
* @return Vector of 4D vertices. Empty if geometryIndex is out of range.
|
|
161
|
+
*/
|
|
162
|
+
std::vector<Vec4> generateGeometry(int geometryIndex, int resolution) noexcept {
|
|
163
|
+
// Clamp to valid range
|
|
164
|
+
if (geometryIndex < 0 || geometryIndex > kMaxGeometryIndex) {
|
|
165
|
+
return {};
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
if (resolution < 2) resolution = 2;
|
|
169
|
+
if (resolution > 256) resolution = 256;
|
|
170
|
+
|
|
171
|
+
int coreType = 0;
|
|
172
|
+
int baseGeometry = 0;
|
|
173
|
+
decodeGeometryIndex(geometryIndex, coreType, baseGeometry);
|
|
174
|
+
|
|
175
|
+
// Generate base geometry
|
|
176
|
+
std::vector<Vec4> vertices = generateBaseGeometry(baseGeometry, resolution);
|
|
177
|
+
|
|
178
|
+
// Apply core type warp
|
|
179
|
+
return applyWarp(coreType, std::move(vertices));
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Get the name string for a base geometry type.
|
|
184
|
+
*
|
|
185
|
+
* @param baseGeometry Base geometry index (0-7)
|
|
186
|
+
* @return Human-readable name, or "Unknown" if out of range
|
|
187
|
+
*/
|
|
188
|
+
const char* getBaseGeometryName(int baseGeometry) noexcept {
|
|
189
|
+
switch (baseGeometry) {
|
|
190
|
+
case 0: return "Tetrahedron";
|
|
191
|
+
case 1: return "Hypercube";
|
|
192
|
+
case 2: return "Sphere";
|
|
193
|
+
case 3: return "Torus";
|
|
194
|
+
case 4: return "Klein Bottle";
|
|
195
|
+
case 5: return "Fractal";
|
|
196
|
+
case 6: return "Wave";
|
|
197
|
+
case 7: return "Crystal";
|
|
198
|
+
default: return "Unknown";
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Get the name string for a core type.
|
|
204
|
+
*
|
|
205
|
+
* @param coreType Core type index (0-2)
|
|
206
|
+
* @return Human-readable name, or "Unknown" if out of range
|
|
207
|
+
*/
|
|
208
|
+
const char* getCoreTypeName(int coreType) noexcept {
|
|
209
|
+
switch (coreType) {
|
|
210
|
+
case 0: return "Base";
|
|
211
|
+
case 1: return "Hypersphere";
|
|
212
|
+
case 2: return "Hypertetrahedron";
|
|
213
|
+
default: return "Unknown";
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Get a full descriptive name for a geometry index.
|
|
219
|
+
*
|
|
220
|
+
* Combines core type and base geometry names, e.g.
|
|
221
|
+
* "Hypersphere Torus" for index 11.
|
|
222
|
+
*
|
|
223
|
+
* @param geometryIndex Combined index (0-23)
|
|
224
|
+
* @param buffer Output buffer (must be at least 64 chars)
|
|
225
|
+
* @param bufferSize Size of the output buffer
|
|
226
|
+
* @return Number of characters written (excluding null terminator)
|
|
227
|
+
*/
|
|
228
|
+
int getGeometryName(int geometryIndex, char* buffer, int bufferSize) noexcept {
|
|
229
|
+
if (!buffer || bufferSize <= 0) return 0;
|
|
230
|
+
|
|
231
|
+
int coreType = 0;
|
|
232
|
+
int baseGeometry = 0;
|
|
233
|
+
decodeGeometryIndex(geometryIndex, coreType, baseGeometry);
|
|
234
|
+
|
|
235
|
+
const char* coreName = getCoreTypeName(coreType);
|
|
236
|
+
const char* baseName = getBaseGeometryName(baseGeometry);
|
|
237
|
+
|
|
238
|
+
int written = 0;
|
|
239
|
+
|
|
240
|
+
if (coreType == 0) {
|
|
241
|
+
// Base type: just use geometry name
|
|
242
|
+
for (int i = 0; baseName[i] != '\0' && written < bufferSize - 1; ++i) {
|
|
243
|
+
buffer[written++] = baseName[i];
|
|
244
|
+
}
|
|
245
|
+
} else {
|
|
246
|
+
// Compound name: "CoreType BaseGeometry"
|
|
247
|
+
for (int i = 0; coreName[i] != '\0' && written < bufferSize - 1; ++i) {
|
|
248
|
+
buffer[written++] = coreName[i];
|
|
249
|
+
}
|
|
250
|
+
if (written < bufferSize - 1) {
|
|
251
|
+
buffer[written++] = ' ';
|
|
252
|
+
}
|
|
253
|
+
for (int i = 0; baseName[i] != '\0' && written < bufferSize - 1; ++i) {
|
|
254
|
+
buffer[written++] = baseName[i];
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
buffer[written] = '\0';
|
|
259
|
+
return written;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
} // namespace vib3
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KleinBottle.cpp - Non-Orientable Surface in 4D
|
|
3
|
+
*
|
|
4
|
+
* Generates points on the Klein bottle immersed in R4.
|
|
5
|
+
*
|
|
6
|
+
* The Klein bottle cannot be embedded in R3 without self-intersection,
|
|
7
|
+
* but it can be properly embedded in R4. We use the standard
|
|
8
|
+
* figure-eight parametrization lifted into the 4th dimension:
|
|
9
|
+
*
|
|
10
|
+
* x = (a + b*cos(v)) * cos(u)
|
|
11
|
+
* y = (a + b*cos(v)) * sin(u)
|
|
12
|
+
* z = b * sin(v) * cos(u/2)
|
|
13
|
+
* w = b * sin(v) * sin(u/2)
|
|
14
|
+
*
|
|
15
|
+
* where u in [0, 2*pi), v in [0, 2*pi), and a > b > 0.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
#include "math/Vec4.hpp"
|
|
19
|
+
#include <vector>
|
|
20
|
+
#include <cmath>
|
|
21
|
+
#include <numbers>
|
|
22
|
+
|
|
23
|
+
namespace vib3 {
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Generate Klein bottle surface points in 4D.
|
|
27
|
+
*
|
|
28
|
+
* Uses the figure-eight immersion lifted to R4, which avoids
|
|
29
|
+
* the self-intersection that occurs in R3.
|
|
30
|
+
*
|
|
31
|
+
* @param resolution Number of subdivisions for each parameter (total points = resolution^2)
|
|
32
|
+
* @return Vector of 4D points on the Klein bottle surface
|
|
33
|
+
*/
|
|
34
|
+
std::vector<Vec4> generateKleinBottle(int resolution) noexcept {
|
|
35
|
+
if (resolution < 4) resolution = 4;
|
|
36
|
+
|
|
37
|
+
constexpr float twoPi = 2.0f * std::numbers::pi_v<float>;
|
|
38
|
+
constexpr float a = 2.0f; // Major radius
|
|
39
|
+
constexpr float b = 1.0f; // Minor radius
|
|
40
|
+
|
|
41
|
+
std::vector<Vec4> vertices;
|
|
42
|
+
vertices.reserve(static_cast<size_t>(resolution) * static_cast<size_t>(resolution));
|
|
43
|
+
|
|
44
|
+
for (int iu = 0; iu < resolution; ++iu) {
|
|
45
|
+
float u = twoPi * static_cast<float>(iu) / static_cast<float>(resolution);
|
|
46
|
+
float cosU = std::cos(u);
|
|
47
|
+
float sinU = std::sin(u);
|
|
48
|
+
float halfU = u * 0.5f;
|
|
49
|
+
float cosHalfU = std::cos(halfU);
|
|
50
|
+
float sinHalfU = std::sin(halfU);
|
|
51
|
+
|
|
52
|
+
for (int iv = 0; iv < resolution; ++iv) {
|
|
53
|
+
float v = twoPi * static_cast<float>(iv) / static_cast<float>(resolution);
|
|
54
|
+
float cosV = std::cos(v);
|
|
55
|
+
float sinV = std::sin(v);
|
|
56
|
+
|
|
57
|
+
float r = a + b * cosV;
|
|
58
|
+
|
|
59
|
+
vertices.emplace_back(
|
|
60
|
+
r * cosU,
|
|
61
|
+
r * sinU,
|
|
62
|
+
b * sinV * cosHalfU,
|
|
63
|
+
b * sinV * sinHalfU
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return vertices;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
} // namespace vib3
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sphere.cpp - 3-Sphere (S3) Surface Points
|
|
3
|
+
*
|
|
4
|
+
* Generates points on the 3-sphere (hypersphere) in 4D using
|
|
5
|
+
* Hopf coordinates (psi, theta, phi) parametrization.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "math/Vec4.hpp"
|
|
9
|
+
#include <vector>
|
|
10
|
+
#include <cmath>
|
|
11
|
+
#include <numbers>
|
|
12
|
+
|
|
13
|
+
namespace vib3 {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Generate points on S3 using Hopf coordinate parametrization.
|
|
17
|
+
*
|
|
18
|
+
* The 3-sphere is parametrized by three angles:
|
|
19
|
+
* x = cos(psi) * cos(theta)
|
|
20
|
+
* y = cos(psi) * sin(theta)
|
|
21
|
+
* z = sin(psi) * cos(phi)
|
|
22
|
+
* w = sin(psi) * sin(phi)
|
|
23
|
+
*
|
|
24
|
+
* where psi in [0, pi/2], theta in [0, 2pi), phi in [0, 2pi).
|
|
25
|
+
*
|
|
26
|
+
* @param resolution Controls sampling density. Total points = resolution^2 * resolution/2
|
|
27
|
+
* @return Vector of 4D points on the unit 3-sphere
|
|
28
|
+
*/
|
|
29
|
+
std::vector<Vec4> generateSphere(int resolution) noexcept {
|
|
30
|
+
if (resolution < 4) resolution = 4;
|
|
31
|
+
|
|
32
|
+
constexpr float pi = std::numbers::pi_v<float>;
|
|
33
|
+
constexpr float twoPi = 2.0f * std::numbers::pi_v<float>;
|
|
34
|
+
constexpr float halfPi = std::numbers::pi_v<float> / 2.0f;
|
|
35
|
+
|
|
36
|
+
// Number of steps for each angle
|
|
37
|
+
int psiSteps = resolution / 2;
|
|
38
|
+
int thetaSteps = resolution;
|
|
39
|
+
int phiSteps = resolution;
|
|
40
|
+
|
|
41
|
+
if (psiSteps < 2) psiSteps = 2;
|
|
42
|
+
|
|
43
|
+
std::vector<Vec4> vertices;
|
|
44
|
+
vertices.reserve(static_cast<size_t>(psiSteps) *
|
|
45
|
+
static_cast<size_t>(thetaSteps) *
|
|
46
|
+
static_cast<size_t>(phiSteps));
|
|
47
|
+
|
|
48
|
+
for (int ip = 0; ip < psiSteps; ++ip) {
|
|
49
|
+
float psi = halfPi * static_cast<float>(ip) / static_cast<float>(psiSteps - 1);
|
|
50
|
+
float cosPsi = std::cos(psi);
|
|
51
|
+
float sinPsi = std::sin(psi);
|
|
52
|
+
|
|
53
|
+
for (int it = 0; it < thetaSteps; ++it) {
|
|
54
|
+
float theta = twoPi * static_cast<float>(it) / static_cast<float>(thetaSteps);
|
|
55
|
+
float cosTheta = std::cos(theta);
|
|
56
|
+
float sinTheta = std::sin(theta);
|
|
57
|
+
|
|
58
|
+
for (int iphi = 0; iphi < phiSteps; ++iphi) {
|
|
59
|
+
float phi = twoPi * static_cast<float>(iphi) / static_cast<float>(phiSteps);
|
|
60
|
+
float cosPhi = std::cos(phi);
|
|
61
|
+
float sinPhi = std::sin(phi);
|
|
62
|
+
|
|
63
|
+
vertices.emplace_back(
|
|
64
|
+
cosPsi * cosTheta,
|
|
65
|
+
cosPsi * sinTheta,
|
|
66
|
+
sinPsi * cosPhi,
|
|
67
|
+
sinPsi * sinPhi
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return vertices;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Generate points on S3 using the Hopf fibration structure.
|
|
78
|
+
*
|
|
79
|
+
* The Hopf fibration maps S3 -> S2, with each fiber being a great circle.
|
|
80
|
+
* This produces points organized along Hopf fibers, useful for
|
|
81
|
+
* visualizing the fibration structure.
|
|
82
|
+
*
|
|
83
|
+
* @param numFibers Number of base points on S2
|
|
84
|
+
* @param pointsPerFiber Number of points along each Hopf circle
|
|
85
|
+
* @return Vector of 4D points on the unit 3-sphere
|
|
86
|
+
*/
|
|
87
|
+
std::vector<Vec4> generateHopfFibration(int numFibers, int pointsPerFiber) noexcept {
|
|
88
|
+
if (numFibers < 4) numFibers = 4;
|
|
89
|
+
if (pointsPerFiber < 8) pointsPerFiber = 8;
|
|
90
|
+
|
|
91
|
+
constexpr float pi = std::numbers::pi_v<float>;
|
|
92
|
+
constexpr float twoPi = 2.0f * std::numbers::pi_v<float>;
|
|
93
|
+
|
|
94
|
+
// Distribute base points on S2 using a spiral
|
|
95
|
+
int sqrtFibers = static_cast<int>(std::sqrt(static_cast<float>(numFibers)));
|
|
96
|
+
if (sqrtFibers < 2) sqrtFibers = 2;
|
|
97
|
+
|
|
98
|
+
std::vector<Vec4> vertices;
|
|
99
|
+
vertices.reserve(static_cast<size_t>(numFibers) * static_cast<size_t>(pointsPerFiber));
|
|
100
|
+
|
|
101
|
+
for (int fi = 0; fi < sqrtFibers; ++fi) {
|
|
102
|
+
float baseTheta = pi * static_cast<float>(fi) / static_cast<float>(sqrtFibers - 1);
|
|
103
|
+
|
|
104
|
+
for (int fj = 0; fj < sqrtFibers; ++fj) {
|
|
105
|
+
float basePhi = twoPi * static_cast<float>(fj) / static_cast<float>(sqrtFibers);
|
|
106
|
+
|
|
107
|
+
// Base point on S2
|
|
108
|
+
float halfTheta = baseTheta * 0.5f;
|
|
109
|
+
float cosHalf = std::cos(halfTheta);
|
|
110
|
+
float sinHalf = std::sin(halfTheta);
|
|
111
|
+
|
|
112
|
+
// Trace the Hopf fiber (great circle in S3) for this base point
|
|
113
|
+
for (int p = 0; p < pointsPerFiber; ++p) {
|
|
114
|
+
float t = twoPi * static_cast<float>(p) / static_cast<float>(pointsPerFiber);
|
|
115
|
+
|
|
116
|
+
float cosT = std::cos(t);
|
|
117
|
+
float sinT = std::sin(t);
|
|
118
|
+
float cosBP = std::cos(basePhi + t);
|
|
119
|
+
float sinBP = std::sin(basePhi + t);
|
|
120
|
+
|
|
121
|
+
vertices.emplace_back(
|
|
122
|
+
cosHalf * cosT,
|
|
123
|
+
cosHalf * sinT,
|
|
124
|
+
sinHalf * cosBP,
|
|
125
|
+
sinHalf * sinBP
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return vertices;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
} // namespace vib3
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tesseract.cpp - 4D Hypercube Geometry
|
|
3
|
+
*
|
|
4
|
+
* Generates the 16 vertices and 32 edges of a tesseract (4D cube).
|
|
5
|
+
* Vertices are at all combinations of (+-1, +-1, +-1, +-1).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "math/Vec4.hpp"
|
|
9
|
+
#include <vector>
|
|
10
|
+
#include <cstdint>
|
|
11
|
+
|
|
12
|
+
namespace vib3 {
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generate the 16 vertices of a tesseract.
|
|
16
|
+
*
|
|
17
|
+
* A tesseract has vertices at every combination of (+-1, +-1, +-1, +-1).
|
|
18
|
+
*/
|
|
19
|
+
std::vector<Vec4> generateTesseractVertices() noexcept {
|
|
20
|
+
std::vector<Vec4> vertices;
|
|
21
|
+
vertices.reserve(16);
|
|
22
|
+
|
|
23
|
+
for (uint8_t i = 0; i < 16; ++i) {
|
|
24
|
+
float x = (i & 1) ? 1.0f : -1.0f;
|
|
25
|
+
float y = (i & 2) ? 1.0f : -1.0f;
|
|
26
|
+
float z = (i & 4) ? 1.0f : -1.0f;
|
|
27
|
+
float w = (i & 8) ? 1.0f : -1.0f;
|
|
28
|
+
vertices.emplace_back(x, y, z, w);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return vertices;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Edge pair for a tesseract (indices into vertex array).
|
|
36
|
+
*/
|
|
37
|
+
struct Edge {
|
|
38
|
+
int a, b;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Generate the 32 edges of a tesseract.
|
|
43
|
+
*
|
|
44
|
+
* Two vertices share an edge if and only if they differ in exactly one coordinate.
|
|
45
|
+
*/
|
|
46
|
+
std::vector<Edge> generateTesseractEdges() noexcept {
|
|
47
|
+
std::vector<Edge> edges;
|
|
48
|
+
edges.reserve(32);
|
|
49
|
+
|
|
50
|
+
for (int i = 0; i < 16; ++i) {
|
|
51
|
+
for (int bit = 0; bit < 4; ++bit) {
|
|
52
|
+
int j = i ^ (1 << bit);
|
|
53
|
+
if (j > i) {
|
|
54
|
+
edges.push_back({i, j});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return edges;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Generate tesseract geometry with edge interpolation.
|
|
64
|
+
*
|
|
65
|
+
* Returns vertices along all edges, creating a wireframe mesh.
|
|
66
|
+
* Each edge is subdivided into `resolution` segments, generating
|
|
67
|
+
* intermediate points via linear interpolation.
|
|
68
|
+
*
|
|
69
|
+
* @param resolution Number of subdivisions per edge (minimum 2)
|
|
70
|
+
* @return Vector of 4D points along all tesseract edges
|
|
71
|
+
*/
|
|
72
|
+
std::vector<Vec4> generateTesseract(int resolution) noexcept {
|
|
73
|
+
if (resolution < 2) resolution = 2;
|
|
74
|
+
|
|
75
|
+
auto baseVertices = generateTesseractVertices();
|
|
76
|
+
auto edges = generateTesseractEdges();
|
|
77
|
+
|
|
78
|
+
std::vector<Vec4> vertices;
|
|
79
|
+
vertices.reserve(static_cast<size_t>(edges.size()) * static_cast<size_t>(resolution));
|
|
80
|
+
|
|
81
|
+
for (const auto& edge : edges) {
|
|
82
|
+
const Vec4& a = baseVertices[static_cast<size_t>(edge.a)];
|
|
83
|
+
const Vec4& b = baseVertices[static_cast<size_t>(edge.b)];
|
|
84
|
+
|
|
85
|
+
for (int i = 0; i < resolution; ++i) {
|
|
86
|
+
float t = static_cast<float>(i) / static_cast<float>(resolution - 1);
|
|
87
|
+
vertices.push_back(a.lerp(b, t));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return vertices;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
} // namespace vib3
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tetrahedron.cpp - 3D Simplex Embedded in 4D
|
|
3
|
+
*
|
|
4
|
+
* Generates vertices and edge geometry for a regular tetrahedron
|
|
5
|
+
* embedded in 4D space (w = 0).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "math/Vec4.hpp"
|
|
9
|
+
#include <vector>
|
|
10
|
+
#include <cmath>
|
|
11
|
+
#include <numbers>
|
|
12
|
+
|
|
13
|
+
namespace vib3 {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Generate the 4 vertices of a regular tetrahedron in 4D.
|
|
17
|
+
*
|
|
18
|
+
* The tetrahedron is centered at the origin with unit edge length,
|
|
19
|
+
* embedded in the w=0 hyperplane. Vertices are placed so that the
|
|
20
|
+
* centroid lies at the origin.
|
|
21
|
+
*/
|
|
22
|
+
std::vector<Vec4> generateTetrahedronVertices() noexcept {
|
|
23
|
+
// Regular tetrahedron vertices centered at origin
|
|
24
|
+
// Using the standard construction: one vertex up, three forming
|
|
25
|
+
// an equilateral triangle below.
|
|
26
|
+
constexpr float a = 1.0f;
|
|
27
|
+
const float h = a * std::sqrt(2.0f / 3.0f);
|
|
28
|
+
const float r = a / std::sqrt(3.0f);
|
|
29
|
+
|
|
30
|
+
// Vertical offset to center at origin
|
|
31
|
+
const float yOff = -h / 4.0f;
|
|
32
|
+
|
|
33
|
+
std::vector<Vec4> vertices;
|
|
34
|
+
vertices.reserve(4);
|
|
35
|
+
|
|
36
|
+
// Top vertex
|
|
37
|
+
vertices.emplace_back(0.0f, 3.0f * h / 4.0f + yOff, 0.0f, 0.0f);
|
|
38
|
+
|
|
39
|
+
// Bottom triangle
|
|
40
|
+
vertices.emplace_back(0.0f, yOff, r, 0.0f);
|
|
41
|
+
vertices.emplace_back(-r * std::sqrt(3.0f) / 2.0f, yOff, -r / 2.0f, 0.0f);
|
|
42
|
+
vertices.emplace_back( r * std::sqrt(3.0f) / 2.0f, yOff, -r / 2.0f, 0.0f);
|
|
43
|
+
|
|
44
|
+
return vertices;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Generate tetrahedron geometry with edge interpolation.
|
|
49
|
+
*
|
|
50
|
+
* Subdivides each of the 6 edges into `resolution` segments and
|
|
51
|
+
* returns all interpolated points.
|
|
52
|
+
*
|
|
53
|
+
* @param resolution Number of subdivisions per edge (minimum 2)
|
|
54
|
+
* @return Vector of 4D points along all tetrahedron edges
|
|
55
|
+
*/
|
|
56
|
+
std::vector<Vec4> generateTetrahedron(int resolution) noexcept {
|
|
57
|
+
if (resolution < 2) resolution = 2;
|
|
58
|
+
|
|
59
|
+
auto baseVertices = generateTetrahedronVertices();
|
|
60
|
+
|
|
61
|
+
// 6 edges for a tetrahedron: every pair of 4 vertices
|
|
62
|
+
constexpr int edgePairs[6][2] = {
|
|
63
|
+
{0, 1}, {0, 2}, {0, 3},
|
|
64
|
+
{1, 2}, {1, 3}, {2, 3}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
std::vector<Vec4> vertices;
|
|
68
|
+
vertices.reserve(6 * static_cast<size_t>(resolution));
|
|
69
|
+
|
|
70
|
+
for (const auto& pair : edgePairs) {
|
|
71
|
+
const Vec4& a = baseVertices[static_cast<size_t>(pair[0])];
|
|
72
|
+
const Vec4& b = baseVertices[static_cast<size_t>(pair[1])];
|
|
73
|
+
|
|
74
|
+
for (int i = 0; i < resolution; ++i) {
|
|
75
|
+
float t = static_cast<float>(i) / static_cast<float>(resolution - 1);
|
|
76
|
+
vertices.push_back(a.lerp(b, t));
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return vertices;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
} // namespace vib3
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Torus.cpp - Clifford Torus in 4D
|
|
3
|
+
*
|
|
4
|
+
* Generates points on the Clifford torus, which is the product of
|
|
5
|
+
* two circles embedded in 4D: S1 x S1 in R4.
|
|
6
|
+
*
|
|
7
|
+
* The Clifford torus is a flat torus that lies on the 3-sphere S3.
|
|
8
|
+
* Parametrization:
|
|
9
|
+
* x = cos(u) * r1
|
|
10
|
+
* y = sin(u) * r1
|
|
11
|
+
* z = cos(v) * r2
|
|
12
|
+
* w = sin(v) * r2
|
|
13
|
+
* where r1^2 + r2^2 = 1 for it to lie on S3 (r1 = r2 = 1/sqrt(2)).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
#include "math/Vec4.hpp"
|
|
17
|
+
#include <vector>
|
|
18
|
+
#include <cmath>
|
|
19
|
+
#include <numbers>
|
|
20
|
+
|
|
21
|
+
namespace vib3 {
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Generate the Clifford torus in 4D.
|
|
25
|
+
*
|
|
26
|
+
* Uses the standard parametrization with equal radii r1 = r2 = 1/sqrt(2),
|
|
27
|
+
* which places the torus on the unit 3-sphere. The two angles u and v
|
|
28
|
+
* each range over [0, 2*pi).
|
|
29
|
+
*
|
|
30
|
+
* @param resolution Number of subdivisions for each angle (total points = resolution^2)
|
|
31
|
+
* @return Vector of 4D points on the Clifford torus
|
|
32
|
+
*/
|
|
33
|
+
std::vector<Vec4> generateTorus(int resolution) noexcept {
|
|
34
|
+
if (resolution < 4) resolution = 4;
|
|
35
|
+
|
|
36
|
+
constexpr float twoPi = 2.0f * std::numbers::pi_v<float>;
|
|
37
|
+
// Equal radii for Clifford torus on S3
|
|
38
|
+
constexpr float r = 1.0f / std::numbers::sqrt2_v<float>;
|
|
39
|
+
|
|
40
|
+
std::vector<Vec4> vertices;
|
|
41
|
+
vertices.reserve(static_cast<size_t>(resolution) * static_cast<size_t>(resolution));
|
|
42
|
+
|
|
43
|
+
for (int iu = 0; iu < resolution; ++iu) {
|
|
44
|
+
float u = twoPi * static_cast<float>(iu) / static_cast<float>(resolution);
|
|
45
|
+
float cosU = std::cos(u);
|
|
46
|
+
float sinU = std::sin(u);
|
|
47
|
+
|
|
48
|
+
for (int iv = 0; iv < resolution; ++iv) {
|
|
49
|
+
float v = twoPi * static_cast<float>(iv) / static_cast<float>(resolution);
|
|
50
|
+
float cosV = std::cos(v);
|
|
51
|
+
float sinV = std::sin(v);
|
|
52
|
+
|
|
53
|
+
vertices.emplace_back(
|
|
54
|
+
r * cosU,
|
|
55
|
+
r * sinU,
|
|
56
|
+
r * cosV,
|
|
57
|
+
r * sinV
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return vertices;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
} // namespace vib3
|