समोच्च मानचित्र में बहुभुज को चिकना करना?


52

यहाँ एक समोच्च नक्शा है जिसके लिए सभी स्तर के बहुभुज उपलब्ध हैं।

चलो पूछें कि अपने सभी स्थानों में संरक्षित सभी लंबों को रखने वाले बहुभुजों को कैसे चिकना करें?

वास्तव में समोच्च एक ग्रिड डेटा के ऊपर बनाया गया है, तो आप ग्रिड डेटा को सुचारू करने के लिए सुझाव दे सकते हैं और इसलिए परिणामस्वरूप समोच्च चिकना होगा। ध्यान दें कि यह मेरी इच्छा के रूप में काम नहीं कर रहा है क्योंकि गॉसियन फ़िल्टर जैसे चौरसाई फ़ंक्शन डेटा के छोटे पैक को हटा देगा और तीसरे चर की सीमा को बदल देगा, उदाहरण के लिए, मेरे आवेदन में ऊंचाई की अनुमति नहीं है।

वास्तव में मैं कोड के एक टुकड़े (अधिमानतः अजगर में ) की तलाश कर रहा हूं जो 2D बहुभुजों (किसी भी प्रकार: उत्तल, अवतल, स्व-प्रतिच्छेदन आदि) को सुचारू रूप से दर्द रहित कर सकता है (कोड के पृष्ठों को भूल जाएं) और सटीक।

FYI करें, ArcGIS में एक फ़ंक्शन है जो यह पूरी तरह से करता है, लेकिन तीसरे पक्ष के वाणिज्यिक अनुप्रयोगों का उपयोग करना इस प्रश्न के लिए मेरी पसंद नहीं है।

यहाँ छवि विवरण दर्ज करें


1)

Scipy.interpolate:

यहाँ छवि विवरण दर्ज करें

जैसा कि आप देखते हैं कि परिणामी स्प्लिंस (लाल) संतोषजनक नहीं हैं!

2)

यहां दिए गए कोड का उपयोग करने का परिणाम यहां दिया गया है । यह अच्छी तरह से काम नहीं कर रहा है!

यहाँ छवि विवरण दर्ज करें

3)

मेरे लिए सबसे अच्छा समाधान निम्न आकृति जैसा कुछ होना चाहिए जिसमें एक वर्ग को केवल एक मान बदलकर धीरे-धीरे चिकना किया जा रहा है। मैं बहुविवाह के किसी भी रूप को चौरसाई करने के लिए इसी तरह की अवधारणा की उम्मीद करता हूं।

यहाँ छवि विवरण दर्ज करें

उस स्थिति को संतुष्ट करना जो तख्तापलट से गुजरती है:

यहाँ छवि विवरण दर्ज करें

4)

यहाँ पायथन में उनके डेटा पर लाइन द्वारा "व्ह्यूबर आइडिया" का मेरा कार्यान्वयन है । परिणाम बेहतर नहीं होने के कारण संभवतः कुछ कीड़े हैं।

यहाँ छवि विवरण दर्ज करें

K = 2 एक आपदा है और इसलिए k> = 4 के लिए है।

5)

मैंने समस्याग्रस्त स्थान में एक बिंदु को हटा दिया है और परिणामी सीमा अब व्हीबर के समान है। लेकिन यह अभी भी एक सवाल है कि विधि सभी मामलों के लिए काम क्यों नहीं करती है?

यहाँ छवि विवरण दर्ज करें

6)

व्हीबर के डेटा के लिए एक अच्छी स्मूथिंग निम्नानुसार हो सकती है (वेक्टर ग्राफिक्स सॉफ्टवेयर द्वारा खींची गई) जिसमें एक अतिरिक्त बिंदु आसानी से जोड़ा गया है (अपडेट की तुलना करें)

4):

यहाँ छवि विवरण दर्ज करें

7)

कुछ प्रतिष्ठित आकृतियों के लिए व्हीबर कोड के पायथन संस्करण से परिणाम देखें:

यहाँ छवि विवरण दर्ज करें
ध्यान दें कि लगता है कि विधि पॉलीलाइन के लिए काम नहीं करती है। कोने के लिए पॉलीलाइन (समोच्च) हरा है जो मैं चाहता हूं लेकिन लाल हो गया। यह ध्यान देने की जरूरत है क्योंकि समोच्च नक्शे हमेशा पॉलीलाइन होते हैं हालांकि बंद पॉलीइन्स को मेरे उदाहरण के रूप में बहुभुज के रूप में माना जा सकता है। यह भी नहीं कि अद्यतन 4 में उभरी समस्या का समाधान अभी तक नहीं किया गया है।

8) [मेरा आखिरी]

यहाँ अंतिम समाधान है (सही नहीं!):

यहाँ छवि विवरण दर्ज करें

याद रखें कि आपको सितारों द्वारा इंगित क्षेत्र के बारे में कुछ करना होगा। मेरे कोड में शायद एक बग है या प्रस्तावित विधि को सभी परिस्थितियों पर विचार करने और वांछित आउटपुट प्रदान करने के लिए और अधिक विकास की आवश्यकता है।


आप 'बहुभुज' आकृति कैसे बना रहे हैं? क्या वे हमेशा रेखा नहीं बनेंगे, क्योंकि एक समोच्च एक DEM के किनारे को काटते हुए अपने आप कभी बंद नहीं होगा?
पिस्ता

मैंने सभ्य परिणामों के साथ समोच्च लाइनों के चौरसाई करने के लिए GRASS में v.generalize फ़ंक्शन का उपयोग किया है, हालांकि यह बहुत घने आकृति वाले नक्शे के लिए थोड़ी देर ले सकता है।
पिस्ता

@pistachionut आप विचार कर सकते हैं कि समोच्च स्तर पाली-रेखाएँ हैं। मैं पहले चरण में शुद्ध कोड की तलाश में हूं । यदि उपलब्ध नहीं है तो पाइथन के लिए हल्का पैकेज।
डेवलपर

शायद देखो scipy.org/Cookbook/Interpolation क्योंकि यह लगता है कि आप पट्टी करना चाहते हैं
PolyGeo

1
आपके लिंक में @ पाब्लो बेजियर कर्व पॉलीइन्स के लिए अच्छा काम करता है। पॉलीगोन के लिए व्हीबर्स लगभग अच्छी तरह से काम करता है। इसलिए वे एक साथ सवाल का समाधान कर सकते थे। अपने ज्ञान को मुफ्त में साझा करने के लिए बहुत धन्यवाद।
डेवलपर

जवाबों:


37

संख्याओं के अनुक्रमों को फैलाने के लिए अधिकांश विधियां बहुभुज को रेखांकित करेंगी। चाल समापन बिंदु पर सुचारू रूप से "क्लोज अप" बनाने के लिए है। ऐसा करने के लिए, सिरों के चारों ओर स्थित "लपेट"। फिर x- और y- निर्देशांक को अलग-अलग स्थानांतरित करें।

इसमें एक कार्य उदाहरण दिया गया है R। यह splineमूलभूत सांख्यिकी पैकेज में उपलब्ध डिफ़ॉल्ट घन प्रक्रिया का उपयोग करता है । अधिक नियंत्रण के लिए, अपनी पसंद की लगभग किसी भी प्रक्रिया को स्थानापन्न करें: बस यह सुनिश्चित करें कि यह संख्याओं के माध्यम से विभाजित होती है (अर्थात उन्हें प्रक्षेपित करती है) केवल "नियंत्रण बिंदु" के रूप में उनका उपयोग करने के बजाय।

