pub mod vec_p {
#[derive(Debug)]
pub struct VecP {
pub x: f64,
pub y: f64,
pub z: f64,
}
impl VecP {
pub fn modul(&self) -> f64 {
(self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
}
}
pub fn add(a: &VecP, b: &VecP) -> VecP {
VecP {
x: a.x + b.x,
y: a.y + b.y,
z: a.z + b.z,
}
}
pub fn add_scaled(a: &VecP, s: f64, b: &VecP) -> VecP {
VecP {
x: a.x + s * b.x,
y: a.y + s * b.y,
z: a.z + s * b.z,
}
}
pub fn sub(a: &VecP, b: &VecP) -> VecP {
VecP {
x: a.x - b.x,
y: a.y - b.y,
z: a.z - b.z,
}
}
pub fn dot(a: &VecP, b: &VecP) -> f64 {
a.x * b.x + a.y * b.y + a.z * b.z
}
pub fn cross(a: &VecP, b: &VecP) -> VecP {
VecP {
x: a.y * b.z - a.z * b.y,
y: a.z * b.x - a.x * b.z,
z: a.x * b.y - a.y * b.x,
}
}
pub fn scale(s: f64, a: &VecP) -> VecP {
VecP {
x: s * a.x,
y: s * a.y,
z: s * a.z,
}
}
pub fn sep_angl(a: &VecP, b: &VecP) -> f64 {
let ss = cross(a, b).modul();
let cs = dot(a, b);
if (ss != 0.0) || (cs != 0.0) {
ss.atan2(cs)
} else {
0.0
}
}
pub fn pos_angl(a: &VecP, b: &VecP) -> f64 {
let am = a.modul();
let au = scale(1.0 / am, a);
let bm = b.modul();
if (am == 0.0) || (bm == 0.0) {
0.0
} else {
let eta: VecP = VecP {
x: -a.x * a.z,
y: -a.y * a.z,
z: a.x * a.x + a.y * a.y,
};
let xi = cross(&eta, &au);
let ab = sub(&b, &a);
let st = dot(&ab, &xi);
let ct = dot(&ab, &eta);
if (st == 0.0) && (ct == 0.0) {
0.0
} else {
st.atan2(ct)
}
}
}
pub fn vel(t0: f64, p0: &VecP, t1: f64, p1: &VecP) -> VecP {
let dt = t1 - t0;
VecP {
x: (p1.x - p0.x) / dt,
y: (p1.y - p0.y) / dt,
z: (p1.z - p0.z) / dt,
}
}
pub fn interp(t: f64, t0: f64, p0: &VecP, t1: f64, p1: &VecP) -> VecP {
let dt = t - t0;
let vel = vel(t0, p0, t1, p1);
add_scaled(p0, dt, &vel)
}
}
pub mod vec_pv {
use super::vec_p::VecP;
use crate::math::scalar::scl_sv::SclSv;
#[derive(Debug)]
pub struct VecPv {
pub x: f64,
pub y: f64,
pub z: f64,
pub vx: f64,
pub vy: f64,
pub vz: f64,
}
impl VecPv {
pub fn modul(&self) -> SclSv {
let m = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
SclSv {
s: m,
v: (self.x * self.vx + self.y * self.vy + self.z * self.vz) / m,
}
}
pub fn modul_v(&self) -> f64 {
let v = VecP {
x: self.vx,
y: self.vy,
z: self.vz,
};
v.modul()
}
}
pub fn add(a: &VecPv, b: &VecPv) -> VecPv {
VecPv {
x: a.x + b.x,
y: a.y + b.y,
z: a.z + b.z,
vx: a.vx + b.vx,
vy: a.vy + b.vy,
vz: a.vz + b.vz,
}
}
pub fn sub(a: &VecPv, b: &VecPv) -> VecPv {
VecPv {
x: a.x - b.x,
y: a.y - b.y,
z: a.z - b.z,
vx: a.vx - b.vx,
vy: a.vy - b.vy,
vz: a.vz - b.vz,
}
}
pub fn dot(a: &VecPv, b: &VecPv) -> SclSv {
SclSv {
s: a.x * b.x + a.y * b.y + a.z * b.z,
v: a.x * b.vx + a.y * b.vy + a.z * b.vz + a.vx * b.x + a.vy * b.y + a.vz * b.z,
}
}
pub fn cross(a: &VecPv, b: &VecPv) -> VecPv {
VecPv {
x: a.y * b.z - a.z * b.y,
y: a.z * b.x - a.x * b.z,
z: a.x * b.y - a.y * b.x,
vx: a.y * b.vz + a.vy * b.z - a.z * b.vy - a.vz * b.y,
vy: a.z * b.vx + a.vz * b.x - a.x * b.vz - a.vx * b.z,
vz: a.x * b.vy + a.vx * b.y - a.y * b.vx - a.vy * b.x,
}
}
pub fn scale(s: f64, a: &VecPv) -> VecPv {
VecPv {
x: s * a.x,
y: s * a.y,
z: s * a.z,
vx: s * a.vx,
vy: s * a.vy,
vz: s * a.vz,
}
}
pub fn scale_other(sp: f64, sv: f64, a: &VecPv) -> VecPv {
VecPv {
x: sp * a.x,
y: sp * a.y,
z: sp * a.z,
vx: sv * a.vx,
vy: sv * a.vy,
vz: sv * a.vz,
}
}
pub fn sep_angl(a: &VecPv, b: &VecPv) -> SclSv {
let ss = cross(a, b).modul();
let cs = dot(a, b);
if (ss.s != 0.0) || (cs.s != 0.0) {
SclSv {
s: ss.s.atan2(cs.s),
v: (ss.v * cs.s - ss.s * cs.v) / (ss.s * ss.s + cs.s * cs.s),
}
} else {
SclSv { s: 0.0, v: 0.0 }
}
}
pub fn update(t: f64, t0: f64, pva0: &VecPv) -> VecPv {
let dt = t - t0;
VecPv {
x: (pva0.x + dt * pva0.vx),
y: (pva0.y + dt * pva0.vy),
z: (pva0.z + dt * pva0.vz),
vx: (pva0.vx),
vy: (pva0.vy),
vz: (pva0.vz),
}
}
pub fn interp(t: f64, t0: f64, pv0: &VecPv, t1: f64, pv1: &VecPv) -> VecPv {
let dt = t - t0;
let dta = t1 - t0;
let dacc = super::vec_p::VecP {
x: (pv1.vx - pv0.vx) / dta,
y: (pv1.vy - pv0.vy) / dta,
z: (pv1.vz - pv0.vz) / dta,
};
VecPv {
x: (pv0.x + dt * (pv0.vx + 0.5 * dt * dacc.x)),
y: (pv0.y + dt * (pv0.vy + 0.5 * dt * dacc.y)),
z: (pv0.z + dt * (pv0.vz + 0.5 * dt * dacc.z)),
vx: (pv0.vx + dt * dacc.x),
vy: (pv0.vy + dt * dacc.y),
vz: (pv0.vz + dt * dacc.z),
}
}
}
pub mod vec_pva {
use crate::math::scalar::scl_sv::SclSv;
use crate::math::scalar::scl_sva::SclSva;
#[derive(Debug)]
pub struct VecPva {
pub x: f64,
pub y: f64,
pub z: f64,
pub vx: f64,
pub vy: f64,
pub vz: f64,
pub ax: f64,
pub ay: f64,
pub az: f64,
}
impl VecPva {
pub fn modul(&self) -> SclSva {
let m = (self.x * self.x + self.y * self.y + self.z * self.z).sqrt();
let mv2 = self.x * self.vx + self.y * self.vy + self.z * self.vz;
SclSva {
s: (m),
v: (mv2 / m),
a: ((self.x * self.ax
+ self.vx * self.vx
+ self.y * self.ay
+ self.vy * self.vy
+ self.z * self.az
+ self.vz * self.vz)
/ m
- (mv2 * mv2) / (m * m * m)),
}
}
pub fn modul_v(&self) -> SclSv {
let a = super::vec_pv::VecPv {
x: self.vx,
y: self.vy,
z: self.vz,
vx: self.ax,
vy: self.ay,
vz: self.az,
};
a.modul()
}
pub fn modul_a(&self) -> f64 {
let a = super::vec_p::VecP {
x: self.ax,
y: self.ay,
z: self.az,
};
a.modul()
}
}
pub fn add(a: &VecPva, b: &VecPva) -> VecPva {
VecPva {
x: (a.x + b.x),
y: (a.y + b.y),
z: (a.z + b.z),
vx: (a.vx + b.vx),
vy: (a.vy + b.vy),
vz: (a.vz + b.vz),
ax: (a.ax + b.ax),
ay: (a.ay + b.ay),
az: (a.az + b.az),
}
}
pub fn sub(a: &VecPva, b: &VecPva) -> VecPva {
VecPva {
x: (a.x - b.x),
y: (a.y - b.y),
z: (a.z - b.z),
vx: (a.vx - b.vx),
vy: (a.vy - b.vy),
vz: (a.vz - b.vz),
ax: (a.ax - b.ax),
ay: (a.ay - b.ay),
az: (a.az - b.az),
}
}
pub fn dot(a: &VecPva, b: &VecPva) -> SclSva {
SclSva {
s: (a.x * b.x + a.y * b.y + a.z * b.z),
v: (a.x * b.vx + a.y * b.vy + a.z * b.vz + a.vx * b.x + a.vy * b.y + a.vz * b.z),
a: (a.x * b.ax
+ 2.0 * a.vx * b.vx
+ a.y * b.ay
+ 2.0 * a.vy * b.vy
+ a.z * b.az
+ 2.0 * a.vz * b.vz
+ a.ax * b.x
+ a.ay * b.y
+ a.az * b.z),
}
}
pub fn cross(a: &VecPva, b: &VecPva) -> VecPva {
VecPva {
x: (a.y * b.z - a.z * b.y),
y: (a.z * b.x - a.x * b.z),
z: (a.x * b.y - a.y * b.x),
vx: (a.y * b.vz + a.vy * b.z - a.z * b.vy - a.vz * b.y),
vy: (a.z * b.vx + a.vz * b.x - a.x * b.vz - a.vx * b.z),
vz: (a.x * b.vy + a.vx * b.y - a.y * b.vx - a.vy * b.x),
ax: (2.0 * a.vy * b.vz + a.y * b.az + a.ay * b.z
- 2.0 * a.vz * b.vy
- a.z * b.ay
- a.az * b.y),
ay: (2.0 * a.vz * b.vx + a.z * b.ax + a.az * b.x
- 2.0 * a.vx * b.vz
- a.x * b.az
- a.ax * b.z),
az: (2.0 * a.vx * b.vy + a.x * b.ay + a.ax * b.y
- 2.0 * a.vy * b.vx
- a.y * b.ax
- a.ay * b.x),
}
}
pub fn scale(s: f64, a: &VecPva) -> VecPva {
VecPva {
x: (s * a.x),
y: (s * a.y),
z: (s * a.z),
vx: (s * a.vx),
vy: (s * a.vy),
vz: (s * a.vz),
ax: (s * a.ax),
ay: (s * a.ay),
az: (s * a.az),
}
}
pub fn scale_other(sp: f64, sv: f64, sa: f64, a: &VecPva) -> VecPva {
VecPva {
x: (sp * a.x),
y: (sp * a.y),
z: (sp * a.z),
vx: (sv * a.vx),
vy: (sv * a.vy),
vz: (sv * a.vz),
ax: (sa * a.ax),
ay: (sa * a.ay),
az: (sa * a.az),
}
}
pub fn sep_angl(a: &VecPva, b: &VecPva) -> SclSva {
let ss = cross(a, b).modul();
let cs = dot(a, b);
if (ss.s != 0.0) || (cs.s != 0.0) {
let svs = ss.v * cs.s - ss.s * cs.v;
let norm = ss.s * ss.s + cs.s * cs.s;
SclSva {
s: (ss.s.atan2(cs.s)),
v: (svs / norm),
a: ((norm * (cs.s * ss.a - ss.s * cs.a) - 2.0 * svs * (cs.s * cs.v + ss.s * ss.v))
/ (norm * norm)),
}
} else {
SclSva {
s: 0.0,
v: 0.0,
a: 0.0,
}
}
}
pub fn update(t: f64, t0: f64, pva0: &VecPva) -> VecPva {
let dt = t - t0;
VecPva {
x: (pva0.x + dt * (pva0.vx + dt * 0.5 * pva0.ax)),
y: (pva0.y + dt * (pva0.vy + dt * 0.5 * pva0.ay)),
z: (pva0.z + dt * (pva0.vz + dt * 0.5 * pva0.az)),
vx: (pva0.vx + dt * pva0.ax),
vy: (pva0.vy + dt * pva0.ay),
vz: (pva0.vz + dt * pva0.az),
ax: (pva0.ax),
ay: (pva0.ay),
az: (pva0.az),
}
}
pub fn interp(t: f64, t0: f64, pva0: &VecPva, t1: f64, pva1: &VecPva) -> VecPva {
let dt = t - t0;
let dta = t1 - t0;
let dacc = super::vec_p::VecP {
x: (pva1.ax - pva0.ax) / dta,
y: (pva1.ay - pva0.ay) / dta,
z: (pva1.az - pva0.az) / dta,
};
VecPva {
x: (pva0.x + dt * (pva0.vx + dt * (0.5 * pva0.ax + dt * dacc.x / 6.0))),
y: (pva0.y + dt * (pva0.vy + dt * (0.5 * pva0.ay + dt * dacc.y / 6.0))),
z: (pva0.z + dt * (pva0.vz + dt * (0.5 * pva0.az + dt * dacc.z / 6.0))),
vx: (pva0.vx + dt * (pva0.ax + 0.5 * dt * dacc.x)),
vy: (pva0.vy + dt * (pva0.ay + 0.5 * dt * dacc.y)),
vz: (pva0.vz + dt * (pva0.az + 0.5 * dt * dacc.z)),
ax: (pva0.ax + dt * dacc.x),
ay: (pva0.ay + dt * dacc.y),
az: (pva0.az + dt * dacc.z),
}
}
}