2013-04-23 24 views
6

three.js में triangulateShape() फ़ंक्शन है। अब मुझे जावास्क्रिप्ट क्लिपर का उपयोग करके सरलीकृत बहुभुजों को त्रिकोण करने में विफलता का सामना करना पड़ा। क्लिपर में सरलीकरण संघनन का उपयोग करके किया जाता है। Wikipedia article साधारण बहुभुज या बहुभुजों को दो सरल बहुभुजों के भीतर क्षेत्र युक्त ढूंढने के रूप में संघटन निर्धारित करता है। एक ही लेख में कहा गया है कि सरल बहुभुज में "प्रत्येक चरम पर बिल्कुल दो किनारे मिलते हैं" और यह भी कमजोर सरल बहुभुज निर्धारित करता है, जहां किनारों को मिल सकता है, लेकिन किनारे के मामले के बारे में कुछ भी नहीं कहता है जहां किनारों को पूरा नहीं होता है, लेकिन कुछ या कई शिखर सम्मेलन मिलते हैं । तो यह थोड़ा अस्पष्ट है अगर यह मामला सरल बहुभुज या कमजोर सरल बहुभुज है।तीन.जेएस पॉलीगॉन त्रिभुज छद्म डुप्लिकेट अंक

क्लिपर ने अनुमोदित दृष्टिकोण का चयन किया है: सरल बहुभुज में इन्हें छूने (या छद्म डुप्लिकेट) कोने की तरह हो सकता है। This Clipper style permissive approach का कारण बनता है कि उत्पन्न सरल बहुभुज तीन.जेएस: triangulateShape() अपेक्षाओं के अर्थ में सरल नहीं हैं।

निम्न छवि इस किनारे के मामले के दो उदाहरण दिखाती है। बायां बहुभुज एक "सरल" बहुभुज है, लाल बिंदु एक "डुप्लिकेट" है। सही एक भी "सरल" बहुभुज है, लेकिन लाल बिंदु एक "डुप्लिकेट" है।

enter image description here

triangulateShape(), इन मामलों में विफल रहता है, क्योंकि यह वहाँ से सरणी allPointsMap में अंक और चेक का ट्रैक रखता है, तो बिंदु डुप्लिकेट है। इन का उपयोग कर अतिरिक्त पैरामीटर जैसे संभाल करने


OPTION 1.

बदलें जावास्क्रिप्ट क्लिपर आंतरिक कोड: इस तरह के डुप्लीकेट निकालने के लिए मैं दो विकल्प हैं। breakPolygonByWeakDuplicatesSimplifyPolygon() और SimplifyPolygons() के लिए। के रूप में एंगस जॉनसन in his post वर्णित है, परिवर्तन की तरह कुछ होगा:

IntersectEdges में() विधि, द्वारा बाद में बदल ...

 
if (e1Contributing && e2contributing) 
{ 
    if (e1stops || e2stops || 
    (e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) || 
    (e1->polyType != e2->polyType && m_ClipType != ctXor)) 
     AddLocalMaxPoly(e1, e2, pt); 
    else 
     DoBothEdges(e1, e2, pt); 
} 

करने के लिए ...

 

if (e1Contributing && e2contributing) 
{ 
    AddLocalMaxPoly(e1, e2, pt); 
    AddLocalMinPoly(e1, e2, pt); 
} 

परिवर्तन बहुत आसान है, लेकिन फिर मूल एंगस जॉनसन क्लिपर और जावास्क्रिप्ट क्लिपर अब और अधिक संगत नहीं होंगे। बेशक अगर मूल क्लिपर परिवर्तन करेगा, जावास्क्रिप्ट क्लिपर इसका पालन करेगा।


OPTION 2.

भी छद्म डुप्लिकेट को स्वीकार करने के Three.js triangulateShape() स्रोत कोड को बदलने के लिए।


मेरा प्रश्न है: जिसमें इस तरह अतिरिक्त सरलीकरण नियमित किया जाना चाहिए अंत? पहला अंत सृजन पक्ष (क्लिपर) है और दूसरा छोर त्रिभुज पक्ष (तीन.जेएस) है।