#
# Splining a polygon.
#
#   The rows of 'xy' give coordinates of the boundary vertices, in order.
#   'vertices' is the number of spline vertices to create.
#              (Not all are used: some are clipped from the ends.)
#   'k' is the number of points to wrap around the ends to obtain
#       a smooth periodic spline.
#
#   Returns an array of points. 
# 
spline.poly <- function(xy, vertices, k=3, ...) {
    # Assert: xy is an n by 2 matrix with n >= k.

    # Wrap k vertices around each end.
    n <- dim(xy)[1]
    if (k >= 1) {
        data <- rbind(xy[(n-k+1):n,], xy, xy[1:k, ])
    } else {
        data <- xy
    }

    # Spline the x and y coordinates.
    data.spline <- spline(1:(n+2*k), data[,1], n=vertices, ...)
    x <- data.spline$x
    x1 <- data.spline$y
    x2 <- spline(1:(n+2*k), data[,2], n=vertices, ...)$y

    # Retain only the middle part.
    cbind(x1, x2)[k < x & x <= n+k, ]
}

इसके उपयोग को स्पष्ट करने के लिए, आइए एक छोटा (लेकिन जटिल) बहुभुज बनाएं।

#
# Example polygon, randomly generated.
#
set.seed(17)
n.vertices <- 10
theta <- (runif(n.vertices) + 1:n.vertices - 1) * 2 * pi / n.vertices
r <- rgamma(n.vertices, shape=3)
xy <- cbind(cos(theta) * r, sin(theta) * r)

पूर्ववर्ती कोड का उपयोग करके इसे स्पलाइन करें। तख़्ता चिकना बनाने के लिए, 100 से कोने की संख्या बढ़ाएं; इसे कम चिकना बनाने के लिए, की संख्या कम करें।

s <- spline.poly(xy, 100, k=3)

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

plot(s, type="l", lwd=2, col="Gray")
lines(xy, col="Red", lty=2, lwd=2)
points(xy, col="Red", pch=19)
points(s, cex=0.8)
points(s[c(1,dim(s)[1]),], col="Blue", pch=19)

विभाजित बहुभुज


5
अच्छा जवाब। क्या समोच्चों की गारंटी देने का कोई तरीका है कि चौरसाई के परिणामस्वरूप क्रॉसिंग खत्म न हो?
कर्क कुयकेंडल

यह एक अच्छा सवाल है, @Kirk। इस प्रकार के चौरसाई से गैर-क्रॉसिंग की गारंटी देने के किसी भी तरीके के बारे में मुझे जानकारी नहीं है। (वास्तव में, मैं यह भी नहीं देखता कि यह गारंटी कैसे दी जाती है कि चिकनी पॉलीलाइन गैर-स्व-प्रतिच्छेदन है। हालांकि, अधिकांश आकृति के लिए यह एक बड़ा मुद्दा नहीं है।) ऐसा करने के लिए, आपको मूल मूल पर लौटने की आवश्यकता होगी। डीईएम और इसके बजाय पहले स्थान पर आकृति की गणना करने के लिए एक बेहतर विधि का उपयोग करें। (वहाँ रहे हैं बेहतर तरीकों - वे एक लंबे समय के लिए जाने जाते हैं - लेकिन AFAIK सबसे लोकप्रिय GISes में से कुछ उन्हें प्रयोग नहीं करते।)
whuber

सबसे पहले, मैं अभी भी पायथन में आपके उत्तर को लागू करने के लिए काम कर रहा हूं, फिर भी सफल नहीं है। दूसरा, यदि आप अपनी पद्धति को एक वर्ग पर लागू करते हैं तो परिणाम क्या होगा? आप उन लोगों का उल्लेख कर सकते हैं जिन्हें मैंने प्रश्न में खींचा है।
डेवलपर

