Skip to content

Commit

Permalink
changed distance and look distance
Browse files Browse the repository at this point in the history
  • Loading branch information
gambon0120 committed Aug 18, 2024
1 parent 4ac9800 commit f20fa90
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 46 deletions.
25 changes: 12 additions & 13 deletions examples/kanik_50bmg_aid_shooting.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,25 +50,24 @@

def calculate_lead_angle(target_speed, target_size, bullet_speed, initial_distance, time_of_flight):
"""
Розрахунок кута упередження маючи швидкість і розмір цілі, швидкість кулі, початкову відстань до цілі.
:param target_speed: Швидкість цілі (м/с)
:param target_size: Довжина цілі (м)
:param bullet_speed: Швидкість кулі (м/с)
:param initial_distance: Початкова відстань до цілі (м)
:return: Кут упередження в градусах
Calculation of the lead angle given the target speed and size, bullet speed, and initial distance to the target.
:param target_speed: Target speed (m/s)
:param target_size: Target length (m)
:param bullet_speed: Bullet speed (m/s)
:param initial_distance: Initial distance to the target (m)
:param time_of_flight: Time of flight (s)
:return: Lead angle in degrees
"""
# Час польоту кулі
# time_of_flight = initial_distance / bullet_speed

# Відстань, яку пройде ніс цілі
# distance_nose_travel = target_speed * time_of_flight + target_size
distance_nose_travel = target_speed * time_of_flight + target_size

# Обчислення кута упередження
# Distance the target's nose will travel
distance_nose_travel = target_speed * time_of_flight + target_size

lead_angle = math.atan(distance_nose_travel / initial_distance)

# Перетворення кута в градуси
# Converting the angle to degrees
lead_angle_degrees = math.degrees(lead_angle)

return lead_angle_degrees
Expand Down
2 changes: 1 addition & 1 deletion py_ballisticcalc/munition.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def get_adjustment(self, target_distance: Distance,
def get_trajectory_adjustment(self, trajectory_point: 'TrajectoryData', magnification: float) -> Clicks:
"""Calculate adjustment for target distance and magnification for `TrajectoryData` instance"""

return self.get_adjustment(trajectory_point.distance,
return self.get_adjustment(trajectory_point.x,
trajectory_point.drop_angle,
trajectory_point.windage_angle,
magnification)
Expand Down
4 changes: 2 additions & 2 deletions py_ballisticcalc/trajectory_calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -443,15 +443,15 @@ def create_trajectory_row(time: float, range_vector: Vector, velocity_vector: Ve

return TrajectoryData(
time=time,
distance=Distance.Foot(range_vector.x),
x=Distance.Foot(range_vector.x),
velocity=Velocity.FPS(velocity),
mach=velocity / mach,
y=Distance.Foot(range_vector.y),
target_drop=Distance.Foot((range_vector.y - range_vector.x * math.tan(look_angle)) * math.cos(look_angle)),
drop_angle=Angular.Radian(drop_angle - (look_angle if range_vector.x else 0)),
windage=Distance.Foot(windage),
windage_angle=Angular.Radian(windage_angle),
look_distance=Distance.Foot(range_vector.x / math.cos(look_angle)),
distance=Distance.Foot(range_vector.x / math.cos(look_angle)),
angle=Angular.Radian(trajectory_angle),
density_factor=density_factor - 1,
drag=drag,
Expand Down
50 changes: 25 additions & 25 deletions py_ballisticcalc/trajectory_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ class TrajectoryData(NamedTuple):
Attributes:
time (float): bullet flight time
distance (Distance): x-axis coordinate
x (Distance): x-axis coordinate
velocity (Velocity): velocity
mach (float): velocity in Mach prefer_units
y (Distance): y-axis coordinate
target_drop (Distance): drop relative to sight-line
drop_angle (Angular): sight adjustment to zero target_drop at this distance
windage (Distance):
windage_angle (Angular):
look_distance (Distance): sight-line distance = .distance/cosine(look_angle)
# look_height (Distance): y-coordinate of sight-line = .distance*tan(look_angle)
distance (Distance): sight-line distance = .x/cosine(look_angle)
# look_height (Distance): y-coordinate of sight-line = .x*tan(look_angle)
angle (Angular): Angle of velocity vector relative to x-axis
density_factor (float): Ratio of air density here to standard density
drag (float): Current drag coefficient
Expand All @@ -72,15 +72,15 @@ class TrajectoryData(NamedTuple):
"""

time: float
distance: Distance
x: Distance
velocity: Velocity
mach: float
y: Distance
target_drop: Distance
drop_angle: Angular
windage: Distance
windage_angle: Angular
look_distance: Distance
distance: Distance
angle: Angular
density_factor: float
drag: float
Expand All @@ -99,15 +99,15 @@ def _fmt(v: AbstractUnit, u: Unit):

return (
f'{self.time:.3f} s',
_fmt(self.distance, PreferredUnits.distance),
_fmt(self.x, PreferredUnits.distance),
_fmt(self.velocity, PreferredUnits.velocity),
f'{self.mach:.2f} mach',
_fmt(self.y, PreferredUnits.drop),
_fmt(self.target_drop, PreferredUnits.drop),
_fmt(self.drop_angle, PreferredUnits.adjustment),
_fmt(self.windage, PreferredUnits.drop),
_fmt(self.windage_angle, PreferredUnits.adjustment),
_fmt(self.look_distance, PreferredUnits.distance),
_fmt(self.distance, PreferredUnits.distance),
_fmt(self.angle, PreferredUnits.angular),
f'{self.density_factor:.3e}',
f'{self.drag:.3f}',
Expand All @@ -123,15 +123,15 @@ def in_def_units(self) -> tuple:
"""
return (
self.time,
self.distance >> PreferredUnits.distance,
self.x >> PreferredUnits.distance,
self.velocity >> PreferredUnits.velocity,
self.mach,
self.y >> PreferredUnits.drop,
self.target_drop >> PreferredUnits.drop,
self.drop_angle >> PreferredUnits.adjustment,
self.windage >> PreferredUnits.drop,
self.windage_angle >> PreferredUnits.adjustment,
self.look_distance >> PreferredUnits.distance,
self.distance >> PreferredUnits.distance,
self.angle >> PreferredUnits.angular,
self.density_factor,
self.drag,
Expand All @@ -150,23 +150,23 @@ class DangerSpace(NamedTuple):
look_angle: Angular

def __str__(self) -> str:
return f'Danger space at {self.at_range.distance << PreferredUnits.distance} ' \
return f'Danger space at {self.at_range.x << PreferredUnits.distance} ' \
+ f'for {self.target_height << PreferredUnits.drop} tall target ' \
+ (f'at {self.look_angle << Angular.Degree} look-angle ' if self.look_angle != 0 else '') \
+ f'ranges from {self.begin.distance << PreferredUnits.distance} ' \
+ f'to {self.end.distance << PreferredUnits.distance}'
+ f'ranges from {self.begin.x << PreferredUnits.distance} ' \
+ f'to {self.end.x << PreferredUnits.distance}'

def overlay(self, ax: 'Axes', label: Optional[str] = None): # type: ignore
"""Highlights danger-space region on plot"""
if matplotlib is None or not Polygon:
raise ImportError("Use `pip install py_ballisticcalc[charts]` to get results as a plot")

cosine = math.cos(self.look_angle >> Angular.Radian)
begin_dist = (self.begin.distance >> PreferredUnits.distance) * cosine
begin_dist = (self.begin.x >> PreferredUnits.distance) * cosine
begin_drop = (self.begin.y >> PreferredUnits.drop) * cosine
end_dist = (self.end.distance >> PreferredUnits.distance) * cosine
end_dist = (self.end.x >> PreferredUnits.distance) * cosine
end_drop = (self.end.y >> PreferredUnits.drop) * cosine
range_dist = (self.at_range.distance >> PreferredUnits.distance) * cosine
range_dist = (self.at_range.x >> PreferredUnits.distance) * cosine
range_drop = (self.at_range.y >> PreferredUnits.drop) * cosine
h = self.target_height >> PreferredUnits.drop

Expand All @@ -182,7 +182,7 @@ def overlay(self, ax: 'Axes', label: Optional[str] = None): # type: ignore
edgecolor='none', facecolor='r', alpha=0.3)
ax.add_patch(polygon)
if label is None: # Add default label
label = f"Danger space\nat {self.at_range.distance << PreferredUnits.distance}"
label = f"Danger space\nat {self.at_range.x << PreferredUnits.distance}"
if label != '':
ax.text(begin_dist + (end_dist - begin_dist) / 2, end_drop, label,
linespacing=1.2, fontsize=PLOT_FONT_SIZE, ha='center', va='top')
Expand Down Expand Up @@ -326,29 +326,29 @@ def plot(self, look_angle: Optional[Angular] = None) -> 'Axes': # type: ignore
"Use Calculator.fire(..., extra_data=True)")
font_size = PLOT_FONT_SIZE
df = self.dataframe()
ax = df.plot(x='distance', y=['y'], ylabel=PreferredUnits.drop.symbol)
max_range = self.trajectory[-1].distance >> PreferredUnits.distance
ax = df.plot(x='x', y=['y'], ylabel=PreferredUnits.drop.symbol)
max_range = self.trajectory[-1].x >> PreferredUnits.distance

for p in self.trajectory:
if TrajFlag(p.flag) & TrajFlag.ZERO:
ax.plot([p.distance >> PreferredUnits.distance, p.distance >> PreferredUnits.distance],
ax.plot([p.x_sight >> PreferredUnits.distance, p.x >> PreferredUnits.distance],
[df['y'].min(), p.y >> PreferredUnits.drop], linestyle=':')
ax.text((p.distance >> PreferredUnits.distance) + max_range / 100, df['y'].min(),
ax.text((p.x >> PreferredUnits.distance) + max_range / 100, df['y'].min(),
f"{(TrajFlag(p.flag) & TrajFlag.ZERO).name}",
fontsize=font_size, rotation=90)
if TrajFlag(p.flag) & TrajFlag.MACH:
ax.plot([p.distance >> PreferredUnits.distance, p.distance >> PreferredUnits.distance],
ax.plot([p.x >> PreferredUnits.distance, p.x >> PreferredUnits.distance],
[df['y'].min(), p.y >> PreferredUnits.drop], linestyle=':')
ax.text((p.distance >> PreferredUnits.distance) + max_range / 100, df['y'].min(),
ax.text((p.x >> PreferredUnits.distance) + max_range / 100, df['y'].min(),
"Mach 1", fontsize=font_size, rotation=90)

max_range_in_drop_units = self.trajectory[-1].distance >> PreferredUnits.drop
max_range_in_drop_units = self.trajectory[-1].x >> PreferredUnits.drop
# Sight line
x_sight = [0, df.distance.max()]
x_sight = [0, df.x.max()]
y_sight = [0, max_range_in_drop_units * math.tan(look_angle >> Angular.Radian)]
ax.plot(x_sight, y_sight, linestyle='--', color=[.3, 0, .3, .5])
# Barrel pointing line
x_bbl = [0, df.distance.max()]
x_bbl = [0, df.x.max()]
y_bbl = [-(self.shot.weapon.sight_height >> PreferredUnits.drop),
max_range_in_drop_units * math.tan(self.trajectory[0].angle >> Angular.Radian)
- (self.shot.weapon.sight_height >> PreferredUnits.drop)]
Expand Down
8 changes: 4 additions & 4 deletions tests/test_danger_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ def test_danger_space(self):
)

self.assertAlmostEqual(
round(danger_space.begin.distance >> Distance.Yard, Distance.Yard.accuracy), 393.6, 0)
round(danger_space.begin.x >> Distance.Yard, Distance.Yard.accuracy), 393.6, 0)
self.assertAlmostEqual(
round(danger_space.end.distance >> Distance.Yard, Distance.Yard.accuracy), 579.0, 0)
round(danger_space.end.x >> Distance.Yard, Distance.Yard.accuracy), 579.0, 0)

danger_space = self.shot_result.danger_space(
Distance.Yard(500), Distance.Inch(10), self.look_angle
)

self.assertAlmostEqual(
round(danger_space.begin.distance >> Distance.Yard, Distance.Yard.accuracy), 484.5, 0)
round(danger_space.begin.x >> Distance.Yard, Distance.Yard.accuracy), 484.5, 0)
self.assertAlmostEqual(
round(danger_space.end.distance >> Distance.Yard, Distance.Yard.accuracy), 514.8, 0)
round(danger_space.end.x >> Distance.Yard, Distance.Yard.accuracy), 514.8, 0)
2 changes: 1 addition & 1 deletion tests/test_trajectory.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def validate_one(self, data: TrajectoryData, distance: float, velocity: float,
windage: float, wind_adjustment: float, time: float, ogv: float,
adjustment_unit: Unit):

self.custom_assert_equal(distance, data.distance >> Distance.Yard, 0.001, "Distance")
self.custom_assert_equal(distance, data.x >> Distance.Yard, 0.001, "Distance")
self.custom_assert_equal(velocity, data.velocity >> Velocity.FPS, 5, "Velocity")
self.custom_assert_equal(mach, data.mach, 0.005, "Mach")
self.custom_assert_equal(energy, data.energy >> Energy.FootPound, 5, "Energy")
Expand Down

0 comments on commit f20fa90

Please sign in to comment.