मुझे विभिन्न 3 डी पुस्तकालयों में बहुभुज त्रिभुज दिनचर्या नहीं पता है, इसलिए कल्पना नहीं कर सकता कि सामान्य रूप से अनुमत त्रिभुज दिनचर्या कैसे हैं। अगर कोई इस क्षेत्र को जानता है, तो वह अधिक परिष्कृत उत्तर दे सकता है।

इसके अलावा मुझे नहीं पता कि कैसे अन्य बुलियन पुस्तकालय छद्म डुप्लिकेट की तरह इसे संघनित या सरलीकृत करते हैं। निश्चित रूप से एक कारण है कि क्लिपर सरल बहुभुज (उदाहरण के लिए अन्य बूलियन पुस्तकालयों के साथ संगतता) के माध्यम से अनुमत है, लेकिन निश्चित रूप से यह तीन.जेएस में बहुभुज बहुभुज में समस्याएं पैदा करता है।

triangulateShape: function (contour, holes) { 

    var shapeWithoutHoles = THREE.Shape.Utils.removeHoles(contour, holes); 

    var shape = shapeWithoutHoles.shape, 
     allpoints = shapeWithoutHoles.allpoints, 
     isolatedPts = shapeWithoutHoles.isolatedPts; 

    var triangles = THREE.FontUtils.Triangulate(shape, false); // True returns indices for points of spooled shape 

    // To maintain reference to old shape, one must match coordinates, or offset the indices from original arrays. It's probably easier to do the first. 

    //console.log("triangles",triangles, triangles.length); 
    //console.log("allpoints",allpoints, allpoints.length); 

    var i, il, f, face, 
     key, index, 
     allPointsMap = {}, 
     isolatedPointsMap = {}; 

    // prepare all points map 

    for (i = 0, il = allpoints.length; i < il; i ++) { 

     key = allpoints[ i ].x + ":" + allpoints[ i ].y; 

     if (allPointsMap[ key ] !== undefined) { 

      console.log("Duplicate point", key); 

     } 

     allPointsMap[ key ] = i; 

    } 

    // check all face vertices against all points map 

    for (i = 0, il = triangles.length; i < il; i ++) { 

     face = triangles[ i ]; 

     for (f = 0; f < 3; f ++) { 

      key = face[ f ].x + ":" + face[ f ].y; 

      index = allPointsMap[ key ]; 

      if (index !== undefined) { 

       face[ f ] = index; 

      } 

     } 

    } 

    // check isolated points vertices against all points map 

    for (i = 0, il = isolatedPts.length; i < il; i ++) { 

     face = isolatedPts[ i ]; 

     for (f = 0; f < 3; f ++) { 

      key = face[ f ].x + ":" + face[ f ].y; 

      index = allPointsMap[ key ]; 

      if (index !== undefined) { 

       face[ f ] = index; 

      } 

     } 

    } 

    return triangles.concat(isolatedPts); 

}, // end triangulate shapes 

अद्यतन:

संदर्भ यहां Three.js की triangulating कोड है मैं एक एसवीजी http://jsbin.com/ugimab/1 जहां एक बहुभुज है कि बिंदु (150,150) का एक उदाहरण है जो एक कमजोर है बनाया डुप्लिकेट या छद्म डुप्लिकेट।

 
var weakDuplicate1 = [{"X":100,"Y":200},{"X":150,"Y":150},{"X":100,"Y":100},{"X":200,"Y":100},{"X":150,"Y":150},{"X":200,"Y":200}]; 

var weakDuplicate2 = [100,200, 150,150, 100,100, 200,100, 150,150, 200,200]; 

var weakDuplicate3 = "M100,200 L150,150 L100,100 L200,100 L150,150 L200,200Z"; 


अद्यतन: किसी भी बहुभुज जो इस अंक कमजोर नकल की तरह है triangulating के लिए एक समाधान खोजने के लिए प्रबंधित किया है तो यह होगा बहुत करता है, तो क्या तुम करोगी उपयोगी इस बहुभुज का प्रतिनिधित्व करने के लिए निम्न शो विभिन्न तरीकों अपने निष्कर्ष प्रकाशित करें।


