Блог от AS3Coder'a о JavaScript, HTML, CSS... и немного о Flash.

четверг, 5 ноября 2009 г.

Сглаживание линий на графике. Как?

Рассмотрим график:



Часто бывает необходимо, чтобы линии на графике были не в виде ломаной кривой, как показано выше, а в виде сглаженной.

Сглаживание ломанной кривой

В этом посте я не буду затрагивать ActionScript, я только опишу принцип решения задачи.

1. Для начала, нарисуем по заданным точкам кривую.



2. Для каждой точки (кроме первой и последней) добавим вспомогательные точки на отрезках соединяющих текущую точку с предыдущей и следующей. Расстояние до вспомогательных точек должно быть одинаковым, и быть равным 25% минимального отрезка (между отрезками до точки и от неё).



3. Теперь вспомогательные точки нужно, соединить квадратичной кривой Безье, используя в качестве опорной, точку со значением. В этом нам поможет метод curveTo() экземпляра класса flash.display.Graphics



4. Добавим настройку уровня сглаживания.



Вроде получилось, но...

Как сделать так, чтобы сглаженная кривая проходила через точки со значениями?

Этот вопрос мучает меня второй день. Ответ я пока не нашел. Может быть вы что-то подскажете. Куда копать?
  

6 комментариев:

  1. Вершина кривой Безье проходит через середину высоты треугольника, образованного контрольными точками

    ОтветитьУдалить
  2. Спасибо, попробую на днях, что-нибудь из этого извлечь. Если получиться, обязательно отпишусь.

    ОтветитьУдалить
  3. В книге Кейта Питерса Foundation ActionScript Animation: Making Things Move! есть решение этой проблемы (с построением дополнительных промежуточных точек). Пример кода из книги:

    package
    {
    import flash.display.Sprite;
    import flash.events.MouseEvent;

    public class MultiCurves2 extends Sprite
    {
    private var numPoints:uint = 9;
    public function MultiCurves2()
    {
    init();
    }

    private function init():void
    {
    // first set up an array of random points
    var points:Array = new Array();
    for (var i:int = 0; i < numPoints; i++)
    {
    points[i] = new Object();
    points[i].x = Math.random() * stage.stageHeight;
    points[i].y = Math.random() * stage.stageHeight;
    }
    graphics.lineStyle(1);

    // now move to the first point
    graphics.moveTo(points[0].x, points[0].y);

    // and loop through each next successive pair
    for (i = 1; i < numPoints - 2; i ++)
    {
    var xc:Number = (points[i].x + points[i + 1].x) / 2;
    var yc:Number = (points[i].y + points[i + 1].y) / 2;
    graphics.curveTo(points[i].x, points[i].y, xc, yc);
    }
    graphics.curveTo(points[i].x, points[i].y, points[i+1].x, points[i+1].y);
    }
    }
    }

    ОтветитьУдалить
  4. такое вот, немного 'шаманское', решение:
    http://silin.su/#AS3/geom/fit

    ОтветитьУдалить

Можно использовать некоторые HTML-теги, например <b>, <i>, <a>

Поиск по блогу

Обо мне



Farid Shamsutdinov (AS3Coder)
Russia, Tatarstan, Kazan
as3coder@gmail.com

Подробнее...

Постоянные читатели

© 2014 Farid Shamsutdinov. При копировании материалов, ссылка на источник обязательна. Технологии Blogger.