Bir başlangıç noktamız (x, y) ve bir daire yarıçapımız var. Bézier eğri noktalarından bir yol oluşturabilen bir motor da vardır.
Bézier eğrilerini kullanarak nasıl daire oluşturabilirim?
Yanıtlar:
Daha önce de belirtildiği gibi: Bezier eğrilerini kullanan dairenin kesin bir temsili yoktur.
Diğer cevapları tamamlamak için: n
Segmentli Bezier eğrisi için , eğrinin ortasının dairenin kendisi üzerinde olması anlamında, kontrol noktalarına olan en uygun mesafe (4/3)*tan(pi/(2n))
.
Yani 4 puan için (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831
.
Comp.graphics.faq kapsamındadır
Subject 4.04: Bezier eğrisini daireye nasıl sığdırırım?
İlginçtir ki, Bezier eğrileri bir daireye yaklaşabilir, ancak bir daireye tam olarak uymaz. Yaygın bir yaklaşım, bir çemberi modellemek için dört bezier kullanmaktır; bunların her biri uç noktalardan d = r * 4 * (sqrt (2) -1) / 3 mesafede (burada r daire yarıçapıdır) ve uç noktalarda daireye teğet bir yön. Bu, Beziers'ın orta noktalarının daire üzerinde olmasını ve ilk türevin sürekli olmasını sağlayacaktır.
Bu yaklaşımdaki radyal hata, dairenin yarıçapının yaklaşık% 0,0273'ü olacaktır.
Michael Goldapp, "Kübik polinomlarla dairesel yayların yaklaştırılması" Bilgisayar Destekli Geometrik Tasarım (# 8 1991 s.227-238)
Tor Dokken ve Morten Daehlen, "Eğrilik-sürekli Bezier eğrileriyle dairelerin İyi Yaklaşımları" Bilgisayar Destekli Geometrik Tasarım (# 7 1990 s. 33-41). http://www.sciencedirect.com/science/article/pii/016783969090019N (ücretsiz olmayan makale)
Ayrıca, http://spencermortensen.com/articles/bezier-circle/ adresindeki ödeme duvarlı olmayan makaleye bakın.
Bazı tarayıcıların tuval çizim yayları için Bezier eğrilerini kullandığını, Chrome'un (şu anda) 4 sektörlü bir yaklaşım kullandığını ve Safari'nin 8 sektörlü bir yaklaşım kullandığını, farkın yalnızca yüksek çözünürlükte fark edilebildiğini, çünkü bu% 0,0273 olduğunu unutmayın. yalnızca yaylar paralel olarak ve faz dışı çizildiğinde gerçekten görünür, yayların gerçek bir çemberden salındığını fark edeceksiniz. Eğri, radyal merkezi etrafında hareket ederken etki daha da belirgindir, 600 piksel yarıçapı genellikle bir fark yaratacağı boyuttur.
Bazı çizim API'leri gerçek yay oluşturma özelliğine sahip değildir, bu nedenle Bezier eğrilerini de kullanırlar, örneğin Flash platformunda yay çizim api'si yoktur, bu nedenle yaylar sunan çerçeveler genellikle aynı Bezier eğrisi yaklaşımını kullanır.
Tarayıcılardaki SVG motorlarının farklı bir çizim yöntemi kullanabileceğini unutmayın.
Kullanmaya çalıştığınız platform ne olursa olsun, yay çiziminin nasıl yapıldığını kontrol etmeye değer, böylece bunun gibi görsel hataları tahmin edebilir ve uyarlayabilirsiniz.
Sorunun cevapları çok iyi, bu yüzden eklenecek çok az şey var. Bundan ilham alarak çözümü görsel olarak doğrulamak için bir deney yapmaya başladım , dört Bézier eğrisinden başlayarak, eğri sayısını bire düşürdüm. Şaşırtıcı bir şekilde, üç Bézier eğrisiyle dairenin benim için yeterince iyi göründüğünü , ancak yapımın biraz zor olduğunu öğrendim . Aslında Inkscape'i siyah 1 piksel genişliğindeki Bézier yaklaşımını kırmızı 3 piksel genişliğindeki bir dairenin üzerine yerleştirmek için kullandım (Inkscape tarafından üretildiği gibi). Açıklama için Bézier eğrilerinin sınırlayıcı kutularını gösteren mavi çizgiler ve yüzeyler ekledim.
Kendinizi görmek için sonuçlarımı sunuyorum:
1 eğri grafiği (tamlık için bir köşede sıkıştırılmış bir damlaya benzeyen):
(SVG'yi veya PDF'yi buraya koymak istedim, ancak bu desteklenmiyor)
Zaten birçok cevap var ama çok iyi bir kübik bezier yaklaşık bir daireye sahip küçük bir çevrimiçi makale buldum. Birim çember cinsinden c = 0.55191502449, burada c, teğetler boyunca eksen kesişme noktalarından kontrol noktalarına olan mesafedir.
Kontrol noktaları olan iki orta koordinat ile birim çember için tek bir kadran olarak. (0,1),(c,1),(1,c),(1,0)
Radyal hata sadece% 0,019608'dir, bu yüzden onu bu cevaplar listesine eklemek zorunda kaldım.
Makale burada bulunabilir. Kübik Bézier eğrilerine sahip yaklaşık bir daire
Mümkün değil. Bezier, kübiktir (en azından ... en yaygın kullanılanıdır). Bir daire tam olarak bir kübik ile ifade edilemez, çünkü bir daire, denkleminde bir karekök içerir. Sonuç olarak, yaklaşmalısınız.
Bunu yapmak için, çemberinizi n-tantlara (egquadrantlar, octants) bölmeniz gerekir. Her n-tant için, ilk ve son noktayı Bezier eğrisinin ilk ve sonuncusu olarak kullanırsınız. Bezier poligonu, iki ek nokta gerektirir. Hızlı olmak için, n-tantın her uç noktası için çembere teğet alır ve iki noktayı iki teğetin kesişimi olarak seçerdim (böylece temelde Bezier poligonunuz bir üçgen olur). Hassasiyetinize uyacak şekilde n-tant sayısını artırın.
Diğer cevaplar, gerçek bir çemberin mümkün olmadığı gerçeğini kapsıyor. Bu SVG dosyası, Kuadratik Bezier eğrilerini kullanan bir yaklaşık değerdir ve alabileceğiniz en yakın şeydir: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg
İşte Kübik Bezier eğrileri olan bir tane: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg
Yalnızca kod arayan kişilere:
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>
Bu, 4 Bezier eğrisinden oluşan daire çizmeye izin verir. JS'de yazılmıştır, ancak başka herhangi bir dile kolayca çevrilebilir
Gerekmedikçe SVG yolunu kullanarak bir daire çizmeniz gerekiyorsa Bezier eğrilerini kullanmayın. Arc
Yolda 2 yarım daire oluşturmak için kullanabilirsiniz .
Yaklaşımla ilgili olduğu için yeni bir soru açmalı mıyım emin değilim ama Bezier için herhangi bir derecede kontrol noktası elde etmek için genel formülle ilgileniyorum ve bu soruya uyduğuna inanıyorum. Web'de bulduğum tüm çözümler sadece kübik eğriler için ya da ücretli ya da anlamıyorum bile (matematikte pek iyi değilim). Bu yüzden bunu kendi başıma çözmeye karar verdim. Verilen açıya bağlı olarak kontrol noktasının dairenin merkezinden uzaklığını inceliyordum ve şimdiye kadar şunu buldum:
N
Tek eğri için kontrol noktalarının sayısı nerede veα
açı ark çemberdir.
İkinci dereceden eğri için basitleştirilebilir: l ≈ r + r * PI*0.1 * pow(α/90, 2)
Daha PI*0.1
ziyade bir tahmin - mükemmel değeri hesaplamadım ama oldukça yakın. Bu, kübik eğri için yaklaşık% 0,2 yarıçap hatası veren 1-2 kontrol noktalı eğri için oldukça iyi çalışır. Daha yüksek dereceli eğriler için doğruluk kaybı fark edilebilir. 3 kontrol noktası ile eğri kuadratiğe benziyor, bu yüzden açıkçası bir şeyi özlüyorum ama çözemiyorum ve bu yöntem genel olarak ihtiyaçlarımı şimdilik karşılıyor. İşte demo .
Bunu ölümden döndürdüğüm için özür dilerim, ancak bu yazıyı genişletilebilir bir formül bulmada bu sayfayla birlikte çok yararlı buldum .
Temel olarak, 4'ün üzerinde herhangi bir sayıda Bezier eğrisini kullanmanıza olanak tanıyan inanılmaz derecede basit bir formül kullanarak yakın bir daire oluşturabilirsiniz: Distance = radius * stepAngle / 3
Distance
Bir Bezier kontrol noktası ile yayın en yakın ucu arasındaki mesafe nerede , yarıçap radius
dairenin ve stepAngle
yayın 2 ucu arasındaki açıdır ve 2π / (eğri sayısı) ile temsil edilir.
Yani tek seferde vurmak için: Distance = radius * 2π / (the number of curves) / 3
Distance = (4/3)*tan(pi/2n)
. Çok sayıda yay için neredeyse aynıdır çünkü tan(pi/2)~pi/2n
örneğin n=4
(en çok kullanılan durum budur) formülünüz verir, Distance=0.5235...
ancak en uygun olanıdır Distance=0.5522...
(yani ~% 5 hataya sahipsiniz).
Çözünürlük ve hassasiyete bağlı olarak makul veya korkunç görünecek ağır bir yaklaşım ama kontrol noktalarım olarak sqrt (2) / 2 x radius kullanıyorum . Bu sayının nasıl elde edildiğini ve okumaya değer olduğunu oldukça uzun bir metin okudum, ancak yukarıdaki formül hızlı ve kirli.