मैं मार्चिंग क्यूब्स के साथ isosurfaces, प्रस्तुत करना (या शायद अग्रसर वर्गों के रूप में इस 2 डी) है और मैं सेट अंतर, चौराहे और संघ की तरह सेट संचालन करना चाहते हैं। मुझे लगा कि यह लागू करने के लिए, बस दो अलग अलग अंतर्निहित सतहों से दो शीर्ष scalars के बीच चुनने के द्वारा आसान था, लेकिन यह नहीं है।CSG संचालन
मेरी प्रारंभिक परीक्षण के लिए, मैं सेट आपरेशन अंतर दो
क्षेत्रों
मंडलियों के साथ की कोशिश की, और। i.e ए - बी एक सर्कल चल रहा है और दूसरा स्थिर है। यहाँ दृष्टिकोण मैंने कोशिश की जब शिखर scalars उठा और जब अंदर या बाहर के रूप में कोने कोने में वर्गीकृत है। कोड सी ++ में लिखा गया है। ओपनजीएल का उपयोग प्रतिपादन के लिए किया जाता है, लेकिन यह महत्वपूर्ण नहीं है। किसी भी सीएसजी संचालन के बिना सामान्य प्रतिपादन अपेक्षित परिणाम देता है।
void march(const vec2& cmin, //min x and y for the grid cell
const vec2& cmax, //max x and y for the grid cell
std::vector<vec2>& tri,
float iso,
float (*cmp1)(const vec2&), //distance from stationary circle
float (*cmp2)(const vec2&) //distance from moving circle
)
{
unsigned int squareindex = 0;
float scalar[4];
vec2 verts[8];
/* initial setup of the grid cell */
verts[0] = vec2(cmax.x, cmax.y);
verts[2] = vec2(cmin.x, cmax.y);
verts[4] = vec2(cmin.x, cmin.y);
verts[6] = vec2(cmax.x, cmin.y);
float s1,s2;
/**********************************
********For-loop of interest******
*******Set difference between ****
*******two implicit surfaces******
**********************************/
for(int i=0,j=0; i<4; ++i, j+=2){
s1 = cmp1(verts[j]);
s2 = cmp2(verts[j]);
if((s1 < iso)){ //if inside circle1
if((s2 < iso)){ //if inside circle2
scalar[i] = s2; //then set the scalar to the moving circle
} else {
scalar[i] = s1; //only inside circle1
squareindex |= (1<<i); //mark as inside
}
}
else {
scalar[i] = s1; //inside neither circle
}
}
if(squareindex == 0)
return;
/* Usual interpolation between edge points to compute
the new intersection points */
verts[1] = mix(iso, verts[0], verts[2], scalar[0], scalar[1]);
verts[3] = mix(iso, verts[2], verts[4], scalar[1], scalar[2]);
verts[5] = mix(iso, verts[4], verts[6], scalar[2], scalar[3]);
verts[7] = mix(iso, verts[6], verts[0], scalar[3], scalar[0]);
for(int i=0; i<10; ++i){ //10 = maxmimum 3 triangles, + one end token
int index = triTable[squareindex][i]; //look up our indices for triangulation
if(index == -1)
break;
tri.push_back(verts[index]);
}
}
यह मैं देता अजीब jaggies: here http://www.mechcore.net/images/gfx/csgbug2.png
यह CSG आपरेशन की तरह लग रहा प्रक्षेप बिना किया जाता है। यह सिर्फ पूरे त्रिकोण को "त्याग" करता है। मैं किसी अन्य तरीके से अंतर्वेशन, या शीर्ष अदिश मूल्यों गठबंधन करने के लिए की जरूरत है? मुझे इसके साथ कुछ मदद चाहिए। एक पूर्ण testcase डाउनलोड किया जा सकता HERE
संपादित करें: असल में, मार्चिंग वर्गों ठीक काम करता है की मेरी कार्यान्वयन। यह मेरी अदिश क्षेत्र जो टूट गया है है, और मुझे आश्चर्य है कि सही तरीका कैसे दिखाई देते हैं। अधिमानतः मैं तीन सेट के संचालन मैं ऊपर चर्चा की, हमेशा की तरह पुरातन (सर्कल, आयत/स्क्वायर, विमान)
संपादित 2 के लिए लागू करने के लिए एक सामान्य दृष्टिकोण के लिए देख रहा हूँ: यहाँ लागू करने के बाद कुछ नए चित्र हैं उत्तर देने के श्वेतपत्र:
1.Difference
2.Intersection
3.Union
संपादित करें 3: मैं भी 3 डी में इस लागू किया, उचित छायांकन/प्रकाश व्यवस्था के साथ:
1.Difference between a greater sphere and a smaller sphere
2.Difference between a greater sphere and a smaller sphere in the center, clipped by two planes on both sides, and then union with a sphere in the center.
3.Union between two cylinders.
हम्म, अजीब। यह वास्तव में काम करता है, लेकिन किनारे अजीब तरह मिलता है। मैं जांच कर रहा हूं कि यह एक सटीक समस्या है या नहीं। हालांकि यह सामान्य सर्कल के लिए दिखाई नहीं देता है। यहां एक 100x100 ग्रिड का एक स्क्रीनशॉट है: http://www.mechcore.net/images/gfx/csgbug3.png –
ठीक है, यह एक सटीक मुद्दा है। बड़ी सर्कल बहुत अच्छी काम करती है, लेकिन ग्रिड टेस्सेलेशन में वृद्धि नहीं होती है (मैं फ्लोट्स का उपयोग कर रहा हूं)। महान जवाब और महान पेपर। श्रीमान के लिए मेरा गहरा धन्यवाद –
आपका स्वागत है! आपकी परियोजना के साथ शुभकामनाएं, अंतर्निहित सतह मजेदार हैं! –