Как мне найти сферу тетраэдра?

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

herme5
источник
4
Попробуйте обменять математику.
Majte
Спасибо, я нашел способ вычислить окружность там!
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 )

Как я понимаю, изоморфизм может иметь несколько различных значений при использовании в геометрии. Если он имеет в виду изоморфность в отношении теории графов, то следующий код должен вести себя корректно, поскольку топология любого тетраэдра одинакова (K4, полный граф). Я проверил результаты функции против альфа-вольфрама, используя различные перестановки в упорядочении канонических вершин, и я не увидел различий в результате. Если упорядочение оказывается проблемой, я предлагаю исследовать нормаль треугольника, образованного вершинами 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);
}
Джон Кельцер
источник