हालांकि यह एक प्राचीन धागा है, मैंने सोचा कि पोस्टीरिटी के लिए संदर्भ के लिए थोड़ा सा होना अच्छा हो सकता है। सूत्र का स्रोत फिलिप जे। श्नाइडर और डेविड एच। एर्ली द्वारा कंप्यूटर ग्राफिक्स के लिए ज्यामितीय उपकरण से है । पाठ के अनुसार कुछ ध्यान दें
टेट्राहेड्रोन 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);
}