From dd0150402c2ada260e4ee4024434523f4c0b6077 Mon Sep 17 00:00:00 2001 From: march3 Date: Sun, 23 Jul 2023 20:16:54 +0800 Subject: [PATCH] =?UTF-8?q?Python=E8=B6=85=E4=BA=BA-=E5=AE=87=E5=AE=99?= =?UTF-8?q?=E6=A8=A1=E6=8B=9F=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../solar_system/solar_system_reality.py | 81 ++++++++++++++++++- 1 file changed, 78 insertions(+), 3 deletions(-) diff --git a/sim_scenes/solar_system/solar_system_reality.py b/sim_scenes/solar_system/solar_system_reality.py index 86f4bd0..f0fc2d0 100644 --- a/sim_scenes/solar_system/solar_system_reality.py +++ b/sim_scenes/solar_system/solar_system_reality.py @@ -20,6 +20,7 @@ from common.consts import SECONDS_PER_WEEK, SECONDS_PER_DAY, AU from sim_scenes.func import ursina_run from simulators.ursina.entities.body_timer import TimeData from simulators.ursina.ui.control_ui import ControlUI +from simulators.ursina.ursina_config import UrsinaConfig from simulators.ursina.ursina_event import UrsinaEvent from ursina import camera @@ -53,9 +54,70 @@ def get_bodies_names(bodies): names += body.__class__.__name__ + "," return names[0:-1] +def are_planets_in_line(positions, line_width): + # 检查行星的数量是否足够判断是否在一条线上 + if len(positions) < 3: + return False + # 获取第一个行星的坐标 + x1, y1, z1 = positions[0] + # 计算行星之间的向量差 + dx = positions[1][0] - x1 + dy = positions[1][1] - y1 + dz = positions[1][2] - z1 + # 计算线的宽度的平方 + line_width_squared = line_width**2 + # 遍历剩余的行星 + for i in range(2, len(positions)): + # 获取当前行星的坐标 + x, y, z = positions[i] + # 计算当前行星与第一个行星之间的向量差 + current_dx = x - x1 + current_dy = y - y1 + current_dz = z - z1 + # 计算当前行星与线之间的距离的平方 + distance_squared = (current_dy * dz - current_dz * dy)**2 + (current_dz * dx - current_dx * dz)**2 + (current_dx * dy - current_dy * dx)**2 + # 如果距离的平方大于线的宽度的平方,则行星不在一条线上 + if distance_squared > line_width_squared: + return False + # 所有行星都在一条线上 + return True + +def are_planets_in_line(planets, line_width): + if len(planets) < 2: + return False + + x_coords = [planet[0] for planet in planets] + y_coords = [planet[1] for planet in planets] + z_coords = [planet[2] for planet in planets] + + x_diff = [abs(x2 - x1) for (x1, x2) in zip(x_coords, x_coords[1:])] + y_diff = [abs(y2 - y1) for (y1, y2) in zip(y_coords, y_coords[1:])] + z_diff = [abs(z2 - z1) for (z1, z2) in zip(z_coords, z_coords[1:])] + + widths = [max(d1, d2, line_width) for (d1, d2) in zip(x_diff, y_diff)] + [line_width] + [max(d1, d2, line_width) for (d1, d2) in zip(x_diff[::-1], y_diff[::-1])] + + return all(w == widths[0] for w in widths) + +def are_planets_in_line(planets, line_width): + if len(planets) < 2: + return False + + x_coords = [planet[0] for planet in planets] + y_coords = [planet[1] for planet in planets] + z_coords = [planet[2] for planet in planets] + + x_diff = [abs(x2 - x1) for (x1, x2) in zip(x_coords, x_coords[1:])] + y_diff = [abs(y2 - y1) for (y1, y2) in zip(y_coords, y_coords[1:])] + z_diff = [abs(z2 - z1) for (z1, z2) in zip(z_coords, z_coords[1:])] + + widths = [max(d1, d2, line_width**2) for (d1, d2) in zip(x_diff, y_diff)] + [line_width**2] + [max(d1, d2, line_width**2) for (d1, d2) in zip(x_diff[::-1], y_diff[::-1])] + + return all(w == widths[0] for w in widths) current_time = Time.now() +in_line_datetimes = [] + if __name__ == '__main__': # 八大行星:木星(♃)、土星(♄)、天王星(♅)、海王星(♆)、地球(⊕)、金星(♀)、火星(♂)、水星(☿) # 排列顺序 @@ -73,7 +135,7 @@ if __name__ == '__main__': Earth(name="地球", size_scale=1e3), # 地球 Moon(name="月球", size_scale=2e3), # 月球 Mars(name="火星", size_scale=1.2e3), # 火星 - Asteroids(size_scale=1e2, parent=sun, rotate_angle=-20), + # Asteroids(size_scale=1e2, parent=sun, rotate_angle=-20), Jupiter(name="木星", size_scale=4e2), # 木星 Saturn(name="土星", size_scale=4e2), # 土星 Uranus(name="天王星", size_scale=10e2), # 天王星 @@ -99,12 +161,12 @@ if __name__ == '__main__': def on_timer_changed(time_data: TimeData): t = current_time + time_data.total_days - posvels = get_bodies_posvels(names, t) + # posvels = get_bodies_posvels(names, t) # earth_loc = None earth_pos = None sun_pos = None + positions = [] for body in bodies: - if isinstance(body, Asteroids): posvel = None else: @@ -124,6 +186,11 @@ if __name__ == '__main__': [posvel[1].x.value * AU / S_OF_D, posvel[1].z.value * AU / S_OF_D, posvel[1].y.value * AU / S_OF_D] + if isinstance(body, Asteroids) or isinstance(body, Moon) or isinstance(body, Sun): + pass + else: + positions.append(position) + body.position = np.array(position) body.velocity = np.array(velocity) if isinstance(body, Earth): @@ -133,6 +200,14 @@ if __name__ == '__main__': sun_pos = posvel[0] dt = time_data.get_datetime(str(current_time)) + + # if len(in_line_datetimes) == 0: + # in_line = are_planets_in_line(positions, 5*AU) + # if in_line: + # in_line_datetimes.append(dt.strftime('%Y-%m-%d %H:%M:%S')) + # print(in_line_datetimes) + # UrsinaConfig.seconds_per = 1 + # print(time_data.get_datetime(str(current_time))) ControlUI.current_ui.show_message(dt.strftime('%Y-%m-%d %H:%M:%S'), font="verdana.ttf", -- GitLab