fix(editor): зажим крена маршрута к ±45°
Бэкенд считает геометрию видимости/маршрута только в |крен| ≤ 45°, поэтому предел снижен с 89° до 45°. Введён общий clampRoll (зажим + округление до 0.1°), применён при ручной правке крена (кнопки ±, прямой ввод) и при загрузке сохранённого маршрута в окно построения (легаси-маршрут вне ±45° зажимается).
This commit is contained in:
@@ -74,8 +74,15 @@ const SHOOT_WINDOW_MS = 6 * 60 * 1000;
|
||||
const DEFAULT_CAPTURE_ANGLE_DEG = 1.5;
|
||||
/** Дефолтная длительность строящегося маршрута съёмки (мс). */
|
||||
const DEFAULT_ROUTE_DURATION_MS = 30_000;
|
||||
/** Предел крена (gamma) маршрута при ручной правке, градусы. */
|
||||
const MAX_ROUTE_ROLL_DEG = 89;
|
||||
/**
|
||||
* Предел крена (gamma) маршрута, градусы. Параметры видимости/маршрута бэкенд считает только
|
||||
* в диапазоне |крен| ≤ 45°; за его пределами геометрия маршрута не определена, поэтому жёстко
|
||||
* зажимаем здесь — и при ручной правке, и при загрузке сохранённого маршрута в окно построения.
|
||||
*/
|
||||
const MAX_ROUTE_ROLL_DEG = 45;
|
||||
/** Крен с зажимом в допустимый диапазон и округлением до 1 знака (как при ручном вводе). */
|
||||
const clampRoll = (deg: number): number =>
|
||||
Math.round(Math.max(-MAX_ROUTE_ROLL_DEG, Math.min(MAX_ROUTE_ROLL_DEG, deg)) * 10) / 10;
|
||||
/** Допустимый выход окна маршрута за пределы окна видимости, мс (±30 минут). */
|
||||
const ROUTE_TIME_MARGIN_MS = 30 * 60_000;
|
||||
const EDITOR_MAP_LAYERS: Tgu2DMapLayersState = {
|
||||
@@ -421,15 +428,15 @@ export function TguEditorTab({ selectedSpacecraftId, selectedPlan, appliedRange,
|
||||
if (prefill) {
|
||||
editShootPrefillRef.current = null;
|
||||
setRouteWindow({ startMs: prefill.startMs, endMs: prefill.endMs });
|
||||
setRouteRoll(Math.round(prefill.roll * 10) / 10);
|
||||
// Сохранённый маршрут мог быть с креном вне ±45° (легаси) — зажимаем при загрузке в окно.
|
||||
setRouteRoll(clampRoll(prefill.roll));
|
||||
return;
|
||||
}
|
||||
const passDurationMs = selectedShootPass.endMs - selectedShootPass.startMs;
|
||||
const half = Math.min(DEFAULT_ROUTE_DURATION_MS, passDurationMs) / 2;
|
||||
const mid = (selectedShootPass.startMs + selectedShootPass.endMs) / 2;
|
||||
setRouteWindow({ startMs: mid - half, endMs: mid + half });
|
||||
// Крен — не точнее одного знака после запятой (как и при ручном вводе).
|
||||
setRouteRoll(Math.round((selectedShootPass.rollDeg ?? 0) * 10) / 10);
|
||||
setRouteRoll(clampRoll(selectedShootPass.rollDeg ?? 0));
|
||||
}, [rightMode, selectedShootPass]);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -1325,14 +1332,10 @@ export function TguEditorTab({ selectedSpacecraftId, selectedPlan, appliedRange,
|
||||
})
|
||||
}
|
||||
onRouteRollChange={(deltaDeg) =>
|
||||
setRouteRoll((current) =>
|
||||
Math.max(-MAX_ROUTE_ROLL_DEG, Math.min(MAX_ROUTE_ROLL_DEG, (current ?? 0) + deltaDeg))
|
||||
)
|
||||
setRouteRoll((current) => clampRoll((current ?? 0) + deltaDeg))
|
||||
}
|
||||
onRouteRollSet={(deg) =>
|
||||
setRouteRoll((current) =>
|
||||
Number.isFinite(deg) ? Math.max(-MAX_ROUTE_ROLL_DEG, Math.min(MAX_ROUTE_ROLL_DEG, deg)) : current
|
||||
)
|
||||
setRouteRoll((current) => (Number.isFinite(deg) ? clampRoll(deg) : current))
|
||||
}
|
||||
onSelectPass={(pass) => {
|
||||
setSelectedShootPass(pass);
|
||||
|
||||
Reference in New Issue
Block a user