2012-01-03 13 views
6

मैं एक ऐसा एप्लीकेशन विकसित कर रहा हूं जहां उपयोगकर्ता HTML5 कैनवास पर यूक्लिडियन निर्माण आकर्षित करते हैं। इस तरह मैं वास्तव में कुछ आकारों के आकार को सीमित नहीं कर सकता। स्क्रीन पर खींची जाने वाली बहुत बड़ी सर्किलों का अपहरण करते समय मैंने देखा कि बहुत बड़ी सर्किलों में निरंतर त्रिज्या नहीं है।बहुत बड़ा एचटीएमएल 5 कैनवास सर्कल अपर्याप्त

अधिक विशिष्ट होने के लिए, दो बिंदुओं द्वारा परिभाषित एक सर्कल, एक केंद्र बिंदु और त्रिज्या निर्दिष्ट करने वाला कोई त्रिज्या बिंदु से गुजरता नहीं है!

Large circle with radius point

progressivly बड़ा हलकों। ये सभी ई

Larger circles

त्रुटि बिंदु के माध्यम से पारित करने के लिए 45 डिग्री = पीआई/4 के गुणकों पर occure नहीं करता अपेक्षा की जाती है।

http://jsfiddle.net/D28J2/2/

मेरे सवालों का:: क्यों इस occure करता है इन गुणकों के बीच त्रुटि यहाँ एक jsfiddle ऊपर पहला उदाहरण युक्त है सबसे बड़ी (पीआई/8 उदाहरण के लिए)

है? और क्या इस के आसपास काम करने के लिए कुछ प्रभावशाली तरीका है?

+1

क्रोम 16.0.912.63 पर मैकोज़ एक्स 10.7.2 पर आपके fiddle _touches_ में सर्कल लेकिन आवश्यक बिंदु से गुजरता नहीं है। – Alnitak

+1

दिलचस्प, क्रोम 16.0.912.63 विंडोज 7 पर रास्ते पर। लिनक्स पर क्रोम पर भी यह समस्या आई। फ़ायरफ़ॉक्स पर विंडोज 7 एक ही त्रुटि होती है लेकिन परिमाण छोटा होता है (केवल जब आर = 100 000 यह ध्यान देने योग्य है)। आईई 9 पर त्रुटि भी छोटी है (आर = 1 000 000 पर ध्यान देने योग्य)। इन सभी परीक्षणों को अल्फा = पीआई/8 –

उत्तर

3

जिस तरह से मैंने इस मुद्दे के आसपास काम किया, वह पूरी तरह से बेजियर वक्र के साथ एक सर्कल ड्रॉ सन्निकटन के अपने कार्यान्वयन को रोल करता था। कार्यान्वयन का विवरण देने वाला एक लेख यहां http://www.tinaja.com/glib/ellipse4.pdf पाया जा सकता है।

function magic_circle(ctx, x, y, r){ 
    m = 0.551784 

    ctx.save() 
    ctx.translate(x, y) 
    ctx.scale(r, r) 

    ctx.beginPath() 
    ctx.moveTo(1, 0) 
    ctx.bezierCurveTo(1, -m, m, -1, 0, -1) 
    ctx.bezierCurveTo(-m, -1, -1, -m, -1, 0) 
    ctx.bezierCurveTo(-1, m, -m, 1, 0, 1) 
    ctx.bezierCurveTo(m, 1, 1, m, 1, 0) 
    ctx.closePath() 
    ctx.restore() 
} 

बस इन चार segements के साथ मैं काफी बेहतर तो गूगल क्रोम कैनवास कार्यान्वयन में निर्माण एक चक्र अनुमान लगाने के लिए सक्षम था।

+1

यह केवल सर्कल ड्राइंग के लिए डिफ़ॉल्ट आर्क() विधि से बेहतर तरीका है। मैंने इसके साथ CanvasRenderingContext2D.prototype.arc को प्रतिस्थापित किया और यह सभी प्रकार के अजीब कलाकृतियों और गड़बड़ी को ठीक कर दिया। – mclaassen

0

Google क्रोम में मैं इस मुद्दे को दोहरा सकता हूं लेकिन आईई 9 और आईई 10 में सब ठीक है।

तो मेरा अनुमान है कि क्रोम में कार्यान्वयन गलत है। यह एक गोल करने वाली त्रुटि हो सकती है या उन्होंने पाप और कोस से बचने के लिए एक इंटरपोलेशन विधि का उपयोग किया जो बहुत सटीक नहीं है।

यहाँ देखो के रूप में अच्छी: HTML5 canvas arcs not rendering correctly in Google Chrome

केवल काम के आसपास मैं कल्पना कर सकते हैं अपने खुद के कोड से सर्कल ड्राइंग या एक (jQuery?) का उपयोग प्लग में है कि आप के लिए यह करता है।

2

यह शायद एक फ़्लोटिंग पॉइंट कटऑफ त्रुटि है। संभवतः क्योंकि साइन और कोसाइन पूरी तरह से सटीक मूल्य नहीं दे रहे हैं। चाप के बजाय कैनवास घूर्णन करके आप इसे चारों ओर (क्रोम में कम से कम) प्राप्त कर सकते हैं।

ctx.save();   // Save the canvas so we can rotate back. 
ctx.translate(x, y); // Translate to the origin point. 
ctx.rotate(alpha); // Rotate the proper angle. 

ctx.arc(0, 0, 3, 0, Math.PI*2); // Draw the small circle at the origin. 
ctx.fill(); 

ctx.arc(r, 0, r, 0, Math.PI*2); // Create a big with the origin 1 radius away. 
ctx.restore();     // Restore the canvas to the original orientation 
           // before drawing. Otherwise the circle looks bad. 
ctx.strokeStyle = "black"; 
ctx.stroke();     // Draw! 

मैं आकृतियों के बजाय कैनवास में हेरफेर करने का एक बड़ा प्रशंसक हूं। यह आपको काम करने के लिए एक और तार्किक क्षेत्र देता है। देखें http://jsfiddle.net/D28J2/10/

+1

वाह के साथ पूर्ववत किया गया है वाह वास्तव में अच्छा है! हालांकि यह मेरी समस्या को बिल्कुल ठीक नहीं करता है। मुझे मंडल को हर जगह 'बिल्कुल सही' होने की ज़रूरत है, केवल कुछ मनमानी बिंदु नहीं। –

+0

सर्कल हर जगह सही होना चाहिए। समस्या सर्कल के त्रिज्या के साथ नहीं थी, लेकिन बड़े पैमाने पर गुणा होने पर 'Math.sin' और' Math.cos' के गणितीय अपर्याप्त होने के साथ अतिरंजित किया गया था। उस ने कहा, आपको मूल विधि का उपयोग करके किसी भी बिंदु को रखने में कोई समस्या होगी, इसलिए यदि आप x + 2 * cos (a), y + 2 * sin (a) पर दूसरा बिंदु रखते हैं तो यह लाइन नहीं होगा। वास्तव में सटीक ग्राफ के लिए, आपको घुमावदार कैनवास पर सभी ड्राइंग करने की आवश्यकता है। –

+1

समस्या यह है कि 'Math.cos' और' Math.sin' को V8 में कुछ टेलर श्रृंखला द्वारा कार्यान्वित किया जाता है। अनुकूलन उद्देश्यों के लिए ये टेलर श्रृंखला बहुत अधिक क्रम नहीं है इसलिए बहुत बड़ी सर्कल ड्राइंग करते समय त्रुटियां होती हैं। –

1

बस इसे बाहर फेंक दिया लेकिन क्या यह पीआई के पर्याप्त अंक निर्दिष्ट किए बिना एक मुद्दा हो सकता है? जब भी मैं ऐसी चीजें करता हूं, मैं थोड़ी अधिक मात्रा में जाता हूं और पीआई के लगभग 10 अंकों का उपयोग करता हूं।

संबंधित मुद्दे