Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Media";
Текущий архив: 2006.02.26;
Скачать: [xml.tar.bz2];

Вниз

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

 
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 вся ветка

Форум: "Media";
Текущий архив: 2006.02.26;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.47 MB
Время: 0.042 c
2-1139203373
Glex
2006-02-06 08:22
2006.02.26
TComponentList.Add - ошибка


3-1135841524
Th
2005-12-29 10:32
2006.02.26
Работа с массивами структур в OCI


3-1135933859
ANB
2005-12-30 12:10
2006.02.26
Оптимальный способо генерации ID (Оракл)


1-1138263863
Daria
2006-01-26 11:24
2006.02.26
Копировать данные из Excel


2-1139310389
naganov
2006-02-07 14:06
2006.02.26
Удаление конечного символа





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский