2015-07-14 2 views
13

Я использую javascript и холст, чтобы нарисовать математически разработанную шкалу (для измерения крутящего момента, он включает в себя новые метры и фунты). Естественно, я позиционировал свои тики, используя тригонометрию, и рисование линий дуги с использованием arc. Проблема возникла, когда им нужно было выстраиваться в линию, но было странное искажение. Затем я рисовал очень большой круг и сравнивал его с круговым выбором в GIMP, и было искажение. Круги согласуются каждые 45 градусов вокруг кругов, но между этими узлами холст, нарисованный кругом, отклоняется наружу, подобно восьмиугольнику, который может быть закруглен слишком далеко, чтобы приблизить круг.Как рисовать круг на холсте?

Зачем возникают эти искажения? Как я могу нарисовать по кругу круг на холсте?

Это код, который я использовал для создания искаженного круга.

<!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> 

Это не может быть минимальным, я не знаю актуальности context.lineCap, но это пережиток кода это на основании. Следующий скриншот показывает разницу между окружностью, проведенной с помощью GIMP и кругом нарисованного Chrome screenshot

+0

у вас есть образец кода? –

+0

@ JonSaw Конечно. Я добавлю код, который я использовал для создания своего круга. –

+0

Отмените свой код на Safari (8.0.6), Chrome (43.0.2357.132) и Firefox (36.0.4) - он отлично смотрелся на моем. JS Bin [здесь] (https://jsbin.com/pogehixibu/edit?html,output). Из любопытства, какой браузер вы используете? –

ответ

10

Это Chromium Bug #164241 (объявляется фиксированной, хотя исправление возможно, не сделал его еще). Короткий ответ: Chrome - approximating circles with composite Bezier curves.

Мне не удалось воспроизвести это самостоятельно на Chromium (43.0.2357.130, Ubuntu), но это происходит на Firefox 39, хотя я не смог найти аналогичный отчет об ошибках для Firefox. Тот факт, что он правильный каждые 90 градусов (не 45, по крайней мере, не для меня), указывает на то, что круги аппроксимируются 4 кривыми, так как конечные точки кривой гарантированно будут правильными.

К счастью, есть простой способ: создать путь, состоящий из более чем 4 кривых. 8 или даже 6 должно быть достаточно для радиусов, которые вы используете, но вы можете использовать больше, если хотите играть в безопасное место. Или вы можете увеличить число кривых в зависимости от радиуса, хотя вычисление оптимальной функции (минимальное n, которое будет производить точный круг для заданного радиуса r), нетривиально.

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(); 

См. Также this question.

(И да, lineCap - это красная сельдь.)

+0

Насколько глубоко разочаровывает. Наверное, мне просто нужно написать собственное, лучшее приближение. –