अद्यतन: विकल्प 1 परीक्षण किया गया है, लेकिन यह सफल नहीं था: http://jsbin.com/owivew/1। बहुभुज एक टुकड़ा के रूप में बनी हुई है, हालांकि इसे दो भागों में थूक जाना चाहिए। शायद एंगस जॉनसन (क्लिपर के निर्माता) को प्रदान करने के लिए बेहतर समाधान है।


अद्यतन: यहाँ (क्लिपर में सरल बनाने के बाद) एक अधिक जटिल "सरल" बहुभुज है। सभी बिंदु जो एक साथ होने लगते हैं वे बिल्कुल समान हैं। इसे वास्तव में सरल बहुभुज में विभाजित करने के लिए, इसे टुकड़ों में विभाजित करने की आवश्यकता होगी। मेरी आंखें कहती हैं कि यहां 4 निचले बहुभुज हैं और एक (बड़ा) ऊपरी बहुभुज है जिसमें छेद है, इसलिए कुल सरलीकृत करने से यह 5 बाहरी बहुभुज और 1 छेद उत्पन्न करेगा। या वैकल्पिक रूप से एक बाहरी बहुभुज जिसमें 5 छेद हैं। या संभवतः आउटर्स और छेद के कुछ अन्य संयोजन। इसे कई अलग-अलग तरीकों से सरल बनाया जा सकता है।

फिडल http://jsbin.com/ugimab/3 (पॉलीगॉन का JSON- संस्करण) में है।

enter image description here

और यहाँ से 25 अंक 0 से गिने हैं:

enter image description here

छवि कोने 2,11,14,25 में एक ही समन्वय कर रहे हैं, इसलिए यह एक है " छद्म बहु-vertice "। Vertex3 डुप्लिकेट नहीं है, लेकिन यह किनारे 6-7 को छूता है।


अद्यतन:

The suggested method कि डुप्लिकेट अंक आगे बढ़ पर आधारित है काम करने के लिए लगता है। यदि डुप्लिकेट पॉइंट को दो बिंदुओं से प्रतिस्थापित किया जाता है जो डुप्लिकेट समन्वय की कुछ दूरी पर होते हैं, तो "टूटी कलम निब" प्रभाव उत्पन्न करते हैं, त्रिकोण कार्य करता है, क्योंकि उत्पादित बहुभुज तब वास्तविक सरल बहुभुज होते हैं, जो त्रिभुज की आवश्यकता होती है। इसके अलावा समोच्च और छेद के बीच डुप्लीकेट होने की अनुमति नहीं है और न ही छेद और छेद के बीच। निम्न छवि इस विधि का प्रभाव दिखाती है। प्रभाव दिखाने के लिए दूरी 10px है, लेकिन वास्तव में उदाहरण के लिए। 0.001 बहुभुज सरल बनाने के लिए पर्याप्त है। थ्री.जेएस आर 58 में भी डिफ़ॉल्ट त्रिभुज अपेक्षित काम नहीं कर रहा है, लेकिन अगर इसे पॉली 2tri में बदल दिया गया है, तो सब ठीक है। इस लंबी प्रक्रिया की प्रक्रिया में प्रक्रिया का वर्णन किया गया है: https://github.com/mrdoob/three.js/issues/3386

enter image description here

+0

क्या आप अपनी स्रोत जेसन फ़ाइल को अंक के साथ साझा कर सकते हैं। आप इसका जिक्र कर रहे हैं लेकिन लिंक गायब प्रतीत होता है। – Wilt

+0

[{"एक्स": 270, "वाई": 520}, {"एक्स": 130, "वाई": 4 9 0}, {"एक्स": 210, "वाई": 250}, {"एक्स": 60 "Y": 170}, { "एक्स": 130 "Y": 490}, { "एक्स": 20, "Y": 410}, { "एक्स": 60, "Y": 300}, { "एक्स": 60, "Y": 20}, { "एक्स": 780 "Y": 40}, { "एक्स": 680 "Y": 180}, { "एक्स": 460, " Y ": 130}, {" एक्स ": 210" Y ": 250}, {" एक्स ": 320" Y ": 100}, {" एक्स ": 220" Y ": 80}, {" एक्स ": 210" Y ": 250}, {" एक्स ": 520" Y ": 250}, {" एक्स ": 680" Y ": 180}, {" एक्स ": 770" Y " : 480}, { "एक्स": 540 "Y": 470}, { "एक्स": 520 "Y": 250}, { "एक्स": 380 "Y": 280}, { "एक्स" : 430, "Y": 390}, { "एक्स": 540 "Y": 470}, { "एक्स": 270 "Y": 520}, { "एक्स": 330 "Y": 350 }, {"एक्स": 210, "वाई": 250}] –

