मैं एचटीएमएल 5 कैनवास (गौरवशाली कुछ भी नहीं, एक पहेली के साथ एक प्रयोग परियोजना के हिस्से के रूप में आसन्न बहुभुज मर्ज करने के लिए एक एल्गोरिथ्म लिखना पड़ा मिलना चाहिए :-) परिणामी बहुभुज में छेद स्वाभाविक रूप से समर्थित हैं। जावास्क्रिप्ट दिनचर्या www dot raymondhill dot net/puzzle-rhill/jigsawpuzzle-rhill-3 dot js
में डुप्लिकेट सेगमेंट को हटाने की कुंजी है, लेकिन पॉलीगॉन.प्रोटोटाइप.मेरगे() नामक फ़ंक्शन में पाया जाता है। उल्टी दिशा। असहज स्पष्टीकरण: एक बिंदु {x:?, Y :?} है, एक सेगमेंट {ptA:?, PtB :?} है, एक कंटूर {pts: []} (कनेक्टेड पॉइंट ऑब्जेक्ट्स का संग्रह) है, पॉलीगॉन है {contours: []} (कंटूर वस्तुओं का संग्रह।)
मर्ज एल्गोरिथ्म सेगमेंट वस्तुओं, जहां डुप्लिकेट समाप्त हो जाते का एक बड़ा वसा पूल में सभी क्षेत्रों इकट्ठा। सबसे पहले, पॉलीगॉन ए को परिभाषित करने वाले सभी रूपों के सभी खंड पूल में जोड़े गए हैं। फिर, सभी बहुभुज बी को परिभाषित सभी आकृति के क्षेत्रों पूल में जुड़ जाते हैं, लेकिन हम परीक्षण करने और डुप्लिकेट के लिए निकाल सकते हैं (आसानी से एक hashkey के रूप में एक प्वाइंट वस्तु का उपयोग किया)।
तो हम पूल (बेतरतीब ढंग से ठीक है) से एक सेगमेंट लेते हैं, और हम "चलना" यह जब तक हम एक "एकतरफ़ा", कि, कोई और अधिक खंड जोड़ा जा सकता है तक पहुँचने। यह एक कंटूर ऑब्जेक्ट बनाता है। जब तक सेगमेंट के पूरे संग्रह का उपयोग नहीं किया जाता है तब तक हम दोहराते हैं। चूंकि सेगमेंट का उपयोग किया जाता है, उन्हें पूल से निकाल दिया जाता है। एक खंड "चलना" का अर्थ है कि हम अपना अंत बिंदु लेते हैं, और हम एक सेगमेंट देखते हैं जो बिंदु से मेल खाता है।
के रूप में कहा, परिणामस्वरूप हम कंटूर वस्तुओं जो बहुभुज को परिभाषित का एक संग्रह है। कुछ रूपों को भर दिया जाएगा, कुछ खोखले हो सकते हैं। निर्धारित करने के लिए एक कंटूर भर जाता है या खोखले परीक्षण का मामला है कि क्या कंटूर दक्षिणावर्त या वामावर्त, या अपने क्षेत्र सकारात्मक है या नकारात्मक है है या नहीं। यह एक सम्मेलन है, मेरे मामले में दक्षिणावर्त आकृति भर रहे हैं, वामावर्त खोखला कर रहे हैं।
यहाँ मेरी कार्यान्वयन है, शून्य से बारीकियों और शून्य से त्रुटि हैंडलिंग। उम्मीद है कि मैं कॉपी किया/पर्याप्त आप अभी किसी और काम करते हैं, संदर्भ के लिए ऊपर मेरी जे एस फ़ाइल को संदर्भित करने के लिए चिपकाया:
// Point object
function Point(a,b) {
// a=x,b=y
if (b) {
this.x=a;
this.y=b;
}
// a=Point or {x:?,y:?}
else if (a) {
this.x=a.x;
this.y=a.y;
}
// empty
else {
this.x=this.y=0;
}
}
Point.prototype.toHashkey = function() {
return this.x+"_"+this.y;
};
Point.prototype.clone = function() {
return new Point(this);
};
// Segment object
function Segment(a,b) {
this.ptA = new Point(a);
this.ptB = new Point(b);
}
// Contour object
function Contour(a) {
this.pts = []; // no points
if (a) {
if (a instanceof Array) { // assume array of Point objects
var nPts = a.length;
for (var iPt=0; iPt<nPts; iPt++) {
this.pts.push(a[iPt].clone());
}
}
}
}
Contour.prototype.clone = function() {
return new Contour(this);
};
Contour.prototype.addPoint = function(p) {
this.pts.push(p);
};
// Polygon object
function Polygon(a) {
this.contours = []; // no contour
if (a) {
if (a instanceof Polygon) {
var contours = a.contours;
var nContours = contours.length;
for (var iContour=0; iContour<nContours; iContour++) {
this.contours.push(new Contour(contours[iContour]));
}
}
else if (a instanceof Array) {
this.contours.push(new Contour(a));
}
}
}
Polygon.prototype.merge = function(other) {
// A Javascript object can be used as an associative array, but
// they are not real associative array, as there is no way
// to query the number of entries in the object. For this
// reason, we maintain an element counter ourself.
var segments={};
var contours=this.contours;
var nContours=contours.length;
var pts; var nPts;
var iPtA; var iPtB;
var idA; var idB;
for (var iContour=0; iContour<nContours; iContour++) {
pts = contours[iContour].pts;
nPts = pts.length;
iPtA = nPts-1;
for (iPtB=0; iPtB<nPts; iPtA=iPtB++) {
idA = pts[iPtA].toHashkey();
idB = pts[iPtB].toHashkey();
if (!segments[idA]) {
segments[idA]={n:0,pts:{}};
}
segments[idA].pts[idB] = new Segment(pts[iPtA],pts[iPtB]);
segments[idA].n++;
}
}
// enumerate segments in other's contours, eliminate duplicate
contours = other.contours;
nContours = contours.length;
for (iContour=0; iContour<nContours; iContour++) {
pts = contours[iContour].pts;
nPts = pts.length;
iPtA=nPts-1;
for (iPtB=0; iPtB<nPts; iPtA=iPtB++) {
idA = pts[iPtA].toHashkey();
idB = pts[iPtB].toHashkey();
// duplicate (we eliminate same segment in reverse direction)
if (segments[idB] && segments[idB].pts[idA]) {
delete segments[idB].pts[idA];
if (!--segments[idB].n) {
delete segments[idB];
}
}
// not a duplicate
else {
if (!segments[idA]) {
segments[idA]={n:0,pts:{}};
}
segments[idA].pts[idB] = new Segment(pts[iPtA],pts[iPtB]);
segments[idA].n++;
}
}
}
// recreate and store new contours by jumping from one point to the next,
// using the second point of the segment as hash key for next segment
this.contours=[]; // regenerate new contours
var contour;
for (idA in segments) { // we need this to get a starting point for a new contour
contour = new Contour();
this.contours.push(contour);
for (idB in segments[idA].pts) {break;}
segment = segments[idA].pts[idB];
while (segment) {
contour.addPoint(new Point(segment.ptA));
// remove from collection since it has now been used
delete segments[idA].pts[idB];
if (!--segments[idA].n) {
delete segments[idA];
}
idA = segment.ptB.toHashkey();
if (segments[idA]) {
for (idB in segments[idA].pts) {break;} // any end point will do
segment = segments[idA].pts[idB];
}
else {
segment = null;
}
}
}
};
जब हम "सैर" एक समोच्च बनाने के लिए खंड, वहाँ एक मामला है, जहां एक
+------+-------+
| Poly A | two segments sharing same start point Z
| |
+ +---<---Z---->---+
| | | Poly B |
| | | |
+ +-------+--------+
| |
| |
+------+-------+--------+
कौन सा करने के लिए दो वैध परिणाम नेतृत्व कर सकते हैं (कलन विधि ऊपर एक या अन्य करने के लिए बेतरतीब ढंग से नेतृत्व करेंगे):
परिणाम 1, एक भरा समोच्च: खंड एक से अधिक खंड से कनेक्ट कर सकते
+------+--->---+
| Poly A |
| |
+ +---<---+---->---+
| | | |
| | | |
+ +--->---+ +
| |
| |
+------+---<---+--------+
परिणाम 2, एक भरा समोच्च, एक खोखला समोच्च:
+------+--->---+
| Poly A |
| |
+ +---<---+---->---+
| | Hole A| |
| | | |
+ +--->---+ +
| |
| |
+------+---<---+--------+
यह एक समस्या है, हालांकि नहीं होना चाहिए, के रूप में अपने कोड पहले से ही छेद को संभालने के लिए तैयार रहना चाहिए।
अन्य महत्वपूर्ण विस्तार: उपरोक्त एल्गोरिथ्म, मध्यवर्ती अंक ('+') से छुटकारा नहीं है मिल वास्तव में वे उम्मीद कर रहे हैं या फिर एल्गोरिथ्म काम नहीं करेगा, निम्नलिखित मामले में:
+------>-------+
| Poly A |
| |
| | +---->---+
| | | Poly B |
| | | |
| | +----<---+
| |
| |
+------<-------+
मेरी समझ यह है कि यह आपके पास है। मुझे लगता है एल्गोरिथ्म खोजने और पहले से अन्तर्विभाजक अंक जोड़कर इस तरह के मामले का समर्थन करने के लिए बढ़ाया जा सकता है (यह मेरे मामले में अनावश्यक था):
+------>-------+
| Poly A |
| |
| + +---->---+
| | | Poly B |
| | | |
| + +----<---+
| |
| |
+------<-------+
आशा इस मदद करते हैं।
पी.एस .: आप कर सकते हैं 'परीक्षण' पहेली के साथ एल्गोरिथ्म, टुकड़ों को एक साथ तड़क छेद उत्पन्न करने के लिए, आदि .: http://www.raymondhill.net/puzzle-rhill/puzzle-rhill.php?puzzlePieces=16&puzzleComplexity=1&puzzleURL=http://www.public-domain-photos.com/free-stock-photos-4/travel/los-angeles/los-angeles-skyline.jpg&puzzleRotate=0&puzzleVersion=3
प्रोग्रामिंग भाषा? –
आसन्न आयताकारों के किसी भी ब्लॉब का परिधि बहुभुज बनाता है। क्या आपका प्रश्न है "मैं लाइन सेगमेंट कैसे सूचीबद्ध करूं जो कनेक्टेड आयत के सेट के परिधि को परिभाषित करता है?" या कुछ और? – mbeckish
जब आप कहते हैं "कई एक दूसरे के समीप हैं", इसका क्या अर्थ है? क्या वे सिर्फ किनारों पर छूते हैं, या आयत को ओवरलैप कर सकते हैं? आयत किसी प्रकार के ग्रिड पर हैं, या उनके शिखर कहीं भी हो सकते हैं? –