2013-10-05 12 views
6

मैं अपने svg मजबूर लेआउट (d3js) में टकराव का पता लगाने की कोशिश कर रहा हूं। मैंने this ट्यूटोरियल का पालन किया है जो एक सर्कल आकार टकराव बनाता है।rect टक्कर पहचान d3js

कुछ कारणों से यह रेक्ट आकार के लिए काम नहीं कर रहा है। मैंने एक पर्दे में पैरामीटर के साथ खेलने की कोशिश की है।

function collide(node) { 
    var r = 30, 
     nx1 = node.x - r, 
     nx2 = node.x + r, 
     ny1 = node.y - r, 
     ny2 = node.y + r; 

    return function(quad, x1, y1, x2, y2) 
    { 
     if (quad.point && (quad.point !== node)) 
     { 
      var x = node.x - quad.point.x, 
       y = node.y - quad.point.y, 
       l = Math.sqrt(x * x + y * y), 
       r = 30 + quad.point.radius; 
      if (l < r) 
      { 
       l = (l - r)/l * .5; 
       node.x -= x *= l; 
       node.y -= y *= l; 
       quad.point.x += x; 
       quad.point.y += y; 
      } 
     } 

     return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; 
    }; 
} 

मैं रेक्ट के लिए टक्कर कैसे पता लगा सकते हैं:

var node = svg.selectAll(".node") 
    .data(json.nodes) 
     .enter().append("g") 
     .attr("class", "node") 
     .call(force.drag); 

    node 
     .append("rect") 
      .attr("class", "tagHolder") 
      .attr("width", 60) 
      .attr("height", 60) 
      .attr("rx", 5) 
      .attr("ry", 5) 
      .attr("x", -10) 
      .attr("y", -10); 

और इस:

svg.selectAll(".node") 
     .attr("x", function(d) { return d.x; }) 
     .attr("y", function(d) { return d.y; }); 

    link.attr("x1", function(d) 
     { 
      return d.source.x; 
     }) 
      .attr("y1", function(d) { return d.source.y; }) 
      .attr("x2", function(d) { return d.target.x; }) 
      .attr("y2", function(d) { return d.target.y; }); 

    node.attr("transform", function(d) 
    { 
     return "translate(" + d.x + "," + d.y + ")"; 
    }); 
}); 

और टक्कर समारोह

यहाँ मेरी कोड है?

धन्यवाद !!!

+0

मेरे पास एक ही प्रश्न है, हालांकि शायद आपके उदाहरण के साथ थोड़ा और आगे। कोलाइड फ़ंक्शन में किए गए परिवर्तनों के साथ कुछ सही नहीं है, 'क्योंकि मुझे आयताकारों के बीच बहुत अधिक प्रतिकृति मिल रही है: http://bl.ocks.org/dobbs/1d353282475013f5c156 –

उत्तर

9

डी 3 उदाहरण में टक्कर समारोह उनके रेडियो के बीच की दूरी की तुलना करके सर्कल के ओवरलैप की गणना करता है, जो उनके त्रिज्या r = node.radius + quad.point.radius के योग के साथ होता है। जब l < r मंडल ओवरलैप होते हैं और ओवरलैप को सही करने के लिए दोनों मंडल एक-दूसरे से दूर हो जाते हैं।

आयतों के लिए इसी तरह की टक्कर समारोह उसी तरह से काम करता है, आयतों के ओवरलैप कंप्यूटिंग और अन्य से प्रत्येक दूर ले जाकर:

function collide(node) { 
    var nx1, nx2, ny1, ny2, padding; 
    padding = 32; 
    nx1 = node.x - padding; 
    nx2 = node.x2 + padding; 
    ny1 = node.y - padding; 
    ny2 = node.y2 + padding; 
    return function(quad, x1, y1, x2, y2) { 
    var dx, dy; 
    if (quad.point && (quad.point !== node)) { 
     if (overlap(node, quad.point)) { 
     dx = Math.min(node.x2 - quad.point.x, quad.point.x2 - node.x)/2; 
     node.x -= dx; 
     quad.point.x += dx; 
     dy = Math.min(node.y2 - quad.point.y, quad.point.y2 - node.y)/2; 
     node.y -= dy; 
     quad.point.y += dy; 
     } 
    } 
    return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; 
    }; 
}; 

चौड़ाई में ओवरलैप dx = Math.min(node.x2 - quad.point.x, quad.point.x2 - node.x)/2; है जहां ऊंचाई में ओवरलैप dy = Math.min(node.y2 - quad.point.y, quad.point.y2 - node.y)/2; है जो दिखाता है कि आपके नोड्स को रेक्ट के दो कोनों को जानना चाहिए: शीर्ष बाएं (x, y) और नीचे दाएं (x2, y2)

यहां एक पूरा उदाहरण देखें: http://bl.ocks.org/dobbs/1d353282475013f5c156। उदाहरण कॉफ़ीस्क्रिप्ट का उपयोग करता है, और केवल y-axis 'cos के साथ एक दूसरे से दूर की ओर जाता है जो मेरे अपने मामले के लिए आवश्यक चीज़ों से बेहतर मेल खाता है।

+0

बकाया, बहुत बहुत धन्यवाद। मैं इस तरह कुछ ढूंढ रहा था। – damianmr

संबंधित मुद्दे