आप एक बिटमैप में दो बिंदुओं के बीच एक सीधी रेखा कैसे खींचते हैं?


17

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

यह आसान है अगर आपके अंक एक एक्स या वाई समन्वय करते हैं, या यदि वे गठबंधन किए जाते हैं तो आप पूरी तरह से विकर्ण रेखा खींच सकते हैं। लेकिन अन्य सभी मामलों में इसकी चालाकी।

यह निर्धारित करने के लिए कि "सीधे" लाइन बनने के लिए किन पिक्सेल को रंगीन करने की आवश्यकता है, यह निर्धारित करने के लिए आप किस एल्गोरिथ्म का उपयोग करते हैं?

जवाबों:


26

मुझे लगता है कि आपको ब्रेसेनहैम की लाइन एल्गोरिदम की आवश्यकता है ।

मुझे जो याद है, उसका उपयोग यह निर्धारित करने के लिए किया जाता है कि किस बिंदु को रंगीन होना चाहिए, न कि प्रत्येक बिंदु को कितना रंगीन होना चाहिए।


21

ब्रेसेनहम की लाइन एल्गोरिदम का उपयोग यह निर्धारित करने के लिए किया जा सकता है कि लाइन सेगमेंट के एक उपयुक्त दृश्य सन्निकटन को प्राप्त करने के लिए एक रेखापुंज ग्रिड में कौन से बिंदु हैं।

एल्गोरिथ्म एक समन्वित स्थान में उत्पत्ति और समापन बिंदु द्वारा परिभाषित रेखा के रेखांकन को कवर करता है जहां मूल ऊपरी बाएँ में है। पूर्णांक निर्देशांक को पिक्सेल केंद्रों के मानचित्र के लिए माना जाता है। विशेष रूप से, एल्गोरिथ्म का मूल रूप केवल सर्कल के एक ओकटेंट को कवर करता है: वह जहां लाइन में एक्स और वाई निर्देशांक बढ़ रहा है, लेकिन 1 से कम निरपेक्ष मान के साथ एक नकारात्मक ढलान है। अन्य सभी ओकटेंट इसे सरल परिवर्तनों के रूप में प्राप्त कर सकते हैं मूल अष्टक।

Psuedocode में, यह मूल रूप इस तरह दिखता है:

void DrawLine(Point origin, Point endpoint, Bitmap surface) {
    deltaX = endpoint.X - origin.X
    deltaY = endpoint.Y - origin.Y
    error = 0

    // Note the below fails for completely vertical lines.
    deltaError = absoluteValue(deltaY / deltaX)

    Y = origin.Y
    for (X from origin.X to endpoint.X) {
        surface.PlotPixel(X, Y)
        error = error + deltaError 
        if (error >= 0.5) {
            ++Y;
            error -= 1.0
        }
    }
}

रोसेटा कोड वेबसाइट में विभिन्न भाषाओं में ठोस कार्यान्वयन का संग्रह है

आपको वू की लाइन एल्गोरिदम में भी रुचि हो सकती है , जो एंटी-अलियासिंग के लिए अनुमति देता है।


3
बस राहगीरों को चेतावनी देने के लिए शामिल pseudocode को संदर्भ से बाहर नहीं करना चाहते हैं, क्योंकि यह बॉक्स से बाहर काम नहीं करेगा। यह केवल एक विशिष्ट अष्टक के लिए काम करता है (शेष उत्तर पढ़ें)। यदि आप कॉपी / पेस्ट करने के लिए कोड की तलाश कर रहे हैं, तो रोसेटा कोड वेबसाइट के लिंक का प्रयास करें।
कॉंग्सबोंगस

1
किसी के लिए वू के लाइन एल्गोरिथ्म के सी संस्करण की जांच करना चाहता हूं, मैं आपको चेतावनी देना चाहूंगा कि यह अधूरा है। : _Dla_changebrightness में जब आप चमक आप से उसे बदलना चाहते हैं बदलने के to->red = br * (float)from->red;इस निम्नलिखित हैं: to->red = (br * (float)from->red) + ((1-br) * (float) to->red);। हरे और नीले रंग के लिए समान रूप से करें
फ्रेड्रिक बोस्टन वेस्टमैन

2

यहाँ रेखाएँ खींचने का एक बहुत ही सरल तरीका है। फ़ंक्शन को आसानी से परियोजनाओं में उपयोग करने के लिए बदला जा सकता है।

void draw_line(float x0, float y0, const float& x1, const float& y1)
{
    float x{x1 - x0}, y{y1 - y0};
    const float max{std::max(std::fabs(x), std::fabs(y))};
    x /= max; y /= max;
    for (float n{0}; n < max; ++n)
    {
        // draw pixel at ( x0, y0 )
        x0 += x; y0 += y;
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.