1
मैंने इसे उत्तर के रूप में स्वीकार किया क्योंकि यह एक अच्छा समाधान देता है। भले ही यह एक संपूर्ण नहीं है, लेकिन इसने मुझे चारों ओर काम करने वाले कुछ विचार दिए, आशा है कि मैं एक ऐसा समाधान पाऊंगा, जो मेरे प्रश्न और टिप्पणियों में ऊपर वर्णित बिंदुओं को संतुष्ट करता है। आप प्रश्न [QC] के लिए व्ह्यूबर की टिप्पणियों पर भी विचार कर सकते हैं, वहाँ अच्छी चालें हैं। अंत में, मुझे कहना चाहिए कि अजगर के लिए अनुवाद लगभग सीधा है, जिसमें प्यारा स्किप पैकेज स्थापित किया गया है। इसके अलावा QC में पाब्लो की टिप्पणी को पॉलीइन्स के लिए संभव समाधान के रूप में समझें, अर्थात, बेज़ियर घटता। भाग्य आप सभी का साथ दे।
डेवलपर

1
आपके जवाबों को देखकर, मुझे अपने मैथ्स का अच्छी तरह से ख्याल न रखने का अफसोस है !!!
११:१२ बजे विनयन

2

मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन यह Google पर कुछ ऐसी चीज़ों के लिए दिखाई दी जिसकी मुझे तलाश थी, इसलिए मैंने सोचा कि मैं अपना समाधान पोस्ट करूं।

मैं इसे 2 डी कर्व फिटिंग एक्सरसाइज के रूप में नहीं देखता, बल्कि 3 डी के रूप में देखता हूं। 3 डी के रूप में डेटा पर विचार करके हम यह सुनिश्चित कर सकते हैं कि कर्व कभी एक दूसरे को पार नहीं करते हैं, और वर्तमान के लिए हमारे अनुमान को बेहतर बनाने के लिए अन्य आकृति से जानकारी का उपयोग कर सकते हैं।

निम्नलिखित iPython एक्सट्रैक्ट SciPy द्वारा प्रदान किए गए क्यूबिक इंटरपोलेशन का उपयोग करता है। ध्यान दें कि मैंने जो मान लिए हैं, वे महत्वपूर्ण नहीं हैं, जब तक कि सभी आकृति ऊंचाई में समरूप न हों।

In [1]: %pylab inline
        pylab.rcParams['figure.figsize'] = (10, 10)
        Populating the interactive namespace from numpy and matplotlib

In [2]: import scipy.interpolate as si

        xs = np.array([0.0, 0.0, 4.5, 4.5,
                       0.3, 1.5, 2.3, 3.8, 3.7, 2.3,
                       1.5, 2.2, 2.8, 2.2,
                       2.1, 2.2, 2.3])
        ys = np.array([0.0, 3.0, 3.0, 0.0,
                       1.1, 2.3, 2.5, 2.3, 1.1, 0.5,
                       1.1, 2.1, 1.1, 0.8,
                       1.1, 1.3, 1.1])
        zs = np.array([0,   0,   0,   0,
                       1,   1,   1,   1,   1,   1,
                       2,   2,   2,   2,
                       3,   3,   3])
        pts = np.array([xs, ys]).transpose()

        # set up a grid for us to resample onto
        nx, ny = (100, 100)
        xrange = np.linspace(np.min(xs[zs!=0])-0.1, np.max(xs[zs!=0])+0.1, nx)
        yrange = np.linspace(np.min(ys[zs!=0])-0.1, np.max(ys[zs!=0])+0.1, ny)
        xv, yv = np.meshgrid(xrange, yrange)
        ptv = np.array([xv, yv]).transpose()

        # interpolate over the grid
        out = si.griddata(pts, zs, ptv, method='cubic').transpose()

        def close(vals):
            return np.concatenate((vals, [vals[0]]))

        # plot the results
        levels = [1, 2, 3]
        plt.plot(close(xs[zs==1]), close(ys[zs==1]))
        plt.plot(close(xs[zs==2]), close(ys[zs==2]))
        plt.plot(close(xs[zs==3]), close(ys[zs==3]))
        plt.contour(xrange, yrange, out, levels)
        plt.show()

क्यूबिक इंटरपोलेटेड रिजल्ट

यहां परिणाम सबसे अच्छे नहीं लगते हैं, लेकिन कुछ नियंत्रण बिंदुओं के साथ वे अभी भी पूरी तरह से मान्य हैं। ध्यान दें कि व्यापक नीले समोच्च का पालन करने के लिए हरे रंग की फिट लाइन को कैसे निकाला जाता है।


