2012-08-13 13 views
9

मैं एक जावास्क्रिप्ट कैनवास का उपयोग कर एक प्रोजेक्ट पर काम कर रहा हूं और एक बहुभुज से एक निश्चित दूरी पर कर्सर को स्नैप करने में सक्षम होना चाहिए। मैं पहले से ही बहुभुज के लिए तस्वीर ले सकता हूं, लेकिन मुझे कर्सर को दूर से दूर करने की आवश्यकता है।एक बहुभुज स्केल करें ताकि किनारों का मिलान

जहां तक ​​मैं इस बारे में जाने का सबसे अच्छा तरीका बता सकता हूं, पॉलीगॉन को स्केल करना और उस पर स्नैप करना है, लेकिन जब मैं बहुभुज को पुराने बहुभुज के किनारों और नए बहुभुज के किनारों के बीच की दूरी को स्केल करता हूं हमेशा मेल नहीं खाते।

यहाँ समस्या का एक उदाहरण है:

enter image description here enter image description here

संपादित करें: ग्रे मूल बहुभुज का प्रतिनिधित्व करता है, लाल अगर मैं बहुभुज सामान्य रूप से बड़े पैमाने मैं क्या मिल रहा है, और है हरा वह है जो मैं

को पूरा करने की कोशिश कर रहा हूं, मैंने पहले से ही बहुभुज को मूल रूप से अनुवाद करने और स्केल फैक्टर द्वारा गुणा करने का प्रयास किया है, लेकिन प्रत्येक किनारे को एक विशिष्ट दूरी से स्केल नहीं कर सकता।

+0

कृपया अपने चित्र है, जो हिस्सों को हल कर लाल और हरे रंग का प्रतिनिधित्व समझाने? – Hogan

+0

धन्यवाद। संपादित। – davey555

+0

क्या आप पॉलीगॉन, अनुवाद और स्केलिंग के लिए उपयोग किए गए कोड को पोस्ट कर सकते हैं? और "हमेशा मेल न करें" से आपका क्या मतलब है? किस स्थिति में यह असफल हो जाता है? –

उत्तर

1

मैं एक समाधान JSTS पुस्तकालय (JTS की जावास्क्रिप्ट बंदरगाह) का उपयोग कर सकते हैं। पुस्तकालय में बहुभुज के फुफ्फुस/अपमान (ऑफसेटिंग) के तरीकों हैं।

यदि आप विभिन्न प्रकार के किनारों के साथ बढ़ते बहुभुज को प्राप्त करना चाहते हैं तो आप टोपी सेट कर सकते हैं और शैली में शामिल हो सकते हैं।

function inflatePolygon(poly, spacing) { 
    var geoInput = vectorCoordinates2JTS(poly); 
    geoInput.push(geoInput[0]); 

    var geometryFactory = new jsts.geom.GeometryFactory(); 

    var shell = geometryFactory.createPolygon(geoInput); 
    var polygon = shell.buffer(spacing); 
    //try with different cap style 
    //var polygon = shell.buffer(spacing, jsts.operation.buffer.BufferParameters.CAP_FLAT); 

    var inflatedCoordinates = []; 
    var oCoordinates; 
    oCoordinates = polygon.shell.points.coordinates; 

    for (i = 0; i < oCoordinates.length; i++) { 
    var oItem; 
    oItem = oCoordinates[i]; 
    inflatedCoordinates.push(new Vector2(Math.ceil(oItem.x), Math.ceil(oItem.y))); 
    } 
    return inflatedCoordinates; 
} 

:

function vectorCoordinates2JTS (polygon) { var coordinates = []; for (var i = 0; i < polygon.length; i++) { coordinates.push(new jsts.geom.Coordinate(polygon[i].x, polygon[i].y)); } return coordinates; }

एक बार जब आप निर्देशांक परिवर्तित कर दिया है आप अपने बहुभुज बढ़ सकता है: केवल एक चीज आपको क्या करना है आप बहुभुज एक JSTS को निर्देशांक परिवर्तित समन्वय है जो वास्तव में सरल है करने के लिए है

enter image description here

: कोड के साथ मैं jsFiddle पर पोस्ट किया है आप कुछ इस तरह मिल जाएगा

