/
Programmi21
/
demo_integration
Обзор
Документация
Войти
/
Programmi21
/
demo_integration
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
task2_visibility.py
121 строка
4 KB
Programmi21
create: .cm-token, app.py, docker-compose.yml, Dockerfile, instruction.md, README.md, requirements.txt, task1_cruise.py, task2_visibility.py, task3_constellation.py
10 апр 2026, 16:36
Верифицирован
10 апр 2026, 16:36
01ec612
Код
Авторство
О чём код?
import math from datetime import datetime def solve_star_visibility(data): target_vector = data["target_star_vector"] bodies = data["celestial_bodies"] start_time_str = data["observation_params"]["start_time"] required_time = data["observation_params"]["required_transmission_time"] target_mag = math.sqrt(target_vector["x"]**2 + target_vector["y"]**2) target_dir = (target_vector["x"] / target_mag, target_vector["y"] / target_mag) start_dt = datetime.fromisoformat(start_time_str.replace('Z', '+00:00')) start_seconds = start_dt.timestamp() stars = {} planets = {} moons = {} for body in bodies: if body["type"] == "star": stars[body["id"]] = body elif body["type"] == "planet": planets[body["id"]] = body elif body["type"] == "moon": moons[body["id"]] = body def get_position(body_id, t): if body_id in stars: body = stars[body_id] return (body["position"]["x"], body["position"]["y"]) elif body_id in planets: body = planets[body_id] parent = stars[body["parent_id"]] parent_pos = (parent["position"]["x"], parent["position"]["y"]) angle = body["initial_angle"] angular_vel = body["angular_velocity"] if body["rotation_clockwise"]: angle -= angular_vel * t else: angle += angular_vel * t angle_rad = math.radians(angle % 360) x = parent_pos[0] + body["orbit_radius"] * math.cos(angle_rad) y = parent_pos[1] + body["orbit_radius"] * math.sin(angle_rad) return (x, y) elif body_id in moons: body = moons[body_id] parent_pos = get_position(body["parent_id"], t) angle = body["initial_angle"] angular_vel = body["angular_velocity"] if body["rotation_clockwise"]: angle -= angular_vel * t else: angle += angular_vel * t angle_rad = math.radians(angle % 360) x = parent_pos[0] + body["orbit_radius"] * math.cos(angle_rad) y = parent_pos[1] + body["orbit_radius"] * math.sin(angle_rad) return (x, y) return None def ray_sphere_intersection(observer, direction, center, radius): dx = direction[0] dy = direction[1] cx = center[0] cy = center[1] a = dx*dx + dy*dy b = 2 * (-cx*dx - cy*dy) c = cx*cx + cy*cy - radius*radius disc = b*b - 4*a*c if disc < 0: return None sqrt_disc = math.sqrt(disc) t1 = (-b - sqrt_disc) / (2*a) t2 = (-b + sqrt_disc) / (2*a) if t1 > 0: return t1 if t2 > 0: return t2 return None def is_visible(t): observer = (0, 0) for body in bodies: if body["type"] == "star" and body["id"] != "target": continue pos = get_position(body["id"], t) if pos: intersection = ray_sphere_intersection(observer, target_dir, pos, body["radius"]) if intersection is not None and intersection > 0: return False return True max_time = 1e9 windows = [] current_start = None step = 1.0 t = 0 while t <= max_time: visible = is_visible(t) if visible and current_start is None: current_start = t elif not visible and current_start is not None: windows.append((current_start, t)) current_start = None t += step if current_start is not None: windows.append((current_start, max_time)) for start, end in windows: duration = end - start if duration >= required_time: wait_time = max(0, start) return { "found": True, "next_fitting_interval_in": round(wait_time), "interval_duration": round(duration) } return {"found": False}