Форум: "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