अतिरिक्त जानकारी: मैं आमतौर पर मानचित्र पर खींचे गए पॉलीगॉन पर त्रिज्या के साथ सीमाओं को निर्धारित करने के लिए इस प्रकार के inflating/deflating (थोड़ा बदल गया) का उपयोग करता हूं (पत्रक या Google मानचित्र के साथ)। आप सिर्फ लैट, एलएनजी जोड़े को जेएसटीएस निर्देशांक में परिवर्तित करते हैं और बाकी सब कुछ वही है। उदाहरण:

enter image description here

+0

वाह यह अच्छा है, मेरी इच्छा है कि मेरे पास यह 3 साल पहले था ... – davey555

2

बहुभुज और कर्सर बिंदु के हर किनारे के बीच की दूरी को खोजने का एक तरीका है, और सबसे छोटा रखें।

एक बिंदु और रेखा खंड के बीच की दूरी की गणना करने के लिए, बिंदु को सहायक लाइन पर प्रोजेक्ट करें; यदि प्रक्षेपण अंतराल के बीच आता है, तो समाधान बिंदु-से-रेखा दूरी है; अन्यथा, समाधान निकटतम अंतराल की दूरी है।

यह आसानी से वेक्टर कैलकुस का उपयोग करके गणना की जाती है।

3

ISTM कि आप जो भी कर रहे हैं वह बहुभुज ऑफसेटिंग एल्गोरिदम या लाइब्रेरी है।
An algorithm for inflating/deflating (offsetting, buffering) polygons

+0

जावास्क्रिप्ट में बहुभुज ऑफसेट करने के लिए कोई विचार? –

+1

जावा लाइब्रेरी जेटीएस (जावा टोपोलॉजी सूट) ऑफ़सेट कर रहा है (हालांकि इसे वहां बफरिंग कहा जाता है)। Https://sourceforge.net/projects/jts-topo-suite/ –

+0

यह जावा है, जावास्क्रिप्ट नहीं और पोर्टिंग प्रक्रिया की भी आवश्यकता है। यह क्लिपर से तुलना कैसे करता है? –

5

मैं एक jsFiddle कि किसी दिए गए बहुभुज के लिए, एक बाहरी पॉलीगॉन कि मुझे आशा है कि आपकी आवश्यकता को पूरा करती गणना करता बनाया देखें। मैंने इस pdf document में गणित को इसके पीछे रखा है।

अद्यतन: लंबवत रेखाओं से निपटने के लिए कोड बनाया गया है।

function Vector2(x, y) 
{ 
    this.x = x; 
    this.y = y; 
} 

function straight_skeleton(poly, spacing) 
{ 
    // http://stackoverflow.com/a/11970006/796832 
    // Accompanying Fiddle: http://jsfiddle.net/vqKvM/35/ 

    var resulting_path = []; 
    var N = poly.length; 
    var mi, mi1, li, li1, ri, ri1, si, si1, Xi1, Yi1; 
    for(var i = 0; i < N; i++) 
    { 
     mi = (poly[(i+1) % N].y - poly[i].y)/(poly[(i+1) % N].x - poly[i].x); 
     mi1 = (poly[(i+2) % N].y - poly[(i+1) % N].y)/(poly[(i+2) % N].x - poly[(i+1) % N].x); 
     li = Math.sqrt((poly[(i+1) % N].x - poly[i].x)*(poly[(i+1) % N].x - poly[i].x)+(poly[(i+1) % N].y - poly[i].y)*(poly[(i+1) % N].y - poly[i].y)); 
     li1 = Math.sqrt((poly[(i+2) % N].x - poly[(i+1) % N].x)*(poly[(i+2) % N].x - poly[(i+1) % N].x)+(poly[(i+2) % N].y - poly[(i+1) % N].y)*(poly[(i+2) % N].y - poly[(i+1) % N].y)); 
     ri = poly[i].x+spacing*(poly[(i+1) % N].y - poly[i].y)/li; 
     ri1 = poly[(i+1) % N].x+spacing*(poly[(i+2) % N].y - poly[(i+1) % N].y)/li1; 
     si = poly[i].y-spacing*(poly[(i+1) % N].x - poly[i].x)/li; 
     si1 = poly[(i+1) % N].y-spacing*(poly[(i+2) % N].x - poly[(i+1) % N].x)/li1; 
     Xi1 = (mi1*ri1-mi*ri+si-si1)/(mi1-mi); 
     Yi1 = (mi*mi1*(ri1-ri)+mi1*si-mi*si1)/(mi1-mi); 
     // Correction for vertical lines 
     if(poly[(i+1) % N].x - poly[i % N].x==0) 
     { 
      Xi1 = poly[(i+1) % N].x + spacing*(poly[(i+1) % N].y - poly[i % N].y)/Math.abs(poly[(i+1) % N].y - poly[i % N].y); 
      Yi1 = mi1*Xi1 - mi1*ri1 + si1; 
     } 
     if(poly[(i+2) % N].x - poly[(i+1) % N].x==0) 
     { 
      Xi1 = poly[(i+2) % N].x + spacing*(poly[(i+2) % N].y - poly[(i+1) % N].y)/Math.abs(poly[(i+2) % N].y - poly[(i+1) % N].y); 
      Yi1 = mi*Xi1 - mi*ri + si; 
     } 

     //console.log("mi:", mi, "mi1:", mi1, "li:", li, "li1:", li1); 
     //console.log("ri:", ri, "ri1:", ri1, "si:", si, "si1:", si1, "Xi1:", Xi1, "Yi1:", Yi1); 

     resulting_path.push({ 
      x: Xi1, 
      y: Yi1 
     }); 
    } 

    return resulting_path; 
} 


