Bézier घटता के साथ सर्कल कैसे बनाएं?


99

हमारे पास एक आरंभ बिंदु (x, y) और एक वृत्त त्रिज्या है। वहाँ एक इंजन भी मौजूद है जो बेज़ियर वक्र बिंदुओं से एक पथ बना सकता है।

मैं Bézier घटता का उपयोग करके एक सर्कल कैसे बना सकता हूं?


निकटता से संबंधित:
गीज़र्टिकल

जवाबों:


138

जैसा कि पहले ही कहा गया है: बेज़ियर वक्रों का उपयोग करके सर्कल का कोई सटीक प्रतिनिधित्व नहीं है।

बेज़ियर वक्र के लिए के साथ: अन्य उत्तर पूरा करने के लिए nक्षेत्रों इष्टतम अर्थ में नियंत्रण बिंदुओं के लिए दूरी, उस चक्र पर ही वक्र झूठ के बीच, है (4/3)*tan(pi/(2n))

n सेगमेंट के लिए सूत्र

तो 4 अंक के लिए यह है (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831

4 बिंदु का मामला


2
इष्टतम दूरी से, आप किस प्रकार के मैट्रिक्स का अनुकूलन कर रहे हैं? जैसा कि क्यूबिक बेज़ियर घटता के साथ एक सर्कल में दिखाया गया है , सबसे कम संभव अधिकतम बहाव एक अलग मूल्य द्वारा प्राप्त किया जाता है। क्या आप अपने मामले में "इष्टतम" का अर्थ निर्धारित करने वाले कुछ लिंक प्रदान कर सकते हैं या यह सूत्र कैसे प्राप्त किया जा सकता है?
सुमा

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

2
ठीक है। मैं फिर से प्रयास करने की कोशिश करूंगा: "नियंत्रण बिंदुओं की दूरी ऐसी है कि वक्र का मध्य सर्कल पर ही स्थित है"। मैं इसे एक वैध निर्णय (गणना के लिए अच्छा और आसान) के रूप में देखता हूं, लेकिन मैं इसे इष्टतम नहीं कहूंगा (कम से कम यह लिखे बिना कि यह किस अर्थ में इष्टतम है) नहीं।
सुमा

1
हाँ, चूँकि इस पर अधिकतम ०.०२ and% का विचलन है और ०-बनाम का एक विचलन है। यह केवल वास्तविक सर्कल की तुलना में कभी बड़ा है, बेहतर सुधार सन्निकटन सी को 0.027% के आधे से आगे बढ़ाकर किया जाता है। यदि आप सर्कल पर मिडपॉइंट चाहते हैं, तो यह निश्चित रूप से इसे करने का तरीका है।
तांत्रिक करें

2
@ किंवदंतियों 2k मैं एक पीडीएफ उत्पन्न करने के लिए टिकज के साथ लाटेक्स का उपयोग करता हूं जिसे मैं पीएनजी में परिवर्तित करता हूं।
23

34

Comp.graphics.faq में कवर किया गया

अंश:

विषय ४.०४: मैं एक सर्कल में एक बेजियर वक्र कैसे फिट करूं?

दिलचस्प रूप से पर्याप्त है, बेजियर घटता एक सर्कल का अनुमान लगा सकता है लेकिन पूरी तरह से एक सर्कल के लायक नहीं है। एक आम सन्निकटन एक वृत्त को मॉडल करने के लिए चार बेज़ियर्स का उपयोग करना है, प्रत्येक नियंत्रण बिंदुओं के साथ दूरी d = r * 4 * (sqrt (2) -1) / 3 अंतिम बिंदुओं से (जहाँ r वृत्त त्रिज्या है), और में अंत बिंदुओं पर वृत्त की एक दिशा स्पर्शरेखा। यह सुनिश्चित करेगा कि बेज़ियर के मध्य बिंदु सर्कल पर हैं, और यह कि पहला व्युत्पन्न निरंतर है।
इस सन्निकटन में रेडियल त्रुटि सर्कल के त्रिज्या का लगभग 0.0273% होगी।

माइकल गोल्डप्प, "क्यूबिक पॉलिनॉमिअल्स द्वारा सर्कुलर आर्क्स की स्वीकृति" कंप्यूटर एडेड जियोमेट्रिक डिज़ाइन (# 8 1991 pp.227-238)

टॉर डोकन और मोर्टन डेहलेन, "वक्र-निरंतर बेज़ियर घटता द्वारा सर्किलों का अच्छा अनुमान" कंप्यूटर एडेड जियोमेट्रिक डिज़ाइन (# 7 1990 पीपी 33-41)। http://www.sciencedirect.com/science/article/pii/016783969090019N (गैर मुक्त लेख)

गैर-देय लेख भी देखें http://spencermortensen.com/articles/bezier-circle/

ब्राउज़र और कैनवास तत्व।

ध्यान दें कि कुछ ब्राउज़र अपने कैनवस ड्रॉ के लिए बेजियर कर्व्स का उपयोग करते हैं, क्रोम (वर्तमान समय में) 4 सेक्टर के दृष्टिकोण का उपयोग करता है और सफारी 8 सेक्टर के दृष्टिकोण का उपयोग करता है, यह अंतर केवल उच्च रिज़ॉल्यूशन पर ध्यान देने योग्य है, क्योंकि यह 0.0273% है, और यह भी केवल वास्तविक रूप से दृश्यमान जब आर्क्स समानांतर और चरण के बाहर खींचे जाते हैं, तो आप आर्क्स को एक सच्चे सर्कल से दोलन करते हुए देखेंगे। प्रभाव तब और भी अधिक ध्यान देने योग्य होता है जब वक्र रेडियल सेंटर के चारों ओर एनिमेट होता है, 600px त्रिज्या आमतौर पर आकार का होता है जहां यह एक अंतर बनाएगा।

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

ध्यान दें कि ब्राउज़रों के भीतर एसवीजी इंजन एक अलग ड्राइंग विधि का उपयोग कर सकते हैं।

अन्य प्लेटफार्मों

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


धन्यवाद, मैं इसका विकल्प दूंगा।
ओसोडो

31

प्रश्न के उत्तर बहुत अच्छे हैं, इसलिए जोड़ने के लिए बहुत कम है। इससे प्रेरित होकर मैंने चार बेज़ियर घटता के साथ शुरू होने वाले समाधान की दृष्टि से पुष्टि करने के लिए एक प्रयोग करना शुरू किया, घटता की संख्या को एक तक कम कर दिया। आश्चर्यजनक रूप से मुझे पता चला कि तीन बेज़ियर कर्व्स के साथ सर्कल मेरे लिए काफी अच्छा लग रहा था, लेकिन निर्माण थोड़ा मुश्किल है। वास्तव में मैं एक लाल 3-पिक्सेल-वाइड सर्कल (जैसा कि Inkscape द्वारा निर्मित) पर ब्लैक 1-पिक्सेल-वाइड बेज़ियर सन्निकटन लगाने के लिए इंकस्केप का उपयोग करता था। स्पष्टीकरण के लिए मैंने नीली रेखाओं और सतहों को जोड़ा जो कि बेज़ियर घटता के बाउंडिंग बॉक्स दिखा रहा है।

अपने आप को देखने के लिए, मैं अपने परिणाम प्रस्तुत कर रहा हूँ:

1-वक्र ग्राफ (जो एक कोने में निचोड़ा हुआ दिखता है, पूर्णता के लिए):यहां छवि विवरण दर्ज करें

2-वक्र ग्राफ:यहां छवि विवरण दर्ज करें

3-वक्र ग्राफ:यहां छवि विवरण दर्ज करें

4-वक्र ग्राफ: यहां छवि विवरण दर्ज करें

(मैं SVG या PDF यहाँ रखना चाहता था, लेकिन यह समर्थित नहीं है)


1
अब तक, svg को html कोड स्निपेट के रूप में शामिल किया जा सकता है। उदाहरण के लिए यह उत्तर देखें: stackoverflow.com/a/32162431
TS

1
@TS: जब मैंने अपने पास मौजूद एसवीजी के साथ ग्राफिक्स को बदलने की कोशिश की, तो मुझे एहसास हुआ कि मैंने उन यूएसबी स्टिक के साथ खो दिया है जो इस साल की शुरुआत में चोरी हो गए थे। अगर समय की अनुमति मिलती है, तो मैं जल्द ही उन्हें फिर से बनाने की कोशिश करूंगा। हालाँकि अगर SVG को XML कोड के रूप में जोड़ा जा सकता है (और ग्राफिक्स के रूप में प्रदर्शित नहीं किया गया है) तो यहाँ बहुत अर्थ नहीं है।
यू। विंडल

यदि आपका ब्राउज़र svg का समर्थन करता है, तो जैसे ही आप "रन कोड स्निपेट" पर क्लिक करते हैं, चित्र प्रदान किए जाते हैं (जाहिर है कि बटन स्टैकओवरफ़्लो के मोबाइल संस्करण पर उपलब्ध नहीं है ...)। मैंने जो जवाब दिया, उसमें देखें।
टीएस

1
@TS: लंबी फ़ाइलों के लिए यह बहुत बदसूरत IMHO है।
यू। विंडल

9

कई उत्तर पहले से ही लेकिन मुझे एक छोटा सा ऑनलाइन लेख मिला जिसमें एक सर्कल का बहुत अच्छा क्यूबिक बेज़ियर सन्निकटन है। यूनिट सर्कल c = 0.55191502449 के संदर्भ में जहां c अक्ष अंतर बिंदुओं से नियंत्रण बिंदुओं पर स्पर्शरेखा के साथ दूरी है।

नियंत्रण बिंदु होने के साथ दो मध्य निर्देशांक के साथ इकाई चक्र के लिए एक एकल चतुर्भुज के रूप में। (0,1),(c,1),(1,c),(1,0)

रेडियल त्रुटि सिर्फ 0.019608% है, इसलिए मुझे इसे केवल उत्तरों की सूची में जोड़ना था।

लेख यहां पाया जा सकता है अनुमानित करें क्यूबिक बेज़ियर घटता के साथ एक चक्र


5
क्या आपने स्टाकेवरफ्लो के माइक ax पोमैक्स ’कमरमन्स द्वारा बेजियर कर्व्स पर इस उत्कृष्ट ग्रंथ को पढ़ा है । यह अच्छी तरह से पढ़ने लायक है! :-)
Marke

1
@markE आपको उस लिंक के लिए बहुत बहुत धन्यवाद, यह "सबसे उत्कृष्ट" ग्रंथ है जो मैंने इस विषय पर कभी देखा है। विस्तार से जाने का मौका पाने के लिए इंतजार नहीं कर सकते ..: D धन्यवाद ...
Blindman67

1
इसलिए 0.019608% त्रुटि के साथ ग्राफिक्स को 4 पिक्सेल मिलेंगे जब त्रिज्या एक चक्र में 2551 पिक्सेल से आगे निकल जाती है बजाय इसके कि भयानक 0.027253% जहां हम त्रुटि का एक ठोस आधा पिक्सेल हैं (जहां ग्राफिक्स इंजन पिक्सेल को बदल देगा) 1835 px के कारण 2 पिक्सेल त्रुटि में हैं!
तातार

@Tatarize लेख में यह निर्दिष्ट नहीं किया गया है कि त्रुटि कैसे मापी गई थी, यह कहता है कि अधिकतम रेडियल बहाव? मुझे लगता है कि त्रुटि को वक्र के साथ कम किया गया है 0 <= t <= 1 चतुर्भुज से मेल खाने के लिए <<pheta <= Pi / 2 at t = 0 = 1/2 = 1 बराबर pheta = 0 = Pi / 4 = Pi / 4 त्रुटि 0.019608% और अधिकतम त्रुटि t = ~ 0.1822 & t = ~ 0.8177 0.019608% (संकेत?) है, लेकिन इन बिंदुओं पर t समान नहीं है त्रुटि में कोणीय बहाव शामिल है? । 4pixels सही हो सकता है या नहीं भी। त्रुटि भिन्न हो सकती है, इस प्रकार त्रुटि <2pix r = 2551 के लिए। बहुत सारे प्रश्न
जिनकी

मुझे पूरा यकीन है कि त्रुटि वक्र को देखने पर लगता है कि दिए गए समायोजन चाप-रेखा के अधिकतम बिंदु के बराबर अधिकतम त्रुटि का कारण बनने के लिए बस बिंदु को नीचे ले जाता है। यह कहना है कि हम वक्र को थोड़ा नीचे बदलते हैं ताकि सभी त्रुटि सकारात्मक न हो। इस समायोजन का मतलब है कि हम अधिकतम त्रुटि के 4 अंक के साथ 4 बार आर्क लाइन पार कर रहे हैं। जब मूल युक्ति की रेखा में 2 बिंदु थे, अर्थात् t = .25 और t = .75 पर। समायोजन के साथ यह t = .125, t = .375 t = .625 t = .875 पर होना चाहिए। यह मानता है कि हम ठोस पिक्सेल का उपयोग कर रहे हैं, न कि एंटी-अलियासिड जो 14px पर बदल जाएगा।
ताताराइज़ करें

8

यह संभव नहीं है। एक बेजियर एक घन है (कम से कम ... सबसे अधिक इस्तेमाल किया जाता है)। एक वृत्त को एक घन के साथ बिल्कुल व्यक्त नहीं किया जा सकता है, क्योंकि एक वृत्त में इसके समीकरण में एक वर्गमूल होता है। परिणाम के रूप में, आपको लगभग अनुमान लगाना होगा।

ऐसा करने के लिए, आपको अपने सर्कल को n-tants (egquadants, octants) में विभाजित करना होगा। प्रत्येक एन-टेंट के लिए, आप पहले और आखिरी बिंदु का उपयोग करते हैं और बेज़ियर वक्र के पहले और अंतिम के रूप में। बेजियर बहुभुज को दो अतिरिक्त बिंदुओं की आवश्यकता होती है। तेज होने के लिए, मैं एन-टैंट के प्रत्येक चरम बिंदु के लिए स्पर्शरेखा को सर्कल में ले जाऊंगा और दो बिंदुओं को दो स्पर्शरेखाओं के प्रतिच्छेदन के रूप में चुनूंगा (ताकि मूल रूप से आपका बेजियर बहुभुज एक त्रिकोण हो)। अपनी सटीकता के लिए n-tants की संख्या बढ़ाएँ।


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

7

अन्य उत्तरों ने इस तथ्य को कवर किया है कि एक सच्चा चक्र संभव नहीं है। यह SVG फ़ाइल द्विघात बेज़ियर कर्व्स का उपयोग करते हुए एक सन्निकटन है, और आपको प्राप्त होने वाली निकटतम चीज़ है: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.sgg

यहाँ क्यूबिक बेज़ियर कर्व्स के साथ एक है: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg


7

जो लोग सिर्फ कोड की तलाश में हैं:

https://jsfiddle.net/nooorz24/2u9forep/12/

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

function drawBezierOvalQuarter(centerX, centerY, sizeX, sizeY) {
    ctx.beginPath();
    ctx.moveTo(
    	centerX - (sizeX),
        centerY - (0)
    );
    ctx.bezierCurveTo(
    	centerX - (sizeX),
        centerY - (0.552 * sizeY),
        centerX - (0.552 * sizeX),
        centerY - (sizeY),
        centerX - (0),
        centerY - (sizeY)
    );
	ctx.stroke();
}

function drawBezierOval(centerX, centerY, sizeX, sizeY) {
    drawBezierOvalQuarter(centerX, centerY, -sizeX, sizeY);
    drawBezierOvalQuarter(centerX, centerY, sizeX, sizeY);
    drawBezierOvalQuarter(centerX, centerY, sizeX, -sizeY);
    drawBezierOvalQuarter(centerX, centerY, -sizeX, -sizeY);
}

function drawBezierCircle(centerX, centerY, size) {
    drawBezierOval(centerX, centerY, size, size)
}

drawBezierCircle(200, 200, 64)
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

यह सर्कल को आकर्षित करने की अनुमति देता है जो 4 बेज़ियर घटता से बना है। जेएस में लिखा है, लेकिन आसानी से किसी भी अन्य भाषा में अनुवाद किया जा सकता है


यह बहुत उपयोगी है, धन्यवाद! 4 खंडों को क्रम में लाने के लिए क्या बदलना होगा? मुझे एक पथ के साथ पाठ लिखने की आवश्यकता है, लेकिन अब यह 4 खंडों के आसपास बिखरा हुआ है
एलेक्सा

1

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

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

Nएकल वक्र के लिए नियंत्रण बिंदुओं की संख्या कहां है और αवृत्त चाप कोण है।

द्विघात वक्र के लिए यह सरल किया जा सकता करने के लिए नहीं बल्कि एक अनुमान है - मैं सही मूल्य की गणना नहीं की थी लेकिन यह काफी करीब है। क्यूबिक वक्र के लिए लगभग 0.2% की त्रिज्या त्रुटि देने वाले 1-2 नियंत्रण बिंदुओं के साथ यह वक्र के लिए यथोचित रूप से अच्छा काम करता है। उच्च डिग्री घटता के लिए सटीकता का नुकसान ध्यान देने योग्य है। 3 नियंत्रण बिंदुओं के साथ वक्र द्विघात के समान दिखता है, तो जाहिर है कि मुझे कुछ याद आ रहा है, लेकिन मैं इसका पता नहीं लगा सकता और यह विधि आम तौर पर अभी के लिए मेरी आवश्यकताओं के अनुरूप है। यहाँ डेमो हैl ≈ r + r * PI*0.1 * pow(α/90, 2)PI*0.1


इस छवि को बनाने के लिए आप किस सॉफ्टवेयर का उपयोग करते हैं do
कियान सिजिहानो

1
मेरे डेमो + मैथ राइटिंग पैनल से स्क्रीनशॉट (या नाम का अनुवाद किया गया है) 7 + MS पेंट से जीतें
Paweł Audionysos

0

इस एक को मृत से वापस लाने के लिए क्षमा करें, लेकिन मुझे यह पोस्ट इस पृष्ठ के साथ-साथ एक विस्तार योग्य सूत्र के साथ आने में बहुत उपयोगी लगी।

मूल रूप से, आप एक अविश्वसनीय रूप से सरल सूत्र का उपयोग करके एक निकट सर्कल बना सकते हैं जो आपको 4 से अधिक किसी भी बेज़ियर वक्र का उपयोग करने की अनुमति देता है: Distance = radius * stepAngle / 3

जहां Distanceएक बेज़ियर नियंत्रण बिंदु और चाप के निकटतम छोर के बीच की दूरी, त्रिज्या radiusसर्कल का है, और stepAngleचाप के 2 छोरों के बीच का कोण है जैसा कि 2π / (घटता की संख्या) द्वारा दर्शाया गया है।

इसलिए इसे एक शॉट में मारने के लिए: Distance = radius * 2π / (the number of curves) / 3


1
यह एक वृत्त का सबसे अच्छा सन्निकटन नहीं है। सबसे अच्छा एक है Distance = (4/3)*tan(pi/2n)। बड़ी संख्या में आर्क्स के लिए यह लगभग समान है tan(pi/2)~pi/2n, लेकिन उदाहरण के लिए n=4(जो कि सबसे अधिक इस्तेमाल किया जाने वाला मामला है) आपका सूत्र देता है, Distance=0.5235...लेकिन इष्टतम एक है Distance=0.5522... (इसलिए आपके पास ~ 5% त्रुटि है)।
Kpym

-2

यह एक भारी सन्निकटन है जो संकल्प और सटीकता के आधार पर उचित या भयानक लगेगा लेकिन मैं अपने नियंत्रण बिंदुओं के रूप में sqrt (2) / 2 x त्रिज्या का उपयोग करता हूं। मैं एक लंबा पाठ पढ़ता हूं कि यह संख्या कैसे निकाली गई है और यह पढ़ने लायक है, लेकिन ऊपर दिया गया सूत्र त्वरित और गंदा है।

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