Abbiamo un punto iniziale (x, y) e un raggio del cerchio. Esiste anche un motore che può creare un percorso dai punti della curva di Bézier.
Come posso creare un cerchio usando le curve di Bézier?
Risposte:
Come già detto: non esiste una rappresentazione esatta del cerchio utilizzando le curve di Bézier.
Per completare le altre risposte: per curva di Bézier con n
segmenti la distanza ottimale dai punti di controllo, nel senso che il centro della curva giace sul cerchio stesso, è (4/3)*tan(pi/(2n))
.
Quindi per 4 punti lo è (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831
.
Coperto in comp.graphics.faq
Soggetto 4.04: come adattare una curva di Bézier a un cerchio?
È interessante notare che le curve di Bézier possono approssimare un cerchio ma non adattarsi perfettamente a un cerchio. Un'approssimazione comune consiste nell'usare quattro bezier per modellare un cerchio, ciascuno con punti di controllo a distanza d = r * 4 * (sqrt (2) -1) / 3 dai punti finali (dove r è il raggio del cerchio), e in una direzione tangente al cerchio nei punti finali. Ciò garantirà che i punti medi di Beziers siano sul cerchio e che la prima derivata sia continua.
L'errore radiale in questa approssimazione sarà circa lo 0,0273% del raggio del cerchio.
Michael Goldapp, "Approssimazione di archi circolari mediante polinomi cubici" Computer Aided Geometric Design (# 8 1991 pp.227-238)
Tor Dokken e Morten Daehlen, "Buone approssimazioni di cerchi mediante curve di Bezier continue con curvatura" Computer Aided Geometric Design (# 7 1990 pp. 33-41). http://www.sciencedirect.com/science/article/pii/016783969090019N (articolo non gratuito)
Vedi anche l'articolo non protetto da paywall su http://spencermortensen.com/articles/bezier-circle/
Nota che alcuni browser utilizzano le curve di Bézier per disegnare l'arco della tela, Chrome utilizza (al momento) un approccio a 4 settori e Safari utilizza un approccio a 8 settori, la differenza è evidente solo ad alta risoluzione, a causa di quello 0,0273%, e anche Veramente visibile solo quando gli archi sono disegnati in parallelo e fuori fase, noterai che gli archi oscillano da un vero cerchio. L'effetto è anche più evidente quando la curva si anima intorno al suo centro radiale, il raggio di 600 px è solitamente la dimensione in cui farà la differenza.
Alcune API di disegno non hanno un rendering ad arco reale, quindi usano anche curve di Bézier, ad esempio la piattaforma Flash non ha API di disegno ad arco, quindi qualsiasi framework che offre archi utilizza generalmente lo stesso approccio della curva di Bézier.
Tieni presente che i motori SVG nei browser potrebbero utilizzare un metodo di disegno diverso.
Qualunque sia la piattaforma che stai cercando di utilizzare, vale la pena controllare per vedere come viene eseguito il disegno dell'arco, in modo da poter prevedere errori visivi come questo e adattarti.
Le risposte alla domanda sono molto buone, quindi c'è poco da aggiungere. Ispirato da ciò ho iniziato a fare un esperimento per confermare visivamente la soluzione, iniziando con quattro curve di Bézier, riducendo il numero di curve a una. Sorprendentemente ho scoperto che con tre curve di Bézier il cerchio mi sembrava abbastanza buono , ma la costruzione è un po 'complicata. In realtà ho usato Inkscape per posizionare l'approssimazione di Bézier nera di 1 pixel su un cerchio rosso di 3 pixel (come prodotto da Inkscape). Per chiarimenti ho aggiunto linee e superfici blu che mostrano i riquadri di delimitazione delle curve di Bézier.
Per vedere te stesso, presento i miei risultati:
Il grafico a 1 curva (che sembra una goccia schiacciata in un angolo, solo per completezza):
(Volevo mettere l'SVG o il PDF qui, ma non è supportato)
Molte risposte già, ma ho trovato un piccolo articolo online con un'ottima approssimazione cubica di un cerchio. In termini di cerchio unitario c = 0,55191502449 dove c è la distanza dai punti di intercettazione dell'asse lungo le tangenti ai punti di controllo.
Come un singolo quadrante per il cerchio unitario con le due coordinate centrali che sono i punti di controllo. (0,1),(c,1),(1,c),(1,0)
L'errore radiale è solo dello 0,019608%, quindi ho dovuto aggiungerlo a questo elenco di risposte.
L'articolo può essere trovato qui Approssimare un cerchio con curve di Bézier cubiche
Non è possibile. Un Bézier è un cubo (almeno ... il più comunemente usato è). Un cerchio non può essere espresso esattamente con un cubo, perché un cerchio contiene una radice quadrata nella sua equazione. Di conseguenza, devi approssimare.
Per fare questo, devi dividere il tuo cerchio in n-tants (egquadrants, ottants). Per ogni n-tant, usi il primo e l'ultimo punto come primo e ultimo della curva di Bézier. Il poligono di Bézier richiede due punti aggiuntivi. Per essere veloce, prenderei le tangenti al cerchio per ogni punto estremo dell'n-tant e sceglierei i due punti come intersezione delle due tangenti (in modo che fondamentalmente il tuo poligono di Bezier sia un triangolo). Aumenta il numero di n-tants in base alla tua precisione.
Le altre risposte hanno coperto il fatto che un vero cerchio non è possibile. Questo file SVG è un'approssimazione che utilizza le curve di Bezier quadratiche ed è la cosa più vicina che puoi ottenere: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg
Eccone uno con le curve di Bézier cubiche: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg
Per le persone che stanno solo cercando il codice:
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>
Ciò consente di disegnare un cerchio composto da 4 curve di Bézier. Scritto in JS ma facilmente traducibile in qualsiasi altra lingua
Non utilizzare le curve di Bézier se è necessario disegnare un cerchio utilizzando il percorso SVG a meno che non sia necessario. Nel percorso è possibile utilizzare Arc
per creare 2 semicerchi.
Non sono sicuro di dover aprire una nuova domanda poiché si tratta di approssimazione, ma sono interessato alla formula generale per ottenere punti di controllo per Bezier di qualsiasi grado e credo che rientri in questa domanda. Tutte le soluzioni che ho trovato sul web sono solo per curve cubiche o sono a pagamento o non capisco nemmeno (non sono molto bravo in matematica). Quindi ho deciso di provare a risolverlo da solo. Stavo studiando la distanza del punto di controllo dal centro di un cerchio dipendente da un dato angolo e finora ho scoperto che:
Dove N
è il numero di punti di controllo per curva singola ed α
è l'angolo dell'arco di cerchio.
Per la curva quadratica può essere semplificato in l ≈ r + r * PI*0.1 * pow(α/90, 2)
Il PI*0.1
è piuttosto un'ipotesi: non ho calcolato il valore perfetto ma è abbastanza vicino. Questo funziona ragionevolmente bene per la curva con 1-2 punti di controllo che danno un errore di raggio di circa lo 0,2% per la curva cubica. Per curve di grado superiore si nota una perdita di precisione. Con 3 punti di controllo la curva sembra simile a quella quadratica, quindi ovviamente mi manca qualcosa ma non riesco a capirlo e questo metodo generalmente si adatta alle mie esigenze per ora. Ecco la demo .
Mi dispiace riportarlo dalla morte, ma ho trovato questo post molto utile insieme a questo pagina nel fornire una formula espandibile.
Fondamentalmente, puoi creare un cerchio vicino usando una formula incredibilmente semplice che ti consente di utilizzare un numero qualsiasi di curve di Bézier su 4: Distance = radius * stepAngle / 3
Dov'è Distance
la distanza tra un punto di controllo di Bézier e l'estremità più vicina dell'arco, il raggio è quello radius
del cerchio estepAngle
è l'angolo tra le 2 estremità dell'arco rappresentato da 2π / (il numero di curve).
Quindi, per colpirlo in un colpo solo: Distance = radius * 2π / (the number of curves) / 3
Distance = (4/3)*tan(pi/2n)
. Per un numero elevato di archi è quasi lo stesso perché tan(pi/2)~pi/2n
, ma ad esempio per n=4
(che è il caso più utilizzato) la tua formula fornisce Distance=0.5235...
ma quella ottimale è Distance=0.5522...
(quindi hai un errore di ~ 5%).
È un'approssimazione pesante che sembrerà ragionevole o terribile a seconda della risoluzione e della precisione, ma uso sqrt (2) / 2 x raggio come punti di controllo. Ho letto un testo piuttosto lungo su come viene derivato quel numero e vale la pena leggerlo, ma la formula sopra è veloce e sporca.