Antworten:
Wie bereits gesagt: Es gibt keine exakte Darstellung des Kreises mit Bezier-Kurven.
Um die anderen Antworten zu vervollständigen: Für die Bezier-Kurve mit n
Segmenten ist der optimale Abstand zu den Kontrollpunkten in dem Sinne, dass die Mitte der Kurve auf dem Kreis selbst liegt (4/3)*tan(pi/(2n))
.
Also für 4 Punkte ist es (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831
.
In der comp.graphics.faq
Thema 4.04: Wie passe ich eine Bezier-Kurve an einen Kreis an?
Interessanterweise können Bezier-Kurven einen Kreis approximieren, passen aber nicht perfekt zu einem Kreis. Eine übliche Annäherung besteht darin, vier Bezier zum Modellieren eines Kreises zu verwenden, wobei jeder Kontrollpunkt einen Abstand d = r * 4 * (sqrt (2) -1) / 3 von den Endpunkten (wobei r der Kreisradius ist) und in eine Richtung, die den Kreis an den Endpunkten tangiert. Dadurch wird sichergestellt, dass sich die Mittelpunkte der Beziers auf dem Kreis befinden und dass die erste Ableitung stetig ist.
Der radiale Fehler in dieser Näherung beträgt ungefähr 0,0273% des Radius des Kreises.
Michael Goldapp, "Approximation von Kreisbögen durch kubische Polynome" Computer Aided Geometric Design (# 8 1991, S. 227-238)
Tor Dokken und Morten Daehlen, "Gute Annäherungen von Kreisen durch krümmungskontinuierliche Bezier-Kurven" Computer Aided Geometric Design (# 7 1990, S. 33-41). http://www.sciencedirect.com/science/article/pii/016783969090019N (nicht kostenloser Artikel)
Siehe auch den Artikel ohne Paywall unter http://spencermortensen.com/articles/bezier-circle/
Beachten Sie, dass einige Browser Bezier-Kurven für ihren Zeichenbogen verwenden, Chrome (derzeit) einen 4-Sektor-Ansatz und Safari einen 8-Sektor-Ansatz verwendet. Der Unterschied ist aufgrund dieser 0,0273% nur bei hoher Auflösung spürbar Nur wenn Bögen parallel und phasenverschoben gezeichnet werden, werden Sie feststellen, dass die Bögen von einem echten Kreis aus schwingen. Der Effekt macht sich auch deutlicher bemerkbar, wenn die Kurve um ihren radialen Mittelpunkt animiert wird. Der Radius von 600 Pixel ist normalerweise die Größe, in der er einen Unterschied macht.
Bestimmte Zeichnungs-APIs verfügen nicht über ein echtes Arc-Rendering, daher verwenden sie auch Bezier-Kurven. Beispielsweise verfügt die Flash-Plattform über keine API zum Zeichnen von Bögen. Daher verwenden Frameworks, die Bögen anbieten, im Allgemeinen denselben Bezier-Kurvenansatz.
Beachten Sie, dass SVG-Engines in Browsern möglicherweise eine andere Zeichenmethode verwenden.
Unabhängig davon, welche Plattform Sie verwenden möchten, sollten Sie überprüfen, wie das Zeichnen von Bögen durchgeführt wird, damit Sie solche visuellen Fehler vorhersagen und anpassen können.
Die Antworten auf die Frage sind sehr gut, daher gibt es wenig hinzuzufügen. Inspiriert davon begann ich ein Experiment zur visuellen Bestätigung der Lösung, beginnend mit vier Bézier-Kurven, wobei die Anzahl der Kurven auf eins reduziert wurde. Erstaunlicherweise fand ich heraus, dass der Kreis mit drei Bézier-Kurven gut genug für mich aussah , aber die Konstruktion ist etwas schwierig. Eigentlich habe ich Inkscape verwendet, um die schwarze 1 Pixel breite Bézier-Näherung über einem roten 3 Pixel breiten Kreis zu platzieren (wie von Inkscape erzeugt). Zur Verdeutlichung habe ich blaue Linien und Flächen hinzugefügt, die die Begrenzungsrahmen der Bézier-Kurven zeigen.
Um sich selbst zu sehen, präsentiere ich meine Ergebnisse:
Das 1-Kurven-Diagramm (das der Vollständigkeit halber wie ein Tropfen aussieht, der in eine Ecke gedrückt wird):
(Ich wollte die SVG oder PDF hier einfügen, aber das wird nicht unterstützt)
Viele Antworten bereits, aber ich fand einen kleinen Online-Artikel mit einer sehr guten kubischen Bezier-Näherung eines Kreises. In Bezug auf den Einheitskreis ist c = 0,55191502449, wobei c der Abstand von den Achsenschnittpunkten entlang der Tangenten zu den Kontrollpunkten ist.
Als einzelner Quadrant für den Einheitskreis, wobei die beiden mittleren Koordinaten die Kontrollpunkte sind. (0,1),(c,1),(1,c),(1,0)
Der radiale Fehler beträgt nur 0,019608%, daher musste ich ihn nur zu dieser Liste von Antworten hinzufügen.
Den Artikel finden Sie hier. Näherungsweise eines Kreises mit kubischen Bézier-Kurven
Es ist nicht möglich. Ein Bezier ist ein Kubikmeter (zumindest ... wird am häufigsten verwendet). Ein Kreis kann nicht genau mit einer Kubik ausgedrückt werden, da ein Kreis eine Quadratwurzel in seiner Gleichung enthält. Infolgedessen müssen Sie annähern.
Dazu müssen Sie Ihren Kreis in n-Tanten (zB Quadranten, Oktanten) teilen. Für jeden n-Tant verwenden Sie den ersten und letzten Punkt als ersten und letzten Punkt der Bezier-Kurve. Das Bezier-Polygon benötigt zwei zusätzliche Punkte. Um schnell zu sein, würde ich die Tangenten für jeden Extrempunkt des n-Tants zum Kreis bringen und die beiden Punkte als Schnittpunkt der beiden Tangenten auswählen (so dass Ihr Bezier-Polygon im Grunde genommen ein Dreieck ist). Erhöhen Sie die Anzahl der n-Tants entsprechend Ihrer Präzision.
Die anderen Antworten haben die Tatsache abgedeckt, dass ein wahrer Kreis nicht möglich ist. Diese SVG-Datei ist eine Annäherung an quadratische Bezier-Kurven und die nächstgelegene, die Sie erhalten können: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg
Hier ist eine mit Cubic Bezier-Kurven: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg
Für Leute, die nur nach Code suchen:
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>
Dies ermöglicht das Zeichnen eines Kreises, der aus 4 Bezier-Kurven besteht. Geschrieben in JS, kann aber leicht in jede andere Sprache übersetzt werden
Ich bin mir nicht sicher, ob ich eine neue Frage eröffnen soll, da es sich um eine Annäherung handelt, aber ich bin an einer allgemeinen Formel interessiert, um Kontrollpunkte für Bezier jeglichen Grades zu erhalten, und ich glaube, dass sie in diese Frage passt. Alle Lösungen, die ich im Web gefunden habe, sind nur für kubische Kurven oder werden bezahlt oder ich verstehe nicht einmal (ich bin nicht sehr gut in Mathe). Also habe ich beschlossen, dies selbst zu lösen. Ich habe die Entfernung des Kontrollpunkts vom Mittelpunkt eines Kreises in Abhängigkeit vom gegebenen Winkel untersucht und bisher festgestellt, dass:
Wo N
ist die Anzahl der Kontrollpunkte für eine einzelne Kurve und α
ist der Kreisbogenwinkel.
Für eine quadratische Kurve kann sie vereinfacht werden. l ≈ r + r * PI*0.1 * pow(α/90, 2)
Das PI*0.1
ist eher eine Vermutung - ich habe keinen perfekten Wert berechnet, aber es ist ziemlich nah. Dies funktioniert ziemlich gut für Kurven mit 1-2 Kontrollpunkten, was einen Radiusfehler von etwa 0,2% für kubische Kurven ergibt. Bei Kurven höheren Grades ist ein Genauigkeitsverlust erkennbar. Mit 3 Kontrollpunkten sieht die Kurve ähnlich wie quadratisch aus, daher vermisse ich offensichtlich etwas, aber ich kann es nicht herausfinden, und diese Methode entspricht im Allgemeinen meinen aktuellen Anforderungen. Hier ist eine Demo .
Es tut mir leid, diesen Beitrag von den Toten zurückzubringen, aber ich fand diesen Beitrag zusammen mit dieser Seite sehr hilfreich , um eine erweiterbare Formel zu entwickeln.
Grundsätzlich können Sie einen Nahkreis mit einer unglaublich einfachen Formel erstellen, mit der Sie eine beliebige Anzahl von Bezier-Kurven über 4 verwenden können: Distance = radius * stepAngle / 3
Wo Distance
ist der Abstand zwischen einem Bezier-Kontrollpunkt und dem nächsten Ende des Bogens, der Radius ist der radius
des Kreises und stepAngle
ist der Winkel zwischen den beiden Enden des Bogens, dargestellt durch 2π / (die Anzahl der Kurven).
Um es auf einen Schlag zu treffen: Distance = radius * 2π / (the number of curves) / 3
Distance = (4/3)*tan(pi/2n)
. Für eine große Anzahl von Bögen ist es fast dasselbe, weil tan(pi/2)~pi/2n
, aber zum Beispiel für n=4
(was der am häufigsten verwendete Fall ist) Ihre Formel gibt, Distance=0.5235...
aber die optimale ist Distance=0.5522...
(also haben Sie ~ 5% Fehler).
Es ist eine schwere Annäherung, die je nach Auflösung und Präzision vernünftig oder schrecklich aussieht, aber ich verwende den Radius sqrt (2) / 2 x als Kontrollpunkte. Ich habe einen ziemlich langen Text gelesen, wie diese Zahl abgeleitet wird, und es lohnt sich zu lesen, aber die obige Formel ist schnell und schmutzig.