उत्तर

3

आप एक समारोह है कि डुप्लिकेट कोने का पता लगाता है और उन्हें पिछड़े चाल 1px उन्हें असतत बनाने के लिए (वे कोई और अधिक एक आम किनारे का हिस्सा) लिख सकते हैं। इस तरह कोई और सामान्य किनार नहीं होंगे और कोई त्रुटि उत्पन्न नहीं होगी लेकिन दृश्य परिणाम अभी भी वही दिखता है।

कच्चे समाधान की तरह लेकिन यह काम कर सकता है।

+1

उत्तर के लिए धन्यवाद! यह समाधान वास्तव में अच्छा लगता है। क्या आपका पिछला वर्टिस की ओर पिछड़ा = मतलब है? –

+0

हां बिल्कुल यह कहने के लिए मेरी माफ़ी नहीं है। –

+1

यह समाधान बहुत अच्छा काम करता प्रतीत होता है, अगर डुप्लिकेट के अगले किनारे पर अतिरिक्त वर्टेक्स भी जोड़ा जाता है, तो वहां एक छोटी "टूटी कलम टिप" प्रभाव होता है, जो असली दुनिया में अदृश्य है। किसी भी आत्म-चौराहे के कारण नहीं। लेकिन मुझे वास्तव में जटिल बहुभुजों के साथ भी परीक्षण करना है, इससे पहले कि यह सुनिश्चित हो सके कि यह विधि वास्तव में त्रिभुज से पहले एक पूर्व-चरण के रूप में काम करती है। –

0

three.js में उपयोग किए गए त्रिभुज समाधान के साथ कई मुद्दे हैं। कई अन्य जावास्क्रिप्ट त्रिभुज पुस्तकालय उपलब्ध हैं और यह बहुत अच्छी तरह से हो सकता है कि भविष्य में वर्तमान पुस्तकालय का कुछ और उदाहरण के लिए आदान-प्रदान किया जाएगा उदाहरण के लिए earcut.js। इस here in this issue on GitHub के बारे में एक चर्चा है।

स्वयं छेड़छाड़ करने वाले किनारों का आपका मुद्दा कान के लिए कोई समस्या नहीं है जैसा कि in this multi viewer here प्रदर्शित किया गया है।


आप पहले से ही अपनी परियोजना में एक अलग ट्राईऐन्ग्युलेशंस समाधान का उपयोग करने मैं होगा एक three.js triangulation library (an adapter) मैंने बनाया का उल्लेख करना चाहते हैं। earcut ट्राईऐन्ग्युलेशंस पुस्तकालय

  • poly2tri - - poly2tri ट्राईऐन्ग्युलेशंस पुस्तकालय
  • libtess - libtess चौकोर पुस्तकालय
  • सभी

    • earcut: अनुकूलक अपने Three.js परियोजना के लिए तीन अन्य ट्राईऐन्ग्युलेशंस पुस्तकालयों मूल जोड़ने की अनुमति देता है आपको triangulation.js फ़ाइल शामिल करने की आवश्यकता है:

      <script src="triangulation.js"></script> 
      

      और setLibrary पद्धति का उपयोग करके अपने चयन के पुस्तकालय की स्थापना की:

      THREE.Triangulation.setLibrary('earcut'); 
      

      पुस्तकालय आप चुनते हैं आप पुस्तकालय खुद के लिए फ़ाइलों का एम्बेड करने के लिए की जरूरत स्पष्ट रूप से होगा पर निर्भर करता है। वर्तमान में libtess के लिए अतिरिक्त tessy.js आवश्यक है जो भंडार में पाया जा सकता है।

      परियोजना here on GitHub के बारे में और पढ़ें।