Câu trả lời:
Như đã nói: không có biểu diễn chính xác của vòng tròn bằng cách sử dụng các đường cong Bezier.
Để hoàn thành các câu trả lời khác: đối với đường cong Bezier với n
các phân đoạn khoảng cách tối ưu đến các điểm kiểm soát, theo nghĩa là giữa đường cong nằm trên chính đường tròn, là (4/3)*tan(pi/(2n))
.
Vì vậy, cho 4 điểm nó là (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831
.
Được đề cập trong comp.graphics.faq
Chủ đề 4.04: Làm cách nào để ghép một đường cong Bezier vào một đường tròn?
Điều thú vị là các đường cong Bezier có thể xấp xỉ một vòng tròn nhưng không hoàn toàn phù hợp với một vòng tròn. Một phép gần đúng phổ biến là sử dụng bốn beziers để mô hình hóa một vòng tròn, mỗi beziers có các điểm điều khiển cách các điểm cuối một khoảng d = r * 4 * (sqrt (2) -1) / 3 (trong đó r là bán kính vòng tròn), và trong một phương tiếp tuyến với đường tròn tại các điểm cuối. Điều này sẽ đảm bảo các điểm giữa của Beziers nằm trên đường tròn và đạo hàm cấp một là liên tục.
Sai số xuyên tâm trong phép tính gần đúng này sẽ là khoảng 0,0273% bán kính của vòng tròn.
Michael Goldapp, "Tính gần đúng của cung tròn bằng đa thức khối" Thiết kế Hình học có Sự hỗ trợ của Máy tính (# 8 1991 trang.227-238)
Tor Dokken và Morten Daehlen, "Phương pháp gần đúng của đường tròn bằng đường cong Bezier liên tục độ cong" Thiết kế Hình học có Sự hỗ trợ của Máy tính (# 7 1990 trang 33-41). http://www.sciasedirect.com/science/article/pii/016783969090019N (bài viết không miễn phí)
Ngoài ra, hãy xem bài viết không có tường phí tại http://spencermortensen.com/articles/bezier-circle/
Lưu ý rằng một số trình duyệt sử dụng đường cong Bezier cho vòng cung vẽ canvas của họ, Chrome sử dụng (tại thời điểm hiện tại) cách tiếp cận 4 khu vực và Safari sử dụng phương pháp tiếp cận 8 khu vực, sự khác biệt chỉ đáng chú ý ở độ phân giải cao, vì 0,0273% đó, và cũng chỉ thực sự hiển thị khi các cung được vẽ song song và lệch pha nhau, bạn sẽ nhận thấy các cung dao động từ một vòng tròn thực. Hiệu ứng này cũng đáng chú ý hơn khi đường cong hoạt động xung quanh tâm xuyên tâm của nó, bán kính 600px thường là kích thước mà nó sẽ tạo ra sự khác biệt.
Một số API vẽ nhất định không có kết xuất vòng cung thực sự, vì vậy chúng cũng sử dụng các đường cong Bezier, ví dụ: nền tảng Flash không có api vẽ vòng cung, vì vậy bất kỳ khung công tác nào cung cấp cung cấp thường sử dụng cùng một cách tiếp cận đường cong Bezier.
Lưu ý rằng công cụ SVG trong trình duyệt có thể sử dụng một phương pháp vẽ khác.
Dù bạn đang cố gắng sử dụng nền tảng nào, bạn cũng nên kiểm tra xem cách vẽ vòng cung được thực hiện như thế nào, vì vậy bạn có thể dự đoán các lỗi trực quan như thế này và điều chỉnh.
Các câu trả lời cho câu hỏi là rất tốt, vì vậy có rất ít để bổ sung. Lấy cảm hứng từ điều đó, tôi bắt đầu thực hiện một thí nghiệm để xác nhận trực quan giải pháp, bắt đầu với bốn đường cong Bézier, giảm số đường cong xuống còn một. Thật ngạc nhiên khi tôi phát hiện ra rằng với ba đường cong Bézier, hình tròn trông đủ đẹp đối với tôi, nhưng việc xây dựng hơi phức tạp. Trên thực tế, tôi đã sử dụng Inkscape để đặt xấp xỉ Bézier rộng 1 pixel màu đen trên một vòng tròn rộng 3 pixel màu đỏ (do Inkscape sản xuất). Để làm rõ hơn, tôi đã thêm các đường và bề mặt màu xanh lam hiển thị các hộp giới hạn của các đường cong Bézier.
Để xem chính bạn, tôi đang trình bày kết quả của mình:
Biểu đồ 1 đường cong (trông giống như một giọt nước bị ép ở một góc, chỉ để hoàn thiện):
(Tôi muốn đặt SVG hoặc PDF ở đây, nhưng điều đó không được hỗ trợ)
Đã có nhiều câu trả lời nhưng tôi đã tìm thấy một bài báo trực tuyến nhỏ với cách tính gần đúng khối vuông góc của một đường tròn. Theo đường tròn đơn vị c = 0,55191502449 trong đó c là khoảng cách từ các điểm chặn trục dọc theo các tiếp tuyến đến các điểm kiểm soát.
Là một góc phần tư duy nhất cho vòng tròn đơn vị với hai tọa độ giữa là các điểm kiểm soát. (0,1),(c,1),(1,c),(1,0)
Sai số xuyên tâm chỉ là 0,019608% vì vậy tôi chỉ cần thêm nó vào danh sách các câu trả lời này.
Bài viết có thể được tìm thấy tại đây Tính gần đúng một đường tròn với các đường cong Bézier lập phương
Điều đó là không thể. Bezier là một hình khối (ít nhất là ... thông dụng nhất là). Một hình tròn không thể được biểu diễn chính xác bằng một hình khối, bởi vì một hình tròn chứa một căn bậc hai trong phương trình của nó. Do đó, bạn phải tính gần đúng.
Để làm điều này, bạn phải chia vòng kết nối của mình theo n-tants (ví dụ: dãy số, số bát phân). Đối với mỗi n-tant, bạn sử dụng điểm đầu tiên và điểm cuối cùng làm điểm đầu tiên và điểm cuối cùng của đường cong Bezier. Đa giác Bezier yêu cầu hai điểm bổ sung. Để nhanh chóng, tôi sẽ lấy các tiếp tuyến của đường tròn cho mỗi điểm cực trị của n-tant và chọn hai điểm làm giao điểm của hai tiếp tuyến (về cơ bản đa giác Bezier của bạn là một tam giác). Tăng số lượng quần lót n để phù hợp với độ chính xác của bạn.
Các câu trả lời khác đã che đậy thực tế rằng một vòng tròn thực sự là không thể. Tệp SVG này là một xấp xỉ sử dụng đường cong Bezier bậc hai và là thứ gần nhất mà bạn có thể nhận được: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg
Đây là một trong những đường cong Bezier khối: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg
Đối với những người chỉ đang tìm kiếm mã:
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>
Điều này cho phép vẽ vòng tròn được tạo ra từ 4 đường cong Bezier. Được viết bằng JS nhưng có thể dễ dàng dịch sang bất kỳ ngôn ngữ nào khác
Tôi không chắc mình có nên mở câu hỏi mới không vì đây là về khoảng cách gần nhưng tôi quan tâm đến công thức chung để lấy điểm kiểm soát cho Bezier ở bất kỳ mức độ nào và tôi tin rằng nó phù hợp với câu hỏi này. Tất cả các giải pháp tôi tìm thấy trên web chỉ dành cho đường cong khối hoặc được trả tiền hoặc thậm chí tôi không hiểu (tôi không giỏi toán lắm). Vì vậy, tôi quyết định cố gắng giải quyết vấn đề này một mình. Tôi đã nghiên cứu khoảng cách của điểm điều khiển từ tâm của một vòng tròn phụ thuộc vào góc đã cho và cho đến nay tôi thấy rằng:
Đâu N
là số điểm kiểm soát cho đường cong đơn và α
là góc cung tròn.
Đối với đường cong bậc hai, nó có thể được đơn giản hóa thành l ≈ r + r * PI*0.1 * pow(α/90, 2)
The PI*0.1
là một dự đoán - Tôi không tính được giá trị hoàn hảo nhưng nó khá gần. Điều này hoạt động hợp lý cho đường cong với 1-2 điểm kiểm soát cho sai số bán kính khoảng 0,2% cho đường cong hình khối. Đối với các đường cong mức độ cao hơn, sự mất độ chính xác là điều đáng chú ý. Với 3 điểm điều khiển, đường cong trông tương tự như bậc hai nên rõ ràng tôi đang bỏ lỡ điều gì đó nhưng tôi không thể tìm ra và phương pháp này nói chung phù hợp với nhu cầu của tôi lúc này. Đây là bản demo .
Xin lỗi vì đã mang lại điều này một trở lại từ cõi chết, nhưng tôi tìm thấy bài viết này rất hữu ích cùng với này trang trong đến với một công thức có thể mở rộng.
Về cơ bản, bạn có thể tạo một vòng tròn gần bằng một công thức cực kỳ đơn giản cho phép bạn sử dụng bất kỳ số lượng đường cong Bezier nào trên 4: Distance = radius * stepAngle / 3
Đâu Distance
là khoảng cách giữa điểm điều khiển Bezier và điểm cuối gần nhất của cung tròn, bán kính là radius
đường tròn vàstepAngle
là góc giữa 2 đầu của cung được biểu diễn bằng 2π / (số đường cong).
Vì vậy, để đạt được nó trong một lần: Distance = radius * 2π / (the number of curves) / 3
Distance = (4/3)*tan(pi/2n)
. Đối với số lượng cung lớn, nó gần như giống nhau bởi vì tan(pi/2)~pi/2n
, nhưng ví dụ đối với n=4
(trường hợp được sử dụng nhiều nhất) công thức của bạn đưa ra Distance=0.5235...
nhưng công thức tối ưu là Distance=0.5522...
(vì vậy bạn có sai số ~ 5%).
Đó là một ước tính nặng trông hợp lý hoặc khủng khiếp tùy thuộc vào độ phân giải và độ chính xác nhưng tôi sử dụng sqrt (2) / 2 x radius làm điểm kiểm soát của mình. Tôi đã đọc một văn bản khá dài về cách con số đó được bắt nguồn và nó đáng đọc nhưng công thức ở trên là nhanh và bẩn.