2012-01-03 55 views
6

Tôi đang phát triển một ứng dụng nơi người dùng vẽ các cấu trúc euclide trên canvas HTML5. Vì vậy tôi không thể giới hạn kích thước của một số hình dạng nhất định. Khi exaploring vòng tròn rất lớn được vẽ trên màn hình, tôi nhận thấy rằng các vòng tròn rất lớn không có bán kính không đổi.Rất lớn vòng tròn canvas HTML5 không chính xác

Để cụ thể hơn, một vòng tròn được xác định bởi hai điểm, một điểm trung tâm và một chỉ định bán kính không đi qua điểm bán kính nữa!

Large circle with radius point

Vòng tròn lớn hơn nữa. Đây là tất cả phải đi qua điểm E.

Larger circles

Lỗi không occure về bội số của 45 độ = PI/4. Giữa các bội số lỗi là lớn nhất (PI/8 chẳng hạn)

Dưới đây là một jsfiddle chứa ví dụ đầu tiên ở trên:

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

Câu hỏi của tôi: Tại sao occure này? và Có một số cách để (hiệu quả) làm việc xung quanh này?

+1

trên Chrome 16.0.912.63 trên MacOS X 10.7.2 vòng tròn trong fiddle _touches_ của bạn nhưng không vượt qua điểm bắt buộc. – Alnitak

+1

Thú vị, im trên Chrome 16.0.912.63 Windows 7 bằng cách này. Sự cố này cũng xảy ra trên Chrome trên Linux. Trên Firefox Windows 7 cùng một lỗi xảy ra nhưng là một đơn đặt hàng của cường độ nhỏ hơn (chỉ khi r = 100 000 là nó đáng chú ý). Trên IE 9, lỗi thậm chí còn nhỏ hơn (đáng chú ý tại r = 1 000 000). Tất cả các thử nghiệm này được tạo sẵn với alpha = PI/8 –

Trả lời

3

Cách tôi làm việc xung quanh vấn đề này hoàn toàn là cuộn thực hiện của riêng tôi về một vòng tròn vẽ xấp xỉ với đường cong bezier. Bạn có thể tìm thấy bài viết chi tiết về việc triển khai tại đây 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() 
} 

Chỉ với bốn phân đoạn này, tôi có thể ước chừng vòng tròn tốt hơn nhiều khi xây dựng trong triển khai canvas google chrome.

+1

Đây là cách tốt hơn so với phương thức arc() mặc định để chỉ vẽ vòng tròn. Tôi đã thay thế CanvasRenderingContext2D.prototype.arc bằng cách này và nó đã sửa tất cả các loại tạo tác kỳ lạ và trục trặc. – mclaassen

0

Trong Google chrome tôi có thể lặp lại vấn đề nhưng trong IE 9 và IE 10 tất cả đều ổn.

Vì vậy, tôi đoán là triển khai không đúng trong Chrome. Nó có thể là một lỗi làm tròn hoặc họ sử dụng một phương pháp nội suy để tránh tội lỗi và cos mà không phải là rất chính xác.

Look đây cũng như: HTML5 canvas arcs not rendering correctly in Google Chrome

Công việc duy nhất xung quanh tôi có thể tưởng tượng được vẽ hình tròn bằng mã riêng của bạn hoặc sử dụng một (jQuery?) Plug-in mà thực hiện điều này cho bạn.

2

Đây có thể là lỗi ngắt điểm nổi. Có thể vì sin và cosin không đưa ra giá trị hoàn toàn chính xác. Bạn có thể sử dụng nó (ít nhất trong Chrome) bằng cách xoay canvas thay vì hình cung.

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! 

Tôi là một người hâm mộ lớn thao túng khung hình thay vì hình dạng. Nó cung cấp cho bạn một khu vực hợp lý hơn để làm việc. Xem http://jsfiddle.net/D28J2/10/

+1

Thật tuyệt vời! Tuy nhiên điều đó không chính xác khắc phục vấn đề của tôi. Tôi cần vòng tròn là 'hoàn hảo' ở khắp mọi nơi, không chỉ là một số điểm tùy ý. –

+0

Vòng tròn phải hoàn hảo ở mọi nơi. Vấn đề có thể không có bán kính của vòng tròn nhưng với sự thiếu chính xác toán học của 'Math.sin' và' Math.cos' được phóng đại khi nhân với một hằng số lớn. Điều đó nói rằng, bạn sẽ có một vấn đề đặt bất kỳ điểm nào bằng cách sử dụng phương pháp ban đầu, vì vậy nếu bạn đặt một điểm thứ hai tại x + 2 * cos (a), y + 2 * sin (a) nó sẽ không xếp hàng. Để có biểu đồ thực sự chính xác, bạn cần thực hiện tất cả bản vẽ trên canvas được xoay. –

+1

Vấn đề là 'Math.cos' và' Math.sin' được thực hiện bởi một số chuỗi taylor trong V8. Vì mục đích tối ưu hóa, các chuỗi taylor này không phải là thứ tự rất cao do đó khi vẽ các vòng tròn rất lớn có lỗi. –

1

Chỉ cần ném điều này ra khỏi đó nhưng nó có thể là một vấn đề mà không chỉ định đủ số PI? Bất cứ khi nào tôi làm những việc như thế, tôi có xu hướng hơi bị quá tải và sử dụng khoảng 10 chữ số PI.

Các vấn đề liên quan