Конференция "Media" » Алгоритм Wu
 
  • Sapersky (14.03.16 20:09) [20]
    Мне лень разбираться в этих ваших китайских алгоритмах, могу предложить рисование кольца с затухающей по краям альфой, при w = 2 результат аналогичен алгоритму Ву. Конечно, рисует медленнее (в 2-2.5 раза), поскольку это более универсальное решение.
    Закомментированный фрагмент без Sqrt работает немного быстрее, но кольцо получается не совсем симметричное (заметно на большой толщине).

    procedure DrawCircleW(Dst : TFastDIB; cx, cy, r, w : Single; c : DWord);
    Var y, sy, ey, BytesPP, Alpha : Integer;
       xf, xf2, r2, r2Min, r2Max, y2 : Single;
       ca : TFColorA;

     procedure DrawPixRange(sx, ex, y : Integer);
     Var x, a, ia : Integer;
         sy, d, w2, aw, aw2 : Single;
         pc : PFColor;
     begin
     Num_InRange(sx, 0, Dst.Width-1); Num_InRange(ex, 0, Dst.Width-1);
     pc := Dst.Scanlines[y]; Inc(PByte(pc), sx * BytesPP);
     sy := Sqr(y - cy);
     aw := Alpha / w;
     w2 := (r2Max - r2Min) * 0.5; aw2 := Alpha / w2;
     For x:=sx to ex do begin

       d := Abs(Sqrt(Sqr(x - cx) + sy) - r);
       If (d < w) then begin
         ia := Round(d * aw);

    {
       d := Abs( (Sqr(x - cx) + sy) - r2);
       If (d < w2) then begin
         ia := Round(d * aw2);
    }

         a := 255 - ia;
         pc.b := (pc.b * ia + ca.b * a) shr 8;
         pc.g := (pc.g * ia + ca.g * a) shr 8;
         pc.r := (pc.r * ia + ca.r * a) shr 8;
       end;
       Inc(PByte(pc), BytesPP);
     end;
     end;

    begin
    w := w * 0.5;
    BytesPP := Dst.Bpp shr 3;
    ca := TFColorA(c);
    Alpha := ca.a; If (Alpha = 0) then Alpha := $FF;

    sy := Trunc(cy - r - w); Num_InRange(sy, 0, Dst.AbsHeight-1);
    ey := Ceil(cy + r + w); Num_InRange(ey, 0, Dst.AbsHeight-1);

    r2Min := Sqr(r - w); r2Max := Sqr(r + w);
    r2 := r * r;

    For y := sy to ey do begin
     y2 := Sqr(y-cy);
     If y2 <= r2Max then begin
       xf := Sqrt( r2Max - y2 );
       If y2 > r2Min then DrawPixRange(Trunc(cx-xf), Ceil(cx+xf), y) else begin
         xf2 := Sqrt( r2Min - y2 );
         DrawPixRange(Trunc(cx-xf), Ceil(cx-xf2), y);
         DrawPixRange(Trunc(cx+xf2), Ceil(cx+xf), y);
       end;
     end;
    end;
    end;

  • Dmk © (14.03.16 20:25) [21]
    А что делает Num_InRange?
  • Dmk © (14.03.16 20:34) [22]
    И что за тип TFColorA и PFColor?
    У меня просто нет сторонних библиотек. Я свои пишу.
  • Sapersky (14.03.16 20:47) [23]
    Uses FastDIB, Utils; - из примера с многопоточностью, кот. я выкладывал.
  • Dmk © (15.03.16 09:33) [24]
    Да не. Кошмарный круг :(
    Ему до Wu далеко по сглаженности.
  • Dmk © (15.03.16 12:56) [25]
    На самом деле имеет смысл «попотеть» для хорошего результата.
    Кстати разница очевидна:
    http://hostingkartinok.com/show-image.php?id=19fc47c3b731f5f4352252f8b81654b0

    Справа Ваш круг.
  • Sapersky (15.03.16 13:16) [26]
    Это я наоптимизировал неудачно, не проверил при альфе < 255.
    Правильно так:

       If (d < w) then begin
         a := Alpha - Round(d * aw);
         ia := 255 - a;

  • Dmk © (17.03.16 11:54) [27]
    Может кто подскажет как узнать размер пикселя, если происходит разрыв функции?
    Например радиус = 101,5. Разрыв функции 2,2216. Функция sqrt(radius*radius - x*x). Для данной функции происходит периодичное накопление длины окружности.
  • Dmk © (18.03.16 16:27) [28]
    Ну и ладно. Сам справился. Нет никакого разрыва оказывается.

    Ровнехонькие получились :)
    http://hostingkartinok.com/show-image.php?id=975cbf34481d62542f34e8e77f38e086

    Чего и Вам желаю )
 
Конференция "Media" » Алгоритм Wu
Есть новые Нет новых   [118667   +45][b:0][p:0.002]