Як я можу знайти навколосферу тетраедра?


9

Я шукаю найбільш згорнутому рівняння , щоб знайти координати центру і радіус з тетраедра circumsphere дав чотири 3D окуляри.

Що я знайшов в Інтернеті, головним чином стосується кругової сфери плоского трикутника, або якихось приблизних математичних визначень, або деяких дуже одиничних випадків, таких як звичайні тетраедри. У будь-якому разі мені вдалося знайти рівняння нижче, але я щось пропустив:

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

Мої знання в цій галузі мають свої межі, але я думаю, що я можу впоратися з матрицями та векторними операціями. Але чи є правильною частиною рівняння квадрат норми кожного вектора? (які перебувають у векторі). Чи справедливе рівняння? Це просто письменник, який ледаче забув написати | d1 | ^ 2? Або це загальний спосіб визначення якоїсь математичної властивості.

PS: Це для реалізації триангуляції Делоне. Рівняння (номер 9) знаходиться за наступним посиланням: https://www2.mps.mpg.de/homes/daly/CSDS/t4h/tetra.htm


4
Спробуйте математику stackexchange.
Майте

Дякую, що я знайшов спосіб обчислити циркулярну сферу!
herme5

1
@JamesAMD посилання www2.mps.mpg.de/homes/daly/CSDS/t4h/tetra.htm .
herme5

3
@ herme5, сміливо публікуйте тут свою власну відповідь про те, як ви обчислюєте відповідь. Багато людей, можливо, приїдуть сюди в майбутньому, сподіваючись знайти відповідь, і ви поділитесь, це буде для них цінним. Цілком прийнятно розмістити власну відповідь і навіть прийняти її.
Тім Холт

2
Дякуємо за повідомлення @TimHolt. Я зроблю це ! Проте я вже не впевнений, як це зробив, це було більше 2 років тому! просто дозвольте мені знайти та поглянути на мою давню реалізацію
herme5

Відповіді:


2

Хоча це давня нитка, я подумав, що для нащадків може бути непогано мати трохи посилання. Джерело формули - з " Геометричних інструментів комп'ютерної графіки " Філіпа Дж. Шнайдера та Девіда Х. Еберлі. Щось зауважити, згідно тексту

Тетраедр V0, V1, V2, V3 впорядкований так, щоб він був ізоморфним канонічному (0, 0, 0), (1, 0, 0), (0, 1, 0), (0, 0, 1 ).

Як я розумію ізоморфізм , у геометрії може бути кілька різних значень. Якщо він означає ізоморфний щодо теорії графів, то наступний код повинен вести себе правильно, оскільки топологія будь-якого тетраедра однакова (К4, повний графік). Я перевіряв результати функції проти вольфрам-альфа, використовуючи різні перестановки в упорядкуванні канонічних вершин, і не бачив різниці в результаті. Якщо впорядкування виявляється проблемою, я пропоную вивчити норму трикутника, утвореного вершинами V1, V2, V3 при введенні в цю функцію, і обробляти точки, як напівпростір, за допомогою тесту крапкового добутку, щоб з'ясувати якщо цей трикутник звернений у потрібний бік. Якщо ні, простийstd::swapбудь-яких двох вершин трикутника буде змінювати напрямок нормального, і ви можете продовжувати. Але, як я вже говорив, я не бачив різниці в різних перестановках.

Ось перекладений код без використання матриць, щоб уникнути будь-якої плутанини в реалізації, це досить прямо;

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);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.