2015-07-14 11 views
13

Ich benutze Javascript und eine Leinwand, um eine mathematisch entworfene Skala zu zeichnen (um Drehmoment zu messen, enthält es Newton-Meter und Fuß-Pfund). Ich hatte meine Ticks mit Trigonometrie positioniert und zeichnete Lichtbogenlinien mit arc natürlich. Das Problem kam, als sie sich anstellen mussten, aber es gab eine seltsame Verzerrung. Ich zeichnete dann einen sehr großen Kreis und verglich ihn mit einer kreisförmigen Auswahl in GIMP und es gab eine Verzerrung. Die Kreise sind alle 45 Grad um die Kreise einheitlich, aber zwischen diesen Knoten weicht der gezeichnete Kreis nach außen ab, ähnlich wie ein Achteck, das zu weit nach außen gerundet werden kann, um einen Kreis zu bilden.Wie kann ich einen Kreis auf einer Leinwand zeichnen?

Warum treten diese Verzerrungen auf? Wie kann ich einen wirklich kreisförmigen Kreis auf einer Leinwand zeichnen?

Dies ist der Code, den ich verwendet habe, um meinen verzerrten Kreis zu erzeugen.

<!DOCTYPE html> 
<html> 
    <body> 
    <canvas width=8000 height=8000 id='myCanvas'></canvas> 
    <script> 
     var canvas = document.getElementById('myCanvas'); 
     var context = canvas.getContext('2d'); 
     context.beginPath(); 
     context.arc(4000, 4000, 3200, 0, Math.PI*2, false); 
     context.lineWidth = 1; 
     context.strokeStyle = '#ff0000'; 
     context.lineCap = 'square'; 
     context.stroke(); 
    </script> 
    </body> 
</html> 

Diese nicht minimal sein kann, weiß ich nicht die Relevanz der context.lineCap, aber es ist ein Überbleibsel des Codes dies auf basiert. Der folgende Screenshot zeigt die Differenz zwischen dem von GIMP gezeichneten Kreis und dem Kreis von Chrome gezeichnet screenshot

+0

Haben Sie einen Beispielcode? –

+0

@ JonSaw Sicher. Ich füge den Code hinzu, mit dem ich meinen Kreis generiert habe. –

+0

Lief den Code auf Safari (8.0.6), Chrome (43.0.2357.132) und Firefox (36.0.4) - es sah gut aus auf meiner. JS Bin [hier] (https://jsbin.com/pohehixibu/edit?html,output). Nur aus Neugier, welchen Browser benutzen Sie? –

Antwort

10

Dies wird Chromium Bug #164241 (Fest deklarierte, obwohl das Update nicht aus noch gemacht haben). Die kurze Antwort lautet: Chrome ist approximating circles with composite Bezier curves.

Ich konnte dies nicht selbst auf Chromium (43.0.2357.130, Ubuntu) replizieren, aber es tritt auf Firefox 39 auf, obwohl ich einen ähnlichen Fehlerbericht für Firefox nicht finden konnte. Die Tatsache, dass es alle 90 Grad korrekt ist (nicht 45, zumindest nicht für mich) zeigt an, dass Kreise durch 4 Kurven approximiert werden, da die Kurvenendpunkte garantiert korrekt sind.

Glücklicherweise gibt es eine einfache Problemumgehung: Erstellen Sie einen Pfad, der aus mehr als 4 Kurven besteht. 8 oder sogar 6 sollten für die Radien ausreichen, die Sie verwenden, aber Sie können mehr verwenden, wenn Sie auf Nummer sicher gehen wollen. Oder Sie könnten die Anzahl der Kurven als Funktion des Radius erhöhen, obwohl die Berechnung der optimalen Funktion (das Minimum n, das für einen gegebenen Radius r einen genauen Kreis ergibt) nicht trivial ist.

context.beginPath(); 
var n=8; // 4 is the default behaviour. higher is better, also slower 
for (var i=0; i<n; i++) { 
    context.arc(4000, 4000, 3200, Math.PI*2*i/n, Math.PI*2*(i+1)/n, false); 
} 
context.stroke(); 

Siehe auch this question.

(Und ja, lineCap ist ein red Hering.)

+0

Wie sehr enttäuschend. Ich denke, ich muss nur meine eigene, bessere Annäherung schreiben. –

Verwandte Themen