เรามีจุดเริ่มต้น (x, y) และรัศมีวงกลม นอกจากนี้ยังมีเครื่องยนต์ที่สามารถสร้างเส้นทางจากจุดโค้งBézier
ฉันจะสร้างวงกลมโดยใช้เส้นโค้งเบเซียร์ได้อย่างไร
เรามีจุดเริ่มต้น (x, y) และรัศมีวงกลม นอกจากนี้ยังมีเครื่องยนต์ที่สามารถสร้างเส้นทางจากจุดโค้งBézier
ฉันจะสร้างวงกลมโดยใช้เส้นโค้งเบเซียร์ได้อย่างไร
คำตอบ:
ดังที่ได้กล่าวไปแล้ว: ไม่มีการแสดงวงกลมโดยใช้เส้นโค้งเบเซียร์อย่างแน่นอน
ให้เสร็จสมบูรณ์คำตอบอื่น ๆ : สำหรับโค้ง Bezier กับn
กลุ่มที่ดีที่สุด(4/3)*tan(pi/(2n))
ระยะทางไปยังจุดควบคุมในความรู้สึกที่ตรงกลางของเส้นโค้งการโกหกในวงกลมที่ตัวเองเป็น
ดังนั้นสำหรับ 4 (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831
จุดที่มันเป็น
ครอบคลุมใน comp.graphics.faq
เรื่อง 4.04: ฉันจะปรับเส้นโค้งเบเซียร์ให้เป็นวงกลมได้อย่างไร
ที่น่าสนใจก็คือเส้นโค้ง Bezier สามารถประมาณวงกลมได้ แต่ไม่พอดีกับวงกลม การประมาณโดยทั่วไปคือการใช้ beziers สี่ตัวเพื่อสร้างแบบจำลองวงกลมโดยแต่ละจุดควบคุมมีระยะทาง d = r * 4 * (sqrt (2) -1) / 3 จากจุดสิ้นสุด (โดยที่ r คือรัศมีวงกลม) และใน ทิศทางแทนเจนต์ไปยังวงกลมที่จุดสิ้นสุด เพื่อให้แน่ใจว่าจุดกึ่งกลางของ Beziers อยู่บนวงกลมและอนุพันธ์แรกนั้นต่อเนื่องกัน
ความคลาดเคลื่อนของรัศมีในการประมาณนี้จะอยู่ที่ประมาณ 0.0273% ของรัศมีของวงกลม
Michael Goldapp "การประมาณส่วนโค้งวงกลมโดยพหุนามลูกบาศก์" การออกแบบทางเรขาคณิตโดยใช้คอมพิวเตอร์ช่วย (# 8 1991 pp.227-238)
Tor Dokken และ Morten Daehlen, "การประมาณที่ดีของวงกลมโดยเส้นโค้ง Bezier ที่มีความโค้งต่อเนื่อง" Computer Aided Geometric Design (# 7 1990 pp. 33-41) http://www.sciencedirect.com/science/article/pii/016783969090019N (ไม่ใช่บทความฟรี)
ดูบทความที่ไม่ใช่ paywalled ได้ที่http://spencermortensen.com/articles/bezier-circle/
โปรดทราบว่าเบราว์เซอร์บางตัวใช้เส้นโค้ง Bezier กับส่วนโค้งการวาดผ้าใบของตน Chrome ใช้ (ในปัจจุบัน) วิธีการ 4 ภาคส่วน Safari ใช้วิธีการ 8 ภาคส่วนความแตกต่างจะสังเกตเห็นได้เฉพาะที่ความละเอียดสูงเท่านั้นเนื่องจาก 0.0273% และยัง มองเห็นได้อย่างแท้จริงก็ต่อเมื่อส่วนโค้งถูกวาดในแนวขนานและอยู่นอกเฟสคุณจะสังเกตเห็นส่วนโค้งที่แกว่งจากวงกลมจริง นอกจากนี้เอฟเฟกต์ยังสังเกตเห็นได้ชัดเจนยิ่งขึ้นเมื่อเส้นโค้งเคลื่อนไหวรอบ ๆ ศูนย์กลางรัศมีโดยปกติแล้วรัศมี 600px จะเป็นขนาดที่จะสร้างความแตกต่าง
API การวาดภาพบางตัวไม่มีการเรนเดอร์ส่วนโค้งจริงดังนั้นจึงใช้เส้นโค้ง Bezier เช่นแพลตฟอร์ม Flash ไม่มี API การวาดส่วนโค้งดังนั้นเฟรมเวิร์กใด ๆ ที่มีส่วนโค้งโดยทั่วไปจะใช้วิธีเส้นโค้ง Bezier เดียวกัน
โปรดทราบว่าเอ็นจิ้น SVG ภายในเบราว์เซอร์อาจใช้วิธีการวาดที่แตกต่างกัน
ไม่ว่าคุณจะพยายามใช้แพลตฟอร์มใดก็ตามคุณควรตรวจสอบเพื่อดูว่าการวาดส่วนโค้งเสร็จสิ้นอย่างไรดังนั้นคุณสามารถคาดเดาข้อผิดพลาดทางสายตาเช่นนี้และปรับเปลี่ยนได้
คำตอบของคำถามนั้นดีมากจึงมีอะไรให้เพิ่มเติมเล็กน้อย โดยได้รับแรงบันดาลใจจากการที่ฉันเริ่มทำการทดลองเพื่อยืนยันการแก้ปัญหาด้วยสายตาโดยเริ่มจากเส้นโค้งเบเซียร์สี่เส้นโดยลดจำนวนเส้นโค้งให้เหลือหนึ่งเส้น น่าประหลาดใจที่ฉันพบว่ามีเส้นโค้งเบเซียร์สามเส้นทำให้วงกลมนั้นดูดีพอสำหรับฉัน แต่การก่อสร้างนั้นค่อนข้างยุ่งยาก จริงๆแล้วฉันใช้ Inkscape เพื่อวางค่าประมาณBézierสีดำกว้าง 1 พิกเซลบนวงกลมสีแดงกว้าง 3 พิกเซล (ผลิตโดย Inkscape) เพื่อความกระจ่างฉันได้เพิ่มเส้นสีน้ำเงินและพื้นผิวที่แสดงกรอบขอบของเส้นโค้งเบเซียร์
เพื่อดูตัวเองฉันกำลังนำเสนอผลลัพธ์ของฉัน:
กราฟ 1 เส้นโค้ง (ซึ่งดูเหมือนว่ามีการลดลงที่มุมเพียงเพื่อความสมบูรณ์):
(ฉันต้องการใส่ SVG หรือ PDF ที่นี่ แต่ไม่รองรับ)
มีคำตอบมากมายแล้ว แต่ฉันพบบทความออนไลน์ขนาดเล็กที่มีค่าประมาณของวงกลมลูกบาศก์ที่ดีมาก ในแง่ของวงกลมหน่วย c = 0.55191502449 โดยที่ c คือระยะห่างจากจุดตัดแกนตามเส้นสัมผัสไปยังจุดควบคุม
เป็นรูปสี่เหลี่ยมเดียวสำหรับวงกลมหน่วยที่มีพิกัดกลางสองจุดเป็นจุดควบคุม (0,1),(c,1),(1,c),(1,0)
ข้อผิดพลาดในแนวรัศมีเป็นเพียง 0.019608% ดังนั้นฉันจึงต้องเพิ่มลงในรายการคำตอบนี้
สามารถอ่านบทความได้ที่นี่โดยประมาณวงกลมที่มีเส้นโค้งลูกบาศก์เบซิเอร์
มันเป็นไปไม่ได้. Bezier คือลูกบาศก์ (อย่างน้อย ... ที่ใช้กันมากที่สุดคือ) วงกลมไม่สามารถแสดงด้วยลูกบาศก์ได้อย่างแน่นอนเนื่องจากวงกลมมีรากที่สองในสมการ ดังนั้นคุณต้องประมาณ
ในการทำเช่นนี้คุณต้องแบ่งวงกลมของคุณเป็น n-tants (egquadrants, octants) สำหรับแต่ละ n-t คุณใช้จุดแรกและจุดสุดท้ายเป็นจุดแรกและจุดสุดท้ายของเส้นโค้ง Bezier รูปหลายเหลี่ยม Bezier ต้องการจุดเพิ่มเติมสองจุด เพื่อให้เร็วฉันจะนำเส้นสัมผัสไปยังวงกลมสำหรับจุดสุดขั้วแต่ละจุดของ n-tant และเลือกจุดสองจุดเป็นจุดตัดของเส้นสัมผัสทั้งสอง (เพื่อให้โดยพื้นฐานแล้วรูปหลายเหลี่ยม Bezier ของคุณเป็นรูปสามเหลี่ยม) เพิ่มจำนวน n-tants ให้พอดีกับความแม่นยำของคุณ
คำตอบอื่น ๆ ครอบคลุมความจริงที่ว่าวงกลมที่แท้จริงเป็นไปไม่ได้ ไฟล์ SVG นี้เป็นการประมาณโดยใช้เส้นโค้ง Quadratic Bezier และเป็นสิ่งที่ใกล้เคียงที่สุดที่คุณจะได้รับ: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg
นี่คือเส้นโค้ง Cubic Bezier: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg
สำหรับผู้ที่กำลังมองหาโค้ด:
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>
ช่วยให้สามารถวาดวงกลมที่สร้างจากเส้นโค้ง Bezier 4 เส้น เขียนด้วย JS แต่สามารถแปลเป็นภาษาอื่นได้อย่างง่ายดาย
อย่าใช้เส้นโค้ง Bezier หากคุณต้องการวาดวงกลมโดยใช้เส้นทาง SVG เว้นแต่จะต้องทำเช่นนั้น ในเส้นทางคุณสามารถใช้Arc
เพื่อสร้างครึ่งวงกลม 2 วง
ฉันไม่แน่ใจว่าควรเปิดคำถามใหม่หรือไม่เนื่องจากเป็นเรื่องเกี่ยวกับการประมาณค่าประมาณ แต่ฉันสนใจในสูตรทั่วไปเพื่อรับคะแนนควบคุมสำหรับ Bezier ในทุกระดับและฉันเชื่อว่ามันเข้ากับคำถามนี้ วิธีแก้ปัญหาทั้งหมดที่ฉันพบบนเว็บมีไว้สำหรับเส้นโค้งลูกบาศก์เท่านั้นหรือได้รับเงินหรือฉันไม่เข้าใจด้วยซ้ำ (ฉันไม่ค่อยเก่งคณิตศาสตร์) ดังนั้นฉันจึงตัดสินใจลองแก้ปัญหานี้ด้วยตัวเอง ฉันศึกษาระยะทางของจุดควบคุมจากศูนย์กลางของวงกลมโดยขึ้นอยู่กับมุมที่กำหนดและจนถึงตอนนี้ฉันพบว่า:
ที่ไหนN
คือจำนวนของจุดควบคุมโค้งเดียวและα
เป็นมุมโค้งวงกลม
สำหรับเส้นโค้งกำลังสองสามารถทำให้ง่ายขึ้นเป็นl ≈ r + r * PI*0.1 * pow(α/90, 2)
The PI*0.1
ค่อนข้างเดาได้ - ฉันไม่ได้คำนวณค่าที่สมบูรณ์แบบ แต่มันค่อนข้างใกล้เคียง สิ่งนี้ทำงานได้ดีพอสมควรสำหรับเส้นโค้งโดยมีจุดควบคุม 1-2 จุดที่ให้รัศมีคลาดเคลื่อนประมาณ 0.2% สำหรับเส้นโค้งลูกบาศก์ สำหรับเส้นโค้งระดับที่สูงขึ้นจะสูญเสียความแม่นยำ ด้วยเส้นโค้งจุดควบคุม 3 จุดมีลักษณะคล้ายกับกำลังสองดังนั้นเห็นได้ชัดว่าฉันพลาดอะไรบางอย่าง แต่ฉันคิดไม่ออกและวิธีนี้มักจะเหมาะกับความต้องการของฉันในตอนนี้ นี่คือการสาธิต
ขออภัยที่นำอันนี้กลับมาจากความตาย แต่ฉันพบว่าโพสต์นี้มีประโยชน์มากพร้อมกับหน้านี้ในการสร้างสูตรที่ขยายได้
โดยทั่วไปคุณสามารถสร้างวงกลมใกล้โดยใช้สูตรง่ายๆอย่างไม่น่าเชื่อที่ให้คุณใช้เส้นโค้ง Bezier จำนวนเท่าใดก็ได้มากกว่า 4: Distance = radius * stepAngle / 3
Distance
ระยะห่างระหว่างจุดควบคุม Bezier และจุดสิ้นสุดที่ใกล้ที่สุดของส่วนโค้งอยู่ที่ไหนรัศมีคือradius
วงกลมและstepAngle
เป็นมุมระหว่างปลายทั้ง 2 ของส่วนโค้งซึ่งแสดงด้วย2π / (จำนวนเส้นโค้ง)
ดังนั้นการตีในนัดเดียว: Distance = radius * 2π / (the number of curves) / 3
Distance = (4/3)*tan(pi/2n)
ที่ดีที่สุดคือ สำหรับส่วนโค้งจำนวนมากมันเกือบจะเท่ากันเพราะtan(pi/2)~pi/2n
แต่ตัวอย่างเช่นn=4
(ซึ่งเป็นกรณีที่ใช้บ่อยที่สุด) สูตรของคุณให้Distance=0.5235...
แต่ค่าที่ดีที่สุดคือDistance=0.5522...
(คุณมีข้อผิดพลาด ~ 5%)
มันเป็นการประมาณที่หนักซึ่งจะดูสมเหตุสมผลหรือแย่มากขึ้นอยู่กับความละเอียดและความแม่นยำ แต่ฉันใช้รัศมี sqrt (2) / 2 xเป็นจุดควบคุมของฉัน ฉันอ่านข้อความที่ค่อนข้างยาวว่าตัวเลขนั้นได้มาอย่างไรและมันก็คุ้มค่าที่จะอ่าน แต่สูตรข้างต้นเป็นวิธีที่รวดเร็วและสกปรก