web-dev-qa-db-fra.com

Comment créer un cercle avec des courbes de Bézier?

Nous avons un point de départ (x, y) et un rayon de cercle. Il existe également un moteur pouvant créer un chemin à partir de points de courbe de Bézier.

Comment créer un cercle en utilisant les courbes de Bézier?

73
Rella

Comme déjà dit: il n’existe pas de représentation exacte du cercle utilisant les courbes de Bézier. 

Pour compléter les autres réponses: pour la courbe de Bézier avec n segmente la optimale distance aux points de contrôle, en ce sens que le milieu de la courbe se situe sur le cercle lui-même, est (4/3)*tan(pi/(2n))

formula for n segments

Donc pour 4 points c'est (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831.

4 point case

109
Kpym

Couvert dans le comp.graphics.faq 

Extrait:

Sujet 4.04: Comment ajuster une courbe de Bézier à un cercle?

Il est intéressant de noter que les courbes de Bézier peuvent représenter un cercle mais Ne correspondent pas parfaitement à un cercle . Une approximation courante consiste à utiliser quatre beziers pour représenter un cercle, chaque (sqrt (2) -1)/3 à partir des points finaux (où r est le rayon du cercle) et dans une direction tangente au cercle aux points finaux. Cela garantira que les points médians du Béziers sont sur le cercle et que la première dérivée est continue.
L’erreur radiale dans cette approximation sera d’environ 0,0273% du rayon du cercle

Michael Goldapp, "Approximation d'arcs de cercle cubiques Polynômes." Conception géométrique assistée par ordinateur (n ° 8 1991, pp.227-238)

Tor Dokken et Morten Daehlen, "Bonnes approximations des cercles par Courbes de Bézier continues et à courbure", géométrie assistée par ordinateurDesign (n ° 7, 1990, p. 33-41). http://www.sciencedirect.com/science/article/pii/016783969090019N (article non libre)

Voir également l'article non paywalled à http://spencermortensen.com/articles/bezier-circle/

Navigateurs et élément de toile.

Notez que certains navigateurs utilisent les courbes de Bézier pour dessiner leur arc de canevas, Chrome utilise (actuellement) une approche à 4 secteurs et Safari utilise une approche à 8 secteurs. La différence est notable uniquement à haute résolution, à cause de cette valeur de 0,0273%. Seulement visible lorsque les arcs sont dessinés en parallèle et déphasés, vous remarquerez que les arcs oscillent à partir d'un vrai cercle. L'effet est également plus visible lorsque la courbe s'anime autour de son centre radial. Le rayon de 600 pixels est généralement la taille où il fera la différence. 

Certaines API de dessin n'ont pas de rendu d'arc réel, elles utilisent donc également les courbes de Bézier. Par exemple, la plate-forme Flash ne dispose d'aucune API de dessin d'arc. Par conséquent, tous les cadres offrant des arcs utilisent généralement la même approche de courbe de Bézier.

Notez que les moteurs SVG des navigateurs peuvent utiliser une méthode de dessin différente.

Autres plateformes

Quelle que soit la plate-forme que vous essayez d'utiliser, il est utile de vérifier comment le dessin à l'arc est effectué. Vous pouvez ainsi prédire de telles erreurs visuelles et vous adapter. 

29
ocodo

Ce n'est pas possible. Un Bézier est un cube (au moins ... le plus couramment utilisé est). Un cercle ne peut pas être exprimé exactement avec un cube, car un cercle contient une racine carrée dans son équation. En conséquence, vous devez approximer.

Pour ce faire, vous devez diviser votre cercle en n-tants (par exemple, quadrants, octants). Pour chaque n-tant, vous utilisez le premier et le dernier point en tant que premier et dernier de la courbe de Bézier. Le polygone de Bézier nécessite deux points supplémentaires. Pour être rapide, je prendrais les tangentes au cercle pour chaque point extrême du n-tant et choisirais les deux points comme intersection des deux tangentes (de sorte que votre polygone de Bézier soit fondamentalement un triangle). Augmentez le nombre de n-tants selon votre précision. 

8
Stefano Borini

Beaucoup de réponses déjà mais j'ai trouvé un petit article en ligne avec une très bonne approximation de Bézier cubique d'un cercle. En termes d'unité de cercle, c = 0,55191502449, c étant la distance entre les points d'interception d'axe le long des tangentes aux points de contrôle.

En tant que quadrant unique pour le cercle d'unités, les deux coordonnées centrales constituant les points de contrôle. (0,1),(c,1),(1,c),(1,0)

L’erreur radiale n’est que de 0,019608%, il me fallait donc l’ajouter à cette liste de réponses.

L'article peut être trouvé ici Approximer un cercle avec les courbes cubiques de Bézier

7
Blindman67

Les autres réponses ont couvert le fait qu’un vrai cercle n’est pas possible. Ce fichier SVG est une approximation à l’aide des courbes de Bézier quadratique et constitue l’objet le plus proche: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg

En voici une avec les courbes de Bézier cubique: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg

7
Jaffer

Je ne sais pas si je devrais ouvrir une nouvelle question car il s'agit d'aproximation mais je m'intéresse à la formule générale permettant d'obtenir des points de contrôle pour Bézier, quel que soit leur degré, et je crois que cela correspond à cette question . Toutes les solutions que j'ai trouvées dans le web ne sont que pour les courbes cubiques ou sont payées ou je ne comprends même pas (je ne suis pas très bon en maths) ... J'ai donc décidé d'essayer de résoudre ce problème moi-même. J'étudiais la distance du point de contrôle à partir du centre du cercle en fonction de l'angle donné et jusqu'à présent, j'ai constaté que:

enter image description here

N est le nombre de points de contrôle pour une courbe et α est l'angle de l'arc de cercle.

Pour la courbe quadratique, il peut être simplifié à l ≈ r + r * PI*0.1 * pow(α/90, 2) Le PI*0.1 est plutôt une supposition - je n’ai pas calculé la valeur parfaite mais c’est assez proche. Cela fonctionne relativement bien pour une courbe avec 1-2 points de contrôle, ce qui donne une erreur de rayon d'environ 0,2% pour la courbe cubique. Pour les courbes de degré plus élevé, une perte de précision est perceptible. Avec 3 points de contrôle, la courbe ressemble au quadratique, il est donc évident que je manque quelque chose, mais je ne peux pas le comprendre et cette méthode correspond généralement à mes besoins pour l'instant . Voici demo .

1
Paweł Audionysos

Aux personnes qui recherchent simplement du code:

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>

Cela permet de dessiner un cercle composé de 4 courbes de Bézier. Écrit en JS mais peut facilement être traduit dans une autre langue

1
NoOorZ24

Désolé de ramener celui-ci d'entre les morts, mais j'ai trouvé ce message très utile avec this page pour proposer une formule extensible.

Fondamentalement, vous pouvez créer un cercle proche en utilisant une formule incroyablement simple qui vous permet d’utiliser un nombre quelconque de courbes de Bézier sur 4: Distance = radius * stepAngle / 3

Distance est la distance entre un point de contrôle de Bézier et l'extrémité la plus proche de l'arc, le rayon est la radius du cercle et stepAngle est l'angle entre les 2 extrémités de l'arc, représenté par 2π/(le nombre de courbes).

Donc, pour le frapper en un seul coup: Distance = radius * 2π / (the number of curves) / 3

0
bubbinator