फिटेड स्मूथ कर्व्स को मूल बहुभुज / पॉलीलाइन के करीब संभव रहना चाहिए।
डेवलपर

1

मैंने लगभग वही पैकेज लिखा, जिसकी आप तलाश कर रहे हैं ... लेकिन यह पर्ल में था, और एक दशक पहले था: जीडी :: पॉलीलाइन । इसमें 2 डी क्यूबिक बेज़ियर कर्व्स का इस्तेमाल किया गया है, और एक मनमाना बहुभुज या "पॉलीलाइन" "मेरा नाम" होगा (फिर मेरा नाम जिसे अब "लाइनस्ट्रीमिंग" कहा जाता है)।

एल्गोरिथ्म दो चरण था: बहुभुज में अंक दिए गए, हर बिंदु के बीच दो बेज़ियर नियंत्रण बिंदु जोड़ें; तो एक सरल एल्गोरिथ्म कॉल करने के लिए एक टुकड़ा के टुकड़े करना सन्निकटन।

दूसरा भाग आसान है; पहला भाग कला का एक सा था। यहाँ अंतर्दृष्टि थी: एक "कंट्रोल सेगमेंट" पर विचार करें एक वर्टेक्स एन vN:। नियंत्रण खंड तीन सह-रेखीय बिंदु थे [cNa, vN, cNb]:। केंद्र बिंदु शीर्ष था। इस नियंत्रण सेग का ढलान वर्टेक्स एन -1 से वर्टेक्स एन + 1 तक ढलान के बराबर था। इस सेगमेंट के बाएं हिस्से की लंबाई वर्टेक्स एन -1 से वर्टेक्स एन तक की लंबाई 1/3 थी, और इस सेगमेंट के दाहिने हिस्से की लंबाई वर्टेक्स एन से वेरटेक्स एन + 1 की लंबाई 1/3 थी।

यदि मूल वक्र चार वर्टिकल थे: [v1, v2, v3, v4]तो प्रत्येक वर्टेक्स को अब फॉर्म का एक नियंत्रण खंड मिलता है [c2a, v2, c2b]:। स्ट्रिंग को एक साथ इस तरह से करें: [v1, c1b, c2a, v2, c2b, c3a, v3, c3b, c4a, v4]और उन्हें चार बेज़ियर बिंदुओं के रूप में एक बार में चबाना:, [v1, c1b, c2a, v2]फिर [v2, c2b, c3a, v3], और इसी तरह। क्योंकि [c2a, v2, c2b]सह-रैखिक थे, परिणामस्वरूप वक्र प्रत्येक शीर्ष पर चिकना होगा।

तो यह भी वक्र की "जकड़न" को मानकीकृत करने के लिए आपकी आवश्यकता को पूरा करता है: "तंग" वक्र के लिए 1/3 से छोटे मूल्य का उपयोग करें, "लूपियर" फिट के लिए एक बड़ा। या तो मामले में, परिणामस्वरूप वक्र हमेशा मूल दिए गए बिंदुओं से गुजरता है।

इससे एक चिकनी वक्र उत्पन्न हुआ जो मूल बहुभुज को "परिचालित" करता है। मेरे पास एक सहज वक्र "इंसुलेट" करने का भी कोई तरीका था ... लेकिन मैं सीपीएएन कोड में नहीं देखता।

वैसे भी, इस समय मेरे पास पायथन में उपलब्ध संस्करण नहीं है, न ही मेरे पास कोई आंकड़े हैं। लेकिन ... अगर / जब मैं इसे पायथन को पोर्ट करता हूं, तो मैं यहां पोस्ट करना सुनिश्चित करूंगा।


पर्ल कोड का मूल्यांकन नहीं किया जा सकता है, यदि संभव हो तो यह प्रदर्शित करने के लिए ग्राफिक्स जोड़ें।
डेवलपर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.