Пример #1
0
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;
}
Пример #2
0
//Foley capítulo 15.10, fórmula 15.17
Intersection Cilindro::Intercepta(const Raio& r_vis, IntersectionMode mode, float threshold)
{
  float a, b, c, delta;
  Intersection intersection;

  // valores intermediários
  float t1, t2; // esticamentos (t*r_vis) do raio que interceptam o cilindro
  Ponto_3D P1, P2; // Pontos em que o raio intercepta o cilindro (podem ser coincidentes)

  Vetor_3D K = Vetor_3D(r_vis.X0() - centro.X(),
                        0,
                        r_vis.Z0() - centro.Z());

  Vetor_3D direcao = Vetor_3D(r_vis.Direcao());
  direcao.setY(0);

  // montando a equação do 2º grau at2 + bt + c = 0
  a = direcao.produtoEscalar(direcao);
  b = 2*(direcao.produtoEscalar(K));
  c = K.produtoEscalar(K) - raio*raio;

  delta = b*b - 4*a*c;
  if (delta >= 0) {
      t1 = (-b - sqrt(delta)) /(2*a);
      t2 = (-b + sqrt(delta)) /(2*a);

      P1 = P2 = r_vis.Origem();

      P1 += r_vis.Direcao()*t1;
      P2 += r_vis.Direcao()*t2;

      // Verifica se pelo menos um dos pontos está dentro do cilindro
      if ( (ALTURA_OK(P1, centro, altura)) || (ALTURA_OK(P2, centro, altura)) ) {
          intersection = Intersection::nearest(
              Intersection(this, t1),
              Intersection(this, t2), threshold);
      }
  }

  return intersection;
}