Полноценный браузерный UI (Pinia, Three.js) с паритетом Qt: редактор цепочки, wizard, пресеты, метрики и 3D viewer; API расширен для catalog/validate/demo/user-presets; CLI отдаёт step metrics в JSON. Co-authored-by: Cursor <cursoragent@cursor.com>
71 lines
2.5 KiB
Python
71 lines
2.5 KiB
Python
"""Demo point cloud generation (mirrors generateDemoPoints in mainwindow.cpp)."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import math
|
|
import random
|
|
from typing import Any
|
|
|
|
|
|
def generate_demo_points(surface_type: str, count: int = 350) -> list[list[float]]:
|
|
points: list[list[float]] = []
|
|
rng = random.Random()
|
|
|
|
for _ in range(count):
|
|
if surface_type == "Дно реки + труба":
|
|
if rng.random() < 0.35:
|
|
angle = rng.random() * 2.0 * math.pi
|
|
y = rng.random() * 2.6 - 1.3
|
|
pipe_radius = 0.22
|
|
jitter = rng.random() * 0.02 - 0.01
|
|
radial = pipe_radius + jitter
|
|
x = 0.0 + radial * math.cos(angle)
|
|
z = -0.62 + radial * math.sin(angle)
|
|
else:
|
|
x = rng.random() * 4.0 - 2.0
|
|
y = rng.random() * 3.0 - 1.5
|
|
waviness = 0.11 * math.cos(2.2 * y)
|
|
channel = 0.08 * x * x
|
|
noise = rng.random() * 0.04 - 0.02
|
|
z = -0.45 + channel + waviness + noise
|
|
elif surface_type == "Тор":
|
|
u = rng.random() * 2.0 * math.pi
|
|
v = rng.random() * 2.0 * math.pi
|
|
major_r = 1.0
|
|
minor_r = 0.35
|
|
jitter = rng.random() * 0.02 - 0.01
|
|
radial = minor_r + jitter
|
|
x = (major_r + radial * math.cos(v)) * math.cos(u)
|
|
y = (major_r + radial * math.cos(v)) * math.sin(u)
|
|
z = radial * math.sin(v)
|
|
elif surface_type == "Волна":
|
|
x = rng.random() * 2.4 - 1.2
|
|
y = rng.random() * 2.4 - 1.2
|
|
noise = rng.random() * 0.03 - 0.015
|
|
z = 0.35 * math.sin(2.5 * x) * math.cos(2.5 * y) + noise
|
|
else:
|
|
u = rng.random() * 2.0 - 1.0
|
|
theta = rng.random() * 2.0 * math.pi
|
|
r = 1.0 + rng.random() * 0.08 - 0.04
|
|
s = math.sqrt(max(0.0, 1.0 - u * u))
|
|
x = r * s * math.cos(theta)
|
|
y = r * s * math.sin(theta)
|
|
z = r * u
|
|
points.append([x, y, z])
|
|
return points
|
|
|
|
|
|
DEMO_SURFACE_TYPES = ["Сфера", "Тор", "Волна", "Дно реки + труба"]
|
|
|
|
|
|
def demo_payload(surface_type: str, count: int = 350) -> dict[str, Any]:
|
|
if surface_type not in DEMO_SURFACE_TYPES:
|
|
surface_type = "Сфера"
|
|
points = generate_demo_points(surface_type, count)
|
|
return {
|
|
"surfaceType": surface_type,
|
|
"pointCount": len(points),
|
|
"points": points,
|
|
"sourceLabel": f"demo: {surface_type}",
|
|
}
|