var canvas = document.getElementById("Canvas"); 
var ctx = canvas.getContext("2d"); 

var poly = [ 
    new Vector2(150, 170), 
    new Vector2(400, 120), 
    new Vector2(200, 270), 
    new Vector2(350, 400), 
    new Vector2(210, 470) 
]; 

draw(poly); 
draw(straight_skeleton(poly, 10)); 

function draw(p) { 
    ctx.beginPath(); 
    ctx.moveTo(p[0].x, p[0].y); 
    for(var i = 1; i < p.length; i++) 
    { 
     ctx.lineTo(p[i].x, p[i].y); 
    } 
    ctx.strokeStyle = "#000000"; 
    ctx.closePath(); 
    ctx.stroke(); 
} 

पॉलीगॉन बिंदु वस्तुओं की एक सरणी में डाल दिया जाता है।

फ़ंक्शन draw(p) कैनवास पर बहुभुज p खींचता है।

दिए गए बहुभुज सरणी पॉली में है, सरणी पॉली में बाहरी।

spacing


बहुभुज के बीच की दूरी (अपने हरे रंग के चित्र में तीर के साथ के रूप में) एंगस जॉनसन टिप्पणी के बाद है, मैं कुछ और fiddles मुद्दों वह उठाती है दिखाने के लिए उत्पादन किया है। मैंने पहली बार सोचा था कि यह समस्या बहुत मुश्किल समस्या है।

+1

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

+0

@ एंगस जॉनसन मैंने अभी आपके द्वारा निर्दिष्ट शर्तों के साथ प्रयास किया है और मैं देखता हूं कि आपका क्या मतलब है। इस पर ध्यान दिलाने के लिए धन्यवाद। मैं इसे और अधिक सोचा दूंगा। शायद डेवी 555 इस बात पर टिप्पणी करेगा कि क्या उनके परिस्थितियों में ये शर्तें उत्पन्न हो सकती हैं। – jing3142

6

मैं क्लिपर के एक जावास्क्रिप्ट बंदरगाह बनाया और इसके साथ आप जिस तरह से आप चाहते हैं में स्केलिंग कर सकते हैं।

enter image description here

जावास्क्रिप्ट क्लिपर के LIVE DEMO की जाँच करें:

यह बढ़ा-चढ़ाकर बहुभुज का एक उदाहरण है।

और https://sourceforge.net/projects/jsclipper/ से clipper.js फ़ाइल प्राप्त करें।

Full code example पॉलीगन्स को ऑफ़सेट करने और उन्हें HTML5 कैनवास पर कैसे आकर्षित करें।

विपरीत (deflating) भी संभव अगर जरूरत है,:

Offsetting polygons

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