समस्या यह देखने के लिए है कि उनके दृश्य रिज़ॉल्यूशन को बढ़ाने के लिए आर्क्स को कितना मोड़ना है।
यहाँ एक समाधान है (कई संभव के बीच)। आइए एक सामान्य उत्पत्ति से निकलने वाले सभी चापों पर विचार करें। यहां चापलूसों की सबसे अधिक भीड़ होती है। उन्हें सबसे अच्छा अलग करने के लिए, आइए इसे व्यवस्थित करें ताकि वे समान रूप से फैलाए गए कोणों में फैल जाएं । यदि हम मूल से गंतव्य तक सीधी रेखा के खंड खींचते हैं तो यह एक समस्या है, क्योंकि आमतौर पर विभिन्न दिशाओं में गंतव्य के समूह होते हैं। आइए हमारी स्वतंत्रता का उपयोग करें कि जहाँ तक संभव हो सके प्रस्थान कोणों को रखने के लिए चाप को मोड़ें।
सरलता के लिए, हम मानचित्र पर परिपत्र आर्क्स का उपयोग करते हैं। "मोड़" बिंदु से एक चाप में का एक प्राकृतिक उपाय y बात करने के लिए एक्स पर अपने असर के बीच अंतर है y और सीधे से असर y के लिए एक्स । ऐसा चाप एक वृत्त का एक क्षेत्र है जिस पर y और x दोनों झूठ बोलते हैं; प्राथमिक ज्यामिति से पता चलता है कि झुकने वाला कोण चाप में शामिल आधे कोण के बराबर है ।
एक एल्गोरिथ्म का वर्णन करने के लिए हमें थोड़ा अधिक अंकन की आवश्यकता है। चलो y उद्गम स्थल हो (रूप में नक्शे पर अनुमान) और जाने x_1 , x_2 , ..., x_n गंतव्य अंक हो। परिभाषित करें a_i को y से x_i , i = 1, 2, ..., n तक वहन करें ।
प्रारंभिक चरण के रूप में, मान लें कि बीयरिंग (सभी 0 और 360 डिग्री के बीच) आरोही क्रम में हैं: इसके लिए हमें बीयरिंगों की गणना करने और फिर उन्हें क्रमबद्ध करने की आवश्यकता होती है; दोनों सीधे कार्य हैं।
आदर्श रूप से, हम कुछ शुरुआती असर के सापेक्ष आर्क्स के बीयरिंग को 360 / n , 2 * 360 / n आदि के बराबर करना चाहेंगे । वांछित बीयरिंग और वास्तविक बीयरिंग के बीच मतभेद इसलिए बराबर मैं * 360 / n a_i प्लस शुरू करने असर, - a0 । सबसे बड़ा अंतर इन एन मतभेदों की अधिकतम है और सबसे छोटा अंतर उनकी न्यूनतम है। आइए अधिकतम और मिनट के बीच आधा होने के लिए a0 सेट करें ; यह शुरुआती असर के लिए एक अच्छा उम्मीदवार है क्योंकि यह झुकने की अधिकतम मात्रा को कम करता है जो घटित होगा । नतीजतन, परिभाषित करें
b_i = i * 360 / n - a0 - a_i:
यह उपयोग करने के लिए झुकने है ।
यह प्राथमिक ज्यामिति की बात है कि y से x तक एक गोलाकार चाप खींचना है जो 2 b_i के कोण को घटाता है, इसलिए मैं विवरणों को छोड़ दूंगा और सीधे एक उदाहरण पर जाऊंगा। 64, 16, और 4 यादृच्छिक बिंदुओं के लिए आयताकार मानचित्र के भीतर दिए गए समाधानों के चित्र यहां दिए गए हैं
जैसा कि आप देख सकते हैं, समाधान अच्छे लगते हैं क्योंकि गंतव्य बिंदुओं की संख्या बढ़ जाती है। N = 4 के लिए समाधान स्पष्ट रूप से दिखाता है कि बीयरिंग कैसे समान रूप से दूरी पर हैं, इस मामले में अंतर 360/4 = 90 डिग्री के बराबर होता है और जाहिर है कि रिक्ति बिल्कुल हासिल की जाती है।
यह समाधान सही नहीं है: आप शायद कई आर्क्स की पहचान कर सकते हैं जो कि ग्राफिक को बेहतर बनाने के लिए मैन्युअल रूप से ट्विक किए जा सकते हैं। लेकिन यह एक भयानक काम नहीं करेगा और वास्तव में अच्छी शुरुआत होगी।
एल्गोरिथ्म में सरल होने का गुण भी है: सबसे जटिल भाग में उनके बीयरिंगों के अनुसार स्थलों को क्रमबद्ध करना शामिल है।
कोडिंग
मैं PostGIS नहीं जानता, लेकिन शायद उदाहरणों को आकर्षित करने के लिए मैंने जो कोड इस्तेमाल किया था, वह पोस्टगिस (या किसी अन्य जीआईएस) में इस एल्गोरिदम को लागू करने के लिए एक मार्गदर्शक के रूप में काम कर सकता है।
निम्नलिखित पर विचार करें pseudocode (लेकिन Mathematica इसे निष्पादित करेगा :-)। (यदि यह साइट TeX का समर्थन करती है, जैसा कि गणित, आँकड़े और TCS वाले करते हैं, तो मैं इसे बहुत अधिक पठनीय बना सकता था ।) संकेतन में शामिल है।
- परिवर्तनीय और फ़ंक्शन नाम केस-संवेदी होते हैं।
- [अल्फा] एक लोअर-केस ग्रीक चरित्र है। ([Pi] का मूल्य है जो आपको लगता है कि यह होना चाहिए।)
- x [[i]] एक सरणी x का तत्व i है (अनुक्रमित १ पर शुरू)।
- f [a, b] तर्क a और b के लिए फ़ंक्शन f लागू करता है। उचित मामले में कार्य, जैसे 'न्यूनतम' और 'तालिका', प्रणाली-परिभाषित हैं; शुरुआती निचले अक्षर वाले अक्षर, जैसे 'कोण' और 'ऑफसेट', उपयोगकर्ता-परिभाषित हैं। टिप्पणियां किसी भी अस्पष्ट प्रणाली के कार्यों (जैसे 'अर्ग') की व्याख्या करती हैं।
- सारणी [f [i], {i, 1, n}] सरणी {f [1], f [2], ..., f [n]} बनाता है।
- वृत्त [o, r, {a, b}], त्रिज्या r के कोण पर केन्द्रित कोण a से कोण b (दोनों रेडियन वामावर्त में दोनों पूर्व की ओर से समतल) का एक चाप बनाता है।
- आदेश देना [x] x के छांटे गए तत्वों के अनुक्रमित की एक सरणी देता है। x [[ऑर्डरिंग [x]]] x का सॉर्ट किया गया संस्करण है। जब y की लंबाई x के समान होती है, तो y [[क्रम [x]]] x के साथ समानांतर रूप से y होता है।
कोड का निष्पादन योग्य भाग दयालु रूप से छोटा है - 20 से कम रेखाएं - क्योंकि इसका आधा भाग या तो घोषणात्मक ओवरहेड या टिप्पणियां हैं।
नक्शा खींचना
z
स्थलों की एक सूची है और y
मूल है।
circleMap[z_List, y_] :=
Module[{\[Alpha] = angles[y,z], \[Beta], \[Delta], n},
(* Sort the destinations by bearing *)
\[Beta] = Ordering[\[Alpha]];
x = z[[\[Beta] ]]; (* Destinations, sorted by bearing from y *)
\[Alpha] = \[Alpha][[\[Beta]]]; (* Bearings, in sorted order *)
\[Delta] = offset[\[Alpha]];
n = Length[\[Alpha]];
Graphics[{(* Draw the lines *)
Gray, Table[circle[y, x[[i]],2 \[Pi] i / n + \[Delta] - \[Alpha][[i]]],
{i, 1, Length[\[Alpha]]}],
(* Draw the destination points *)
Red, PointSize[0.02], Table[Point[u], {u, x}]
}]
]
X -> y असर के सापेक्ष कोण पर x
बिंदु से बिंदु तक एक गोलाकार चाप बनाएं ।y
\[Beta]
circle[x_, y_, \[Beta]_] /; -\[Pi] < \[Beta] < \[Pi] :=
Module[{v, \[Rho], r, o, \[Theta], sign},
If[\[Beta]==0, Return[Line[{x,y}]]];
(* Obtain the vector from x to y in polar coordinates. *)
v = y - x; (* Vector from x to y *)
\[Rho] = Norm[v]; (* Length of v *)
\[Theta] = Arg[Complex @@ v]; (* Bearing from x to y *)
(* Compute the radius and center of the circle.*)
r = \[Rho] / (2 Sin[\[Beta]]); (* Circle radius, up to sign *)
If[r < 0, sign = \[Pi], sign = 0];
o = (x+y)/2 + (r/\[Rho]) Cos[\[Beta]]{v[[2]], -v[[1]]}; (* Circle center *)
(* Create a sector of the circle. *)
Circle[o, Abs[r], {\[Pi]/2 - \[Beta] + \[Theta] + sign, \[Pi] /2 + \[Beta] + \[Theta] + sign}]
]
एक मूल से बीयरिंगों की गणना बिंदुओं की सूची के लिए करें।
angles[origin_, x_] := Arg[Complex@@(#-origin)] & /@ x;
बीयरिंगों के एक सेट के अवशेषों की midrange की गणना करें।
x
क्रमबद्ध क्रम में बीयरिंगों की एक सूची है। आदर्श रूप से, x [[i]] ~ 2 [Pi] i / n।
offset[x_List] :=
Module[
{n = Length[x], y},
(* Compute the residuals. *)
y = Table[x[[i]] - 2 \[Pi] i / n, {i, 1, n}];
(* Return their midrange. *)
(Max[y] + Min[y])/2
]