use crate::Vec3;
use crate::x_l1;
pub fn blink(q: f64, r: &Vec3, e: &Vec3, acc: f64) -> bool {
static mut QQ: f64 = -100.0;
let mut x_cofm: f64 = 0.0;
let mut c1: f64 = 0.0;
let mut c2: f64 = 0.0;
let mut step: f64 = 0.0;
let mut pp: f64 = 0.0;
let mut crit: f64 = 0.0;
let mut p: f64;
let p1: f64;
let p2: f64;
let mut r1: f64;
let mut r2: f64;
if q != unsafe { QQ } {
if q <= 0.0 {
panic!("q = {} <= 0", q);
}
if acc <= 0.0 {
panic!("Invalid accuracy parameter. {} <= 0.0.", acc);
}
unsafe { QQ = q; }
x_cofm = 1.0 / (1.0 + q);
c1 = 2.0 * x_cofm;
x_cofm *= q;
c2 = 2.0 * x_cofm;
let rl1: f64 = x_l1(q);
r1 = rl1;
r2 = 1.0 - rl1;
let xc: f64 = rl1 - x_cofm;
crit = c1/r1 + c2/r2 + xc*xc;
let rsphere: f64 = 1.0 - rl1;
pp = rsphere*rsphere;
step = rsphere*acc
}
let xt: f64 = r.x - 1.0;
let mut b: f64 = e.x*xt + e.y*r.y + e.z*r.z;
let mut c: f64 = xt*xt + r.y*r.y + r.z*r.z - pp;
let mut fac: f64 = b*b - c;
if fac <= 0.0 {
return false;
}
fac = fac.sqrt();
let par2: f64 = -b + fac;
if par2 <= 0.0 {
return false;
}
let mut par1: f64 = -b - fac;
par1 = if par1 > 0.0 {
par1
} else {
0.0
};
let par: f64 = if b < 0.0 {
-b
} else {
0.0
};
let mut x1: f64 = r.x + par*e.x;
let mut x2: f64 = r.y + par*e.y;
let mut x3: f64 = r.z + par*e.z;
let mut xm: f64 = x1 - 1.0;
let mut yy: f64 = x2*x2;
let mut rr: f64 = yy + x3*x3;
let rs2: f64 = xm*xm + rr;
if rs2 <= 0.0 {
return true;
}
let rs1: f64 = x1*x1 + rr;
r1 = rs1.sqrt();
r2 = rs2.sqrt();
let mut xc: f64 = x1 - x_cofm;
c = c1/r1 + c2/r2 + xc*xc + yy;
if c > crit {
return true;
}
let a: f64 = x1*e.x + x2*e.y;
b = a + x3*e.z;
if -c1*b/(rs1*r1) - c2*(b - e.x)/(rs2*r2) + 2.0*(a - x_cofm*e.x) > 0.0 {
p1 = par;
p2 = par2;
} else {
p1 = par;
p2 = par1;
}
let mut nstep: i32 = ((p2-p1).abs() / step + 0.5).floor() as i32;
nstep = nstep.max(2);
let dp: f64 = (p2-p1)/(nstep as f64);
let mut cmax: f64 = c - 1.0;
let mut i: i32 = 0;
while c > cmax && i < nstep {
i += 1;
cmax = c;
p = p1 + dp*(i as f64);
x1 = r.x + p*e.x;
x2 = r.y + p*e.y;
x3 = r.z + p*e.z;
xm = x1 - 1.0;
yy = x2*x2;
rr = yy + x3*x3;
r2 = (xm*xm + rr).sqrt();
if r2 <= 0.0 {
return true;
}
r1 = (x1*x1 + rr).sqrt();
xc = x1 - x_cofm;
c = c1/r1 + c2/r2 + xc*xc + yy;
if c > crit {
return true;
}
}
return false
}