Como encontro a circunsfera de um tetraedro?


9

Estou procurando a equação mais minimizada para encontrar as coordenadas centrais e o raio de uma circunsfera de tetraedro, com quatro pontos 3D.

O que encontrei na internet lida principalmente com a circunferência de um triângulo 3D plano, ou com algumas definições matemáticas grosseiras, ou com casos muito simples, como tetraedros comuns. Enfim, consegui encontrar a equação abaixo, mas perdi uma coisa:

    ->  ->      ->
let d1, d2, and d3 three vectors of any face of the triangle :

    | d1x  d1y  d1z |   | x |   | d1^2 |
2 * | d2x  d2y  d2z | * | y | = | d2^2 |
    | d3x  d3y  d3z |   | z |   | d3^2 |

Meu conhecimento neste campo tem seus limites, mas acho que posso lidar com matrizes e operações de vetores. Mas a parte direita da equação é o quadrado da norma de cada vetor? (que estão em um vetor). A equação é válida? É apenas o escritor que se esqueceu de escrever | d1 | ^ 2? Ou é uma maneira comum de definir alguma propriedade matemática.

PS: É para uma implementação de Triangulação em Delaunay. A equação (número 9) está no seguinte link: https://www2.mps.mpg.de/homes/daly/CSDS/t4h/tetra.htm


4
Tente matemática stackexchange.
Majte 24/10/2015

Obrigado, encontrei uma maneira de calcular a circunsfera lá!
herme5


3
@ herme5, fique à vontade para postar sua própria resposta aqui sobre como você está calculando a resposta. Muitas pessoas podem vir aqui no futuro na esperança de encontrar a resposta, e você compartilhá-la será valiosa para elas. É totalmente aceitável postar sua própria resposta e até aceitá-la.
Tim Holt

2
Obrigado pelo aviso @ TimHolt. Eu vou fazer isso ! No entanto, não tenho mais certeza de como o fiz, foi há mais de 2 anos! apenas deixe-me encontrar e dar uma olhada em minha implementação de idade
herme5

Respostas:


2

Embora esse seja um tópico antigo, achei que seria bom para a posteridade ter um pouco de referência. A fonte da fórmula é de Geometric Tools for Computer Graphics, de Philip J. Schneider e David H. Eberly. Algo a observar, de acordo com o texto

O tetraedro V0, V1, V2, V3 é ordenado de forma que seja isomórfico ao canônico (0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1 )

Pelo que entendi o isomorfismo , pode haver vários significados diferentes quando usados ​​em geometria. Se ele quer dizer isomórfico em relação à teoria dos grafos, o código a seguir deve se comportar corretamente, pois a topologia de qualquer tetraedro é a mesma (K4, um gráfico completo). Eu testei os resultados da função contra alfa wolfram usando várias permutações na ordenação dos vértices canônicas, e eu não vi nenhuma diferença no resultado. Se a ordem provar ser um problema, sugiro examinar o normal do triângulo formado pelos vértices V1, V2, V3 após a entrada nessa função e tratar os pontos como um meio espaço com um teste de produto a ponto para descobrir se esse triângulo estiver voltado para o lado certo. Se não for, um simplesstd::swapqualquer um dos dois vértices do triângulo reverterá a direção do normal e você poderá continuar. Mas, como eu disse, não vi diferença com várias permutações.

Aqui está o código traduzido sem o uso de matrizes para evitar qualquer confusão na implementação; é bastante direto;

void Circumsphere(const Vec3& v0, const Vec3& v1, const Vec3& v2, const Vec3& v3, Vec3* center, float* radius)
{
  //Create the rows of our "unrolled" 3x3 matrix
  Vec3 Row1 = v1 - v0;
  float sqLength1 = length2(Row1);
  Vec3 Row2 = v2 - v0;
  float sqLength2 = length2(Row2);
  Vec3 Row3 = v3 - v0;
  float sqLength3 = length2(Row3);

  //Compute the determinant of said matrix
  const float determinant =   Row1.x * (Row2.y * Row3.z - Row3.y * Row2.z)
                            - Row2.x * (Row1.y * Row3.z - Row3.y * Row1.z)
                            + Row3.x * (Row1.y * Row2.z - Row2.y * Row1.z);

  // Compute the volume of the tetrahedron, and precompute a scalar quantity for re-use in the formula
  const float volume = determinant / 6.f;
  const float iTwelveVolume = 1.f / (volume * 12.f);

  center->x = v0.x + iTwelveVolume * ( ( Row2.y * Row3.z - Row3.y * Row2.z) * sqLength1 - (Row1.y * Row3.z - Row3.y * Row1.z) * sqLength2 + (Row1.y * Row2.z - Row2.y * Row1.z) * sqLength3 );
  center->y = v0.y + iTwelveVolume * (-( Row2.x * Row3.z - Row3.x * Row2.z) * sqLength1 + (Row1.x * Row3.z - Row3.x * Row1.z) * sqLength2 - (Row1.x * Row2.z - Row2.x * Row1.z) * sqLength3 );
  center->z = v0.z + iTwelveVolume * ( ( Row2.x * Row3.y - Row3.x * Row2.y) * sqLength1 - (Row1.x * Row3.y - Row3.x * Row1.y) * sqLength2 + (Row1.x * Row2.y - Row2.x * Row1.y) * sqLength3 );

  //Once we know the center, the radius is clearly the distance to any vertex
  *radius = length(*center - v0);
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.