¿Como encuentro la circunsfera de un tetraedro?

9

Estoy buscando la ecuación más minimizada para encontrar las coordenadas centrales y el radio de una circunsfera de tetraedro dados cuatro puntos 3D.

Lo que encontré en Internet se ocupa principalmente de la circunferencia de un triángulo plano 3D, o de algunas definiciones matemáticas aproximadas, o de casos muy simples, como los tetraedros regulares. De todos modos logré encontrar la ecuación a continuación, pero me perdí algo:

    ->  ->      ->
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 |

Mi conocimiento en este campo tiene sus límites, pero creo que puedo manejar matrices y operaciones de vectores. Pero, ¿es la parte correcta de la ecuación el cuadrado de la norma de cada vector? (que están en un vector). ¿Es válida la ecuación? ¿Es solo el escritor que perezosamente olvidó escribir | d1 | ^ 2? O ¿Es una forma común de definir alguna propiedad matemática?

PD: es para una implementación de triangulación de Delaunay. La ecuación (número 9) se encuentra en el siguiente enlace: https://www2.mps.mpg.de/homes/daly/CSDS/t4h/tetra.htm

herme5
fuente
44
Prueba las matemáticas stackexchange.
Majte
¡Gracias, he encontrado una manera de calcular la circunsfera allí!
herme5
1
@JamesAMD el enlace es www2.mps.mpg.de/homes/daly/CSDS/t4h/tetra.htm .
herme5
3
@ herme5, siéntase libre de publicar su propia respuesta aquí sobre cómo está calculando la respuesta. Muchas personas pueden venir aquí en el futuro con la esperanza de encontrar la respuesta, y compartirla será valioso para ellos. Es totalmente aceptable publicar su propia respuesta e incluso aceptarla.
Tim Holt
2
Gracias por el aviso @TimHolt. Lo haré ! Sin embargo, ya no estoy seguro de cómo lo hice, ¡fue hace más de 2 años! solo déjame encontrar y echar un vistazo a mi implementación anterior
herme5

Respuestas:

2

Si bien este es un hilo antiguo, pensé que sería bueno para la posteridad tener un poco de referencia. La fuente de la fórmula es de Herramientas geométricas para gráficos por computadora de Philip J. Schneider y David H. Eberly. Algo a tener en cuenta, según el texto.

El tetraedro V0, V1, V2, V3 se ordena de modo que sea isomorfo al canónico (0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1 )

Según entiendo el isomorfismo , puede haber varios significados diferentes cuando se usa en geometría. Si quiere decir isomorfo con respecto a la teoría de grafos, entonces el siguiente código debería comportarse correctamente, ya que la topología de cualquier tetraedro es la misma (K4, un gráfico completo). I probaron los resultados de la función contra wolfram alpha utilizando diversas permutaciones en el orden de los vértices canónicas, y vi ninguna diferencia en el resultado. Si el orden demuestra ser un problema, sugiero examinar la normalidad del triángulo formado por los vértices V1, V2, V3 al ingresar a esta función, y tratar los puntos como un medio espacio con una prueba de producto de punto para descubrir si ese triángulo está orientado en la dirección correcta. Si no es así, un simplestd::swapde cualquiera de los dos vértices del triángulo invertirá la dirección de lo normal y puede continuar. Pero como dije, no vi diferencia con varias permutaciones.

Aquí está el código traducido sin usar matrices para evitar confusiones de implementación, es bastante sencillo;

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);
}
Jon Koelzer
fuente