From ebfb4075523f5259e722c6d1c3a0bcecd6e67754 Mon Sep 17 00:00:00 2001 From: 2weiEmu Date: Fri, 6 Feb 2026 22:31:19 +0100 Subject: [PATCH] updated: initial design, some of the math seems to fuck up? --- .obsidian/workspace.json | 2 +- Nebulous Command/missiles-ranges.py | 130 ++++++++++++++++++++++------ 2 files changed, 105 insertions(+), 27 deletions(-) diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index ceb8a47..09c85f4 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -179,9 +179,9 @@ "lastOpenFiles": [ "Nebulous Command/missiles-ranges.py~", "Nebulous Command/4913", + "Nebulous Command/missile-simulator.py~", "Nebulous Command/data.py~", "List of things to do.md", - "Nebulous Command/missile-simulator.py~", "Nebulous Command/__pycache__/data.cpython-314.pyc", "Nebulous Command/missiles-ranges.py", "Nebulous Command/calc.py~", diff --git a/Nebulous Command/missiles-ranges.py b/Nebulous Command/missiles-ranges.py index 5fc9ee8..25aa00e 100644 --- a/Nebulous Command/missiles-ranges.py +++ b/Nebulous Command/missiles-ranges.py @@ -1,29 +1,116 @@ from data import Jammer, Radar, Ship, Missile, radars, jammers, ships import tkinter as tk from tkinter import ttk +import math +import cv2 as cv +import numpy as np RADAR_OPTIONS = [r.name for r in radars] JAMMER_OPTIONS = [j.name for j in jammers] SHIP_OPTIONS = [s.name for s in ships] -radar_det_combo: ttk.Combobox -jammer_det_combobox_1: ttk.Combobox -jammer_det_combobox_2: ttk.Combobox -strobe_corr_spinbox: ttk.Spinbox -arr_spinbox: ttk.Spinbox -sig_scrambler_spinbox: ttk.Spinbox -radar_coating_spinbox: ttk.Spinbox -ship_det_combobox: ttk.Combobox -radar_mod_spinbox: ttk.Spinbox +HEIGHT = 600 +WIDTH = 1500 + +root = tk.Tk() +root.title("Missile and Ship Detection Range Calculator") + +radar_det_combo = ttk.Combobox( + root, values=RADAR_OPTIONS, state="readonly") +jammer_det_combobox_1 = ttk.Combobox( + root, values=JAMMER_OPTIONS, state="readonly") +jammer_det_combobox_2 = ttk.Combobox( + root, values=JAMMER_OPTIONS, state="readonly") +strobe_corr_spinbox = ttk.Spinbox(root, from_=0, to=10) +arr_spinbox = ttk.Spinbox(root, from_=0, to=10) +sig_scrambler_spinbox = ttk.Spinbox(root, from_=0, to=10) +radar_coating_spinbox = ttk.Spinbox(root, from_=0, to=10) +ship_det_combobox = ttk.Combobox( + root, values=SHIP_OPTIONS, state="readonly") +radar_mod_spinbox = ttk.Spinbox(root, from_=-100, to=100) # TODO: SPRINTER GETS +20% SENSITIVITY +img = np.zeros((HEIGHT, WIDTH, 3), np.uint8) + + +def calculate_return_power_density( + radiated_power, gain, rcs, aperture_size, distance) -> float: + numerator = radiated_power * (gain ** 2) * (rcs / 10) * aperture_size + denominator = 16 * (math.pi ** 2) * (distance ** 4) + return numerator / denominator + + +def calculate_noise(gain, noise_filtering, total_jamming_power) -> float: + return ((10 ** -7) + (total_jamming_power * gain)) * (10 ** (noise_filtering / 10)) + def determine_and_graph(): - pass + img = np.zeros((HEIGHT, WIDTH, 3), np.uint8) + # draw the detecting ships + CENTERED = (HEIGHT // 3) * 0.5 + cv.circle(img, center=(0, int(CENTERED * 1)), + radius=2, color=(255, 0, 0), thickness=2) + cv.circle(img, center=(0, int(CENTERED * 3)), + radius=2, color=(255, 0, 0), thickness=2) + cv.circle(img, center=(0, int(CENTERED * 5)), + radius=2, color=(255, 0, 0), thickness=2) + + # set some markers + cv.line(img, (300, 0), (300, HEIGHT), color=(255,255,255), thickness=3) + cv.line(img, (600, 0), (600, HEIGHT), color=(255,255,255), thickness=3) + cv.line(img, (900, 0), (900, HEIGHT), color=(255,255,255), thickness=3) + cv.line(img, (1200, 0), (1200, HEIGHT), color=(255,255,255), thickness=3) + cv.line(img, (1500, 0), (1500, HEIGHT), color=(255,255,255), thickness=3) + cv.line(img, (150, 0), (150, HEIGHT), color=(255,255,255), thickness=3) + + radar = [r for r in radars if r.name == radar_det_combo.get()][0] + strob_correlator_count = int(strobe_corr_spinbox.get()) + adaptive_radar_receiver = int(arr_spinbox.get()) + sig_scrambler_count = int(sig_scrambler_spinbox.get()) + + ship = [s for s in ships if s.name == ship_det_combobox.get()][0] + jammer_1 = [j for j in jammers if j.name == jammer_det_combobox_1.get()][0] + jammer_2 = [j for j in jammers if j.name == jammer_det_combobox_2.get()][0] + radar_coat_count = int(radar_coating_spinbox.get()) + radar_offset = int(radar_mod_spinbox.get()) + + # draw line at max range of radar + max_range = int(radar.max_range_km * 100) + cv.line(img, (max_range, 0), (max_range, HEIGHT), color=(0, 255, 255), thickness=3) + + # determine total rcs + rcs = ship.rcs_m2 + (ship.rcs_m2 * (radar_offset / 100)) + if (radar_coat_count == 1): + rcs = rcs * 0.6 + if (radar_coat_count == 2): + rcs = rcs * 0.4528 + + # determine total noise_filtering + noise_f = radar.noise_filtering_dB + (adaptive_radar_receiver * -0.7) + + # first RPD and NOISE + for d in range(5, int(radar.max_range_km * 1000), 5): + rpd = calculate_return_power_density( + radar.radiated_power_kw, radar.gain_db, rcs, + radar.aperture_size_m2, d) + + jamming_power = 0 + + if (int(jammer_1.range_km * 1000) <= d): + jamming_power = (jammer_1.radiated_power_kw * jammer_1.gain_db) / (4 * math.pi * (d**2)) + if (int(jammer_2.range_km * 1000) <= d): + jamming_power += 0.876 * (jammer_2.radiated_power_kw * jammer_2.gain_db) / (4 * math.pi * (d ** 2)) + + n = calculate_noise(radar.gain_db, noise_f, jamming_power) + + if (rpd > n): + cv.line(img, (int(d / 10), int(CENTERED * 2)), (int(d/10), int(CENTERED * 0)), color=(0, 0, 255), thickness=1) + + cv.imshow("Display of Ranges", img) + cv.waitKey(1) + def main(): - root = tk.Tk() - root.title("Missile and Ship Detection Range Calculator") # we need the ship that is _detecting_ # what does that ship need? Radar, Illuminators, # Strobe Correlators, ARRs and Signature Scramblers @@ -33,8 +120,6 @@ def main(): # RADAR label = tk.Label(root, text="RADAR:") label.grid(row=1, column=0) - radar_det_combo = ttk.Combobox( - root, values=RADAR_OPTIONS, state="readonly") radar_det_combo.grid(row=1, column=1) radar_det_combo.set(RADAR_OPTIONS[0]) @@ -46,21 +131,18 @@ def main(): # How many Strobe Correlators? label = tk.Label(root, text="STROBE CORR:") label.grid(row=2, column=0) - strobe_corr_spinbox = ttk.Spinbox(root, from_=0, to=10) strobe_corr_spinbox.grid(row=2, column=1) strobe_corr_spinbox.set(0) # How many ARRs label = tk.Label(root, text="ADAPTIVE RADAR RECV:") label.grid(row=3, column=0) - arr_spinbox = ttk.Spinbox(root, from_=0, to=10) arr_spinbox.grid(row=3, column=1) arr_spinbox.set(0) # Signature Scramblers label = tk.Label(root, text="SIGNATURE SCRM:") label.grid(row=4, column=0) - sig_scrambler_spinbox = ttk.Spinbox(root, from_=0, to=10) sig_scrambler_spinbox.grid(row=4, column=1) sig_scrambler_spinbox.set(0) @@ -77,45 +159,41 @@ def main(): # What kinda ship is it? label = tk.Label(root, text="Ship / Missile Type:") label.grid(row=1, column=2) - ship_det_combobox = ttk.Combobox( - root, values=SHIP_OPTIONS, state="readonly") ship_det_combobox.grid(row=1, column=3) ship_det_combobox.set(SHIP_OPTIONS[0]) # What Jammer #1? # ideally just radar, but hey label = tk.Label(root, text="JAMMER #1:") label.grid(row=2, column=2) - jammer_det_combobox_1 = ttk.Combobox( - root, values=JAMMER_OPTIONS, state="readonly") jammer_det_combobox_1.grid(row=2, column=3) jammer_det_combobox_1.set(JAMMER_OPTIONS[0]) # What Jammer #2? label = tk.Label(root, text="JAMMER #2:") label.grid(row=3, column=2) - jammer_det_combobox_2 = ttk.Combobox( - root, values=JAMMER_OPTIONS, state="readonly") jammer_det_combobox_2.grid(row=3, column=3) jammer_det_combobox_2.set(JAMMER_OPTIONS[0]) # How many layers of Radar Coating label = tk.Label(root, text="RADAR COATING COUNT:") label.grid(row=4, column=2) - radar_coating_spinbox = ttk.Spinbox(root, from_=0, to=10) radar_coating_spinbox.grid(row=4, column=3) radar_coating_spinbox.set(0) # Other radar offsets label = tk.Label(root, text="OTHER RADAR OFFSETS:") label.grid(row=5, column=2) - radar_mod_spinbox = ttk.Spinbox(root, from_=-100, to=100) radar_mod_spinbox.grid(row=5, column=3) radar_mod_spinbox.set(0) - calc_button = tk.Button(root, text="Calculate", command=determine_and_graph) + calc_button = tk.Button(root, + text="Calculate", command=determine_and_graph) calc_button.grid(row=6, column=1, columnspan=2) + # cv.imshow("Display of Ranges", img) + root.mainloop() + cv.waitKey(0) if __name__ == "__main__": -- 2.54.0