Intersection Cone::Intercepta(const Raio& r_vis, IntersectionMode mode, float threshold) { float a, b, c, delta; Intersection intersection; // valores intermediários Vetor_3D K = Vetor_3D(r_vis.X0() - centro.X(), r_vis.Y0() - centro.Y(), r_vis.Z0() - centro.Z()); // montando a equação do 2º grau at2 + bt + c = 0 // equação para o cone: a = pow(r_vis.Direcao().X(), 2) + pow(r_vis.Direcao().Z(), 2) - pow(r_vis.Direcao().Z(), 2); b = 2*((r_vis.Direcao().X() * K.X()) + (r_vis.Direcao().Z() * K.Y()) - (r_vis.Direcao().Z() * K.Z)); c = pow(K.X(), 2) + pow(K.Y(), 2) - pow(K.Z(), 2); delta = b*b - 4*a*c; if (delta >= 0) { float t_plus = (-b + sqrt(delta)) /(2*a); float t_minus = (-b - sqrt(delta)) /(2*a); Ponto_3D p_plus( r_vis.Origem().X() + r_vis.Direcao().X()*t_plus , r_vis.Origem().Y() + r_vis.Direcao().Y()*t_plus , r_vis.Origem().Z() + r_vis.Direcao().Z()*t_plus ); Ponto_3D p_minus( r_vis.Origem().X() + r_vis.Direcao().X()*t_minus , r_vis.Origem().Y() + r_vis.Direcao().Y()*t_minus , r_vis.Origem().Z() + r_vis.Direcao().Z()*t_minus ); bool p_plus_dentro_do_intervalo = false; bool p_minus_dentro_do_intervalo = false; if ((p_plus.Y() < (centro.Y() + altura/2.0)) && (p_minus.Y() > (centro.Y() - altura/2.0))) p_plus_dentro_do_intervalo = true; if ((p_minus.Y() < (centro.Y() + altura/2.0)) && (p_minus.Y() > (centro.Y() - altura/2.0))) p_minus_dentro_do_intervalo = true; if (p_plus_dentro_do_intervalo && p_minus_dentro_do_intervalo){ intersection = Intersection::nearest( Intersection(this, t_plus), Intersection(this, t_minus), threshold); } else if (p_plus_dentro_do_intervalo){ intersection.setValues(this, t_plus); } else if (p_minus_dentro_do_intervalo){ intersection.setValues(this, t_minus); } } return intersection; }
static Term eval2(Int fi, Term t1, Term t2 USES_REGS) { arith2_op f = fi; switch (f) { case op_plus: return p_plus(t1, t2 PASS_REGS); case op_minus: return p_minus(t1, t2 PASS_REGS); case op_times: return p_times(t1, t2 PASS_REGS); case op_div: return p_div(t1, t2 PASS_REGS); case op_idiv: return p_div2(t1, t2 PASS_REGS); case op_and: return p_and(t1, t2 PASS_REGS); case op_or: return p_or(t1, t2 PASS_REGS); case op_sll: return p_sll(t1, t2 PASS_REGS); case op_slr: return p_slr(t1, t2 PASS_REGS); case op_mod: return p_mod(t1, t2 PASS_REGS); case op_rem: return p_rem(t1, t2 PASS_REGS); case op_fdiv: return p_fdiv(t1, t2 PASS_REGS); case op_xor: return p_xor(t1, t2 PASS_REGS); case op_atan2: return p_atan2(t1, t2 PASS_REGS); case op_power: return p_exp(t1, t2 PASS_REGS); case op_power2: return p_power(t1, t2 PASS_REGS); case op_gcd: return p_gcd(t1, t2 PASS_REGS); case op_min: return p_min(t1, t2); case op_max: return p_max(t1, t2); case op_rdiv: return p_rdiv(t1, t2 PASS_REGS); } RERROR(); }
Point<float> GMWMI_finder::get_normal (const Point<float>& p, Interp& interp) const { Point<float> normal (0.0, 0.0, 0.0); for (size_t axis = 0; axis != 3; ++axis) { Point<float> p_minus (p); p_minus[axis] -= 0.5 * GMWMI_PERTURBATION; const Tissues v_minus = get_tissues (p_minus, interp); Point<float> p_plus (p); p_plus[axis] += 0.5 * GMWMI_PERTURBATION; const Tissues v_plus = get_tissues (p_plus, interp); normal[axis] = (v_plus.get_wm() - v_plus.get_gm()) - (v_minus.get_wm() - v_minus.get_gm()); } return (normal.normalise()); }
Point<float> GMWMI_finder::get_cf_min_step (const Point<float>& p, Interp& interp) const { Point<float> grad (0.0, 0.0, 0.0); for (size_t axis = 0; axis != 3; ++axis) { Point<float> p_minus (p); p_minus[axis] -= 0.5 * GMWMI_PERTURBATION; const Tissues v_minus = get_tissues (p_minus, interp); Point<float> p_plus (p); p_plus[axis] += 0.5 * GMWMI_PERTURBATION; const Tissues v_plus = get_tissues (p_plus, interp); if (!v_minus.valid() || !v_plus.valid()) return Point<float> (0.0, 0.0, 0.0); grad[axis] = (v_plus.get_gm() - v_plus.get_wm()) - (v_minus.get_gm() - v_minus.get_wm()); } grad *= (1.0 / GMWMI_PERTURBATION); if (!grad.norm2()) return Point<float> (0.0, 0.0, 0.0); const Tissues local_tissue = get_tissues (p, interp); const float diff = local_tissue.get_gm() - local_tissue.get_wm(); Point<float> step = -grad * (diff / grad.norm2()); const float norm = step.norm(); if (norm > 0.5 * min_vox) step *= 0.5 * min_vox / norm; return step; }