use lox_core::glam::DVec3;
use lox_core::units::{Angle, Decibel, Frequency};
use crate::pattern::AntennaPattern;
pub trait AntennaGain {
fn gain(&self, frequency: Frequency, angle: Angle) -> Decibel;
fn beamwidth(&self, frequency: Frequency) -> Option<Angle>;
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SimpleAntenna {
pub gain: Decibel,
pub beamwidth: Angle,
}
impl AntennaGain for SimpleAntenna {
fn gain(&self, _frequency: Frequency, _angle: Angle) -> Decibel {
self.gain
}
fn beamwidth(&self, _frequency: Frequency) -> Option<Angle> {
Some(self.beamwidth)
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ComplexAntenna {
pub pattern: AntennaPattern,
pub boresight: DVec3,
}
impl AntennaGain for ComplexAntenna {
fn gain(&self, frequency: Frequency, angle: Angle) -> Decibel {
self.pattern.gain(frequency, angle)
}
fn beamwidth(&self, frequency: Frequency) -> Option<Angle> {
self.pattern.beamwidth(frequency)
}
}
impl ComplexAntenna {
pub fn peak_gain(&self, frequency: Frequency) -> Decibel {
self.pattern.peak_gain(frequency)
}
}
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(tag = "type"))]
pub enum Antenna {
Simple(SimpleAntenna),
Complex(ComplexAntenna),
}
impl AntennaGain for Antenna {
fn gain(&self, frequency: Frequency, angle: Angle) -> Decibel {
match self {
Antenna::Simple(a) => a.gain(frequency, angle),
Antenna::Complex(a) => a.gain(frequency, angle),
}
}
fn beamwidth(&self, frequency: Frequency) -> Option<Angle> {
match self {
Antenna::Simple(a) => a.beamwidth(frequency),
Antenna::Complex(a) => a.beamwidth(frequency),
}
}
}