Skip to main content

rust_roche/
sphere_eclipse.rs

1use std::f64::consts::TAU;
2use crate::Vec3;
3
4
5///
6/// sphere_eclipse tells you whether or not a given sphere will eclipse a 
7/// given point or not. If the answer is yes, it will also return with four 
8/// parameters to define the phase range and the multiplier range delimiting the
9/// region within which the spheres surface is crossed.
10/// These can then be used as the starting point for later computation.
11/// (The line of sight is described as the point in question plus a scalar multiplier
12/// times a unit vector pointing towards Earth -- this is the "multiplier" referred to above
13/// and below). The multiplier must be positive: in other words the routine does not
14/// project backwards. If the point in inside the sphere, phi1 will be set = 0, phi2 = 1,
15/// lam1 = 0, and lam2 = the largest value of the multiplier lambda
16///
17/// \param cosi cosine of orbital inclination
18/// \param sini sine of orbital inclination
19/// \param r       the position vector of the point in question (units of binary separation)
20/// \param c       the centre of the sphere enclosing the star (units of binary separation)
21/// \param rsphere the radius defining the sphere enclosing the star (units of binary separation)
22/// \param phi1    if eclipse by the sphere, this is the start of the phase range (0 -1)
23/// \param phi2    if eclipse by the sphere, this is the end of the phase range (least amount > phi1)
24/// \param lam1    if eclipse by the sphere, this is the start of the multiplier range (>=0)
25/// \param lam2    if eclipse by the sphere, this is the end of the multiplier range (>lam1)
26/// \return false = not eclipsed; true = eclipsed.
27///
28pub fn sphere_eclipse(cosi: f64, sini: f64, r: &Vec3, c: &Vec3, rsphere: f64, phi1: &mut f64, phi2: &mut f64, lam1: &mut f64, lam2: &mut f64) -> bool {
29
30    let d: Vec3 = *r - *c;
31
32    let pdist: f64 = (d.x*d.x + d.y*d.y).sqrt();
33    let bquad: f64 = d.z*cosi - pdist*sini;
34    if bquad >= 0. {
35        return false;
36    }
37    let cquad: f64 = d.sqr() - rsphere*rsphere;
38
39    let mut fac: f64 = bquad*bquad - cquad;
40    if fac <= 0.0 {
41        return false
42    }
43    fac = fac.sqrt();
44
45    *lam2 = -bquad + fac;
46    *lam1 = 0_f64.max(cquad/(*lam2));
47
48    if cquad < 0. {
49        *phi1 = 0.;
50        *phi2 = 1.
51    }else {
52        let delta: f64 = ((cosi*d.z + cquad.sqrt())/(sini*pdist)).acos();
53        let phi: f64 = d.y.atan2(-d.x);
54        *phi1 = (phi - delta)/TAU;
55        *phi1 -= phi1.floor();
56        *phi2 = *phi1 + 2.*delta/TAU;
57    }
58    return true;
59
60}
61
62
63///
64/// This version of sphere_eclipse tells you whether or not a given sphere will eclipse 
65/// a given point at a particular phase or not. If the answer is yes,
66/// it will also return with the multiplier values giving the cut points. These can then
67/// be used as starting points for Roche lobe computations. These can then be used as the 
68/// starting point for later computation. Points inside the sphere are regarded as being
69/// eclipsed with the lower mulitplier set = 0
70///
71/// \param earth   vector towards Earth
72/// \param r       the position vector of the point in question (units of binary separation)
73/// \param c       the centre of the sphere (units of binary separation)
74/// \param rsphere the radius defining the sphere enclosing the star (units of binary separation)
75/// \param lam1    if eclipse by the sphere, this is the start of the multiplier range
76/// \param lam2    if eclipse by the sphere, this is the end of the multiplier range
77/// \return false = not eclipsed; true = eclipsed.
78///
79pub fn sphere_eclipse_vector(earth: &Vec3, r: &Vec3, c: &Vec3, rsphere: f64, lam1: &mut f64, lam2: &mut f64) -> bool {
80
81    let d: Vec3 = *r - *c;
82
83    let bquad: f64 = earth.dot(&d);
84    if bquad >= 0. {
85        return false;
86    }
87    let cquad: f64 = d.sqr() - rsphere*rsphere;
88
89    let mut fac: f64 = bquad*bquad - cquad;
90    if fac <= 0. {
91        return false
92    }
93    fac = fac.sqrt();
94
95    *lam2 = -bquad + fac;
96    *lam1 = 0_f64.max(cquad/(*lam2));
97    return true;
98}