Skip to content

Instantly share code, notes, and snippets.

@BertanT
Created August 9, 2025 07:05
Show Gist options
  • Save BertanT/b99b663f1ded762fd1a9d3f2b7abceb9 to your computer and use it in GitHub Desktop.
Save BertanT/b99b663f1ded762fd1a9d3f2b7abceb9 to your computer and use it in GitHub Desktop.
Enter the dimensions of your eyepiece and camera specs, and we will pop out the front frame size for a viewfinder that matches your camera's field of view!
import numpy as np
def sports_viewfinder_calc(
eye_to_rear_mm,
tunnel_length_mm,
horizontal_fov_deg,
vertical_fov_deg,
aspect_ratio=None # e.g. (3, 2) for 2:3; None = full camera FoV
):
"""
Calculates rear and front rectangle sizes for a sports-style viewfinder.
Parameters:
- eye_to_rear_mm: Distance from eye to rear frame (E)
- tunnel_length_mm: Distance from rear frame to front frame (T)
- horizontal_fov_deg: Camera horizontal field of view
- vertical_fov_deg: Camera vertical field of view
- aspect_ratio: Optional (width, height) tuple for cropping (e.g., (3,2))
Returns:
- rear_width_mm, rear_height_mm, front_width_mm, front_height_mm
"""
h_fov_rad = np.radians(horizontal_fov_deg)
v_fov_rad = np.radians(vertical_fov_deg)
# Full-FoV rear size
rear_width_mm = 2 * eye_to_rear_mm * np.tan(h_fov_rad / 2)
rear_height_mm = 2 * eye_to_rear_mm * np.tan(v_fov_rad / 2)
# Aspect ratio cropping
if aspect_ratio:
target_aspect = aspect_ratio[0] / aspect_ratio[1]
current_aspect = rear_width_mm / rear_height_mm
if target_aspect > current_aspect:
# Crop height
rear_height_mm = rear_width_mm / target_aspect
else:
# Crop width
rear_width_mm = rear_height_mm * target_aspect
# Scale factor from rear to front
scale = (eye_to_rear_mm + tunnel_length_mm) / eye_to_rear_mm
front_width_mm = rear_width_mm * scale
front_height_mm = rear_height_mm * scale
return rear_width_mm, rear_height_mm, front_width_mm, front_height_mm
print("\n*************** Welcome to the Sports Viewfinder Calculator! ***************")
print("""
Enter the dimensions of your eyepiece and camera specs, and we will pop out
the front frame size for a viewfinder that matches your camera's field of view!
""")
eye_to_rear_mm = float(input("Please enter a eye-to-camera distance (mm) : "))
tunnel_length_mm = float(input("Please enter the viewfinder tunnel length (mm) : "))
horizontal_fov_deg = float(input("Please enter the camera's horizontal field of view (deg) : "))
vertical_fov_deg = float(input("Please enter the camera's vertical field of view (deg) : "))
aspect_ratio_input = input("Aspect ratio if you want to crop the image (E.g. (3,2)). Blank if not : ")
if aspect_ratio_input.strip():
try:
w, h = aspect_ratio_input.split(":")
aspect_ratio = (float(w), float(h))
except:
print("Invalid aspect ratio format — using full FoV.")
aspect_ratio = None
else:
aspect_ratio = None
print("\n********************************** Results *********************************")
rw, rh, fw, fh = sports_viewfinder_calc (
eye_to_rear_mm,
tunnel_length_mm,
horizontal_fov_deg,
vertical_fov_deg,
aspect_ratio
)
print("Rear frame width (mm) :", rw)
print("Read frame height (mm) :", rh)
print("Front frame width (mm) :", fw)
print("Front frame height (mm) :", fh)
print("****************************************************************************")
print("\n Have a nice day :)")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment