Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.02.26;
Скачать: CL | DM;

Вниз

Быстрый вывод треугольника   Найти похожие ветки 

 
Xerx ©   (2005-09-17 09:10) [0]

Подскажите как отрисовать треугольник с использованием алгоритмов Брезенхема( в идеале на основе более быстрых алгоритмов (Бойе, и т.д.) ). У меня проблема с разным временем достижения концов отрезка для сторон с разным углом наклона. Из-за этого не получается выводить горизонтальными линиями.
Необходимо именно идти по точкам сторон.


 
MBo ©   (2005-09-17 09:31) [1]

Треугольник закрашенный или нет?
Требуется самоcтоятельное попиксельное рисование, без использования графических примитивов GDI?


 
Xerx ©   (2005-09-17 09:34) [2]

Да, конечно. Закрашиваю треугольник попиксельно горизонтальними линиями в 2 захода (верхняя и нижняя половины).


 
MBo ©   (2005-09-17 09:43) [3]

Пока не особо понял, в чем проблема...
Растеризация треугольника обычно делается так:
Вершины сортируются по высоте, треугольник делится по средней по горизонтали на два, каждый с гориз. стороной (естественно, если уже есть гориз. сторона, то проще)
Для каждого из треугольников для наклонных сторон синхронно идем от горизонтали к противоположной вершине Брезенхемом по прямой. Синхронизация заключается в том, что пока Y-координата не сменилась, выбираем макс. и мин. значение X, при смене Y - выводим гориз. прямую.


 
MBo ©   (2005-09-17 10:47) [4]

Можешь вот это попробовать: (на базе кода R.Wilcock)

type
 TTriangle = array[0..2] of TPoint;
 TEdge = record
   xint, xfrac: Integer;
   dxint, dxfrac: Integer;
   dy, life: Integer;
 end;

procedure TriangleFill(t: TTriangle; Canvas: TCanvas);
var
 shortedge, longedge: TEdge;
 line: Integer;

 function SwapVertices(var t: TTriangle; p, q: Integer): Boolean;
 var
   Tmp: TPoint;
 begin
   Result := t[p].y > t[q].y;
   if Result then begin
     Tmp := t[p];
     t[p] := t[q];
     t[q] := Tmp;
   end;
 end;

 function initedge(t: TTriangle; p, q: Integer): TEdge;
 var
   x, dx, dy: Integer;
   e: TEdge;
 begin
   dx := t[q].x - t[p].x;
   dy := t[q].y - t[p].y;
   e.life := dy;
   dy := 2 * dy;
   e.dy := dy;
   if dy = 0 then begin
     Result := e;
     Exit;
   end;
   x := t[p].x * e.dy + dx;
   e.xint := x div dy;
   e.xfrac := x mod dy;
   if e.xfrac < 0 then begin
     Dec(e.xint);
     Inc(e.xfrac, dy);
   end;
   dx := dx * 2;
   e.dxint := dx div dy;
   e.dxfrac := dx mod dy;
   if e.dxfrac < 0 then begin
     Dec(e.dxint);
     Inc(e.dxfrac, dy);
   end;
   Result := e;
 end;

 procedure advance(var e: TEdge);
 begin
   Inc(e.xint, e.dxint);
   Inc(e.xfrac, e.dxfrac);
   if e.xfrac >= e.dy then begin
     Dec(e.xfrac, e.dy);
     Inc(e.xint);
   end;
   Dec(e.life);
 end;

begin
 SwapVertices(t, 0, 1);
 SwapVertices(t, 1, 2);
 SwapVertices(t, 0, 1);
 longedge := initedge(t, 0, 2);
 shortedge := initedge(t, 0, 1);
 line := t[0].y;
 while shortedge.life > 0 do begin
   Canvas.MoveTo(longedge.xint, line);
   Canvas.LineTo(shortedge.xint, line);
   Inc(Line);
   advance(longedge);
   advance(shortedge);
 end;
 shortedge := initedge(t, 1, 2);
 while longedge.life > 0 do begin
   Canvas.MoveTo(longedge.xint, line);
   Canvas.LineTo(shortedge.xint, line);
   Inc(Line);
   advance(longedge);
   advance(shortedge);
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
 t: TTriangle;
begin
 t[0] := Point(0, 0);
 t[1] := Point(200, 100);
 t[2] := Point(100, 200);
 TriangleFill(t, Canvas);
 Canvas.Brush.Style := bsClear;
 Canvas.Pen.Color := clLime;
 Canvas.Polygon(t);
end;


 
wicked ©   (2005-09-17 20:35) [5]

как вариант, могу посоветовать использовать "строчный буффер" - два массива размером с вертикальное разрешение выводимого изображения... в одном из них - "левые" координаты по икс, в другом - "правые".... и в простом цикле забивать строки...
недостаток - нужна доп. память...... преимущество - "слон" делится на кусочки, оптимизируемые по отдельности...
плюс потенциальная возможность антиалиасинга в горизонтальном направлении...


 
miek ©   (2005-09-19 08:46) [6]

никакие буферы не нужны. антиалиасинг и так дается.

www.miek.narod.ru/spriteutils2.zip

в модуле su2_primitives.inc работающий код. но в принципе от MBo там мало чем отличается, только больше асма.



Страницы: 1 вся ветка

Текущий архив: 2006.02.26;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.145 c
15-1138792435
Тульский
2006-02-01 14:13
2006.02.26
Скачать готовый Proxy на PHP


15-1139230393
max999
2006-02-06 15:53
2006.02.26
маленький вопросик С++ ))


2-1139835151
13
2006-02-13 15:52
2006.02.26
2 вопроса по SpinEdit


15-1139393125
ZMRaven
2006-02-08 13:05
2006.02.26
Мемо ?


2-1139394396
webpauk
2006-02-08 13:26
2006.02.26
Z order