Как стать автором
Обновить

Комментарии 23

А если мы сидим на движке Хрома (собссно Chrome или Opera), то можно заюзать экспериментальную фичу:

ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise);
спасибо за совет!
Извините, но не до конца понял, чем Вам не понравилось параметрическое уравнение и отрисовка через какое то dt?

Почему было решено все делать через кривые безье?
Я думал и о таком варианте решения, но решил остановиться на кривых Безье, потому что раньше с ними не работал.
А, хорошо ) просто это не совсем эллипс, скорее визуальная аппроксимация, так как Безье это все таки полином. Но это так, придирки к названию )
НЛО прилетело и опубликовало эту надпись здесь
И правда. Написал функцию рисования эллипса через параметрическое уравнение. Наложил. Разница заметна. jsfiddle.net/Smoren/ztpy8pag

function drawEllipseParam(ctx, coords, sizes, angle, segments) {
    ctx.save();
    ctx.translate(coords[0], coords[1]);
    ctx.rotate(angle);
    ctx.beginPath();
    var x, y, firstTime=true;
    var dt = 1/segments;
    
    for(var t=0; t<2*Math.PI; t+=dt) {
        x = sizes[0]*Math.cos(t);
        y = sizes[1]*Math.sin(t);
        if(firstTime) {
            firstTime = false;
            ctx.moveTo(x, y);
        } else {
            ctx.lineTo(x, y);
        }
    }
    
    ctx.strokeStyle = 'blue';
    ctx.stroke();
    ctx.closePath();
    ctx.restore();
}
А можно проще:
ctx.rotate(0.3);
ctx.save();
ctx.translate(50, 50);
ctx.scale(0.75, 1);
ctx.arc(0, 0, 50, 0, Math.PI*2, false);
ctx.closePath();
ctx.stroke();
ctx.restore();
ctx.rotate(-0.3);


Demo: jsfiddle.net/2frckjxm
спасибо за вариант!
В этом случае линия контура может стать слишком тонкой. Чтобы стало заметно, попробуйте использовать:
ctx.scale(0.1, 1);
Хм
Прочитал пост в метро, но не имел возможности написать, а сейчас уже все доступные способы описали и реализовали :). И через scale, и аппроксимацию отрезками.

Добавлю, разве что, вот эту ссылку
stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas/23184724
Это автору топа.

Теперь конкретно к вам, kahi4. Мне больше нравится вот так :).
ctx.save();
ctx.fillStyle = 'red';
ctx.translate(100, 100);
ctx.rotate(30 * Math.PI / 180);
ctx.scale(0.75, 1);
ctx.translate(-100, -100);
ctx.arc(100, 100, 50, 0, Math.PI*2, true);
ctx.fill();
ctx.restore();
Я в своё время пробовал. Но не сумел добиться, чтобы у меня эллипс и дуга такого же эллипса точно друг на друга накладывались (нужно было выделить более жирно часть эллиптической орбиты). В результате я плюнул и стал строить орбиты как графики функций.
Так тут можно как раз рисовать дугу эллипса средствами параметрического уравнения.
Я брал уравнения конических сечений в полярных координатах. Да, явно получить параметрические уравнения не сообразил.
артефакты
Не нужно велосипедов! Всё это можно сделать встроенными средствами: jsfiddle.net/7ppu4g9x
Спасибо за метод.
Вот как раз этот метод мне и дал разные результаты для целого эллипса и его дуги.
Как по мне, эллипс и дуга вполне достойно стыкуются: jsfiddle.net/subzey/p0pq6gr8

По границам жёлтого отрезка есть сероватые полосы, но это из-за субпиксельного рендеринга — если нарисовать две линии поверх друг друга, не попадая в пиксели, получится тот же эффект.
У меня была орбита толщиной один пиксель и, собственно, рабочий участок — два пикселя. Не утверждаю, что нельзя найти решение, но мне перейти к графику уравнения оказалось технически проще, потому что так уже строились гиперболы.
Вас понял. Вашем случае действительно рисование по точкам весьма и весьма приемлимый подход.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории