IPB
ЛогинПароль:

> Прочтите прежде чем задавать вопрос!

1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!

> Рисование закрашенного треугольника
Дож
сообщение 14.05.2005 21:59
Сообщение #1


Бывалый
***

Группа: Пользователи
Сообщений: 179
Пол: Мужской

Репутация: -  1  +


Я составлял прогу по рисованию закрашенного треугольника(процедура triangleDraw). Задаются точки A,B,C и цвет col.

Алгоритм таков:
1) Сортируем точки так, что A.y<B.y и C.y>B.y;
2) От sy=A.y до C.y находим точки пересечения со сторонами и
3)рисуем горизонтальную линию в этих координатах.

Описал алгоритм ужасно, подробнее см. http://www.enlight.ru/faq3d/articles/24.htm

Код

USES CRT;

Procedure setGraph;
begin
asm
  mov ax,13h
  int 10h
end;
end;

Procedure PutPixel(x,y:integer;col:byte);
begin
If (x<321)and(x>-1)and(y<200)and(y>-1) then
Mem[$A000:x+y*320]:=col;
end;

Function  GetPixel(x,y:integer) : byte;
begin
GetPixel:=Mem[$A000:x+y*320];
end;

Type Point2D = record
    x,y : integer;
    end;

Procedure triangleDraw(A,B,C:Point2D;col:byte);
Var i,sy,x1,x2:integer;
   T : Point2D;
begin
{сортировка вершин}
If A.y>B.y then begin T:=B; B:=A; A:=T; end;
If A.y>C.y then begin T:=C; C:=A; A:=T; end;
If B.y>C.y then begin T:=B; B:=C; C:=T; end;
{завершение сортировки}
{Основной цикл подпрограммы}
sy:=A.y;
 While sy<>C.y do begin
  sy:=sy+1;
   {Поиск точек пересечения для sy}
   x1:=round(A.x+(sy-A.y)*(C.x-A.x)/(C.y-A.y));
   If sy<B.y then begin
    x2:=round(A.x+(sy-A.y)*(B.x-A.x)/(B.y-A.y));
   end else begin
    If C.y=B.y then begin
     x2:=B.x;
    end else begin
     x2:=round(B.x+(sy-B.y)*(C.x-B.x)/(C.y-B.y));
    end;
   end;
   {Точки найденны, надо отсортировать}
  If (x1>x2) then begin
  T.x:=x1; x1:=x2; x2:=T.x;
  end;
   {отсортированны, надо нарисовать}
  i:=x1;
   While i<>x2 do begin
    i:=i+1;
    PutPixel(i,sy,col);
   end;
    {Все, для sy сделали то, что хотели}
end;
end;

Const A1 : Point2D = (x : 300;y : 150);
     A2 : Point2D = (x : 150;y : 170);
     A3 : Point2D = (x : 5;y : 5);

BEGIN
setGraph;
TriangleDraw(A3,A1,A2,70);
PutPixel(250,100,67);
readln;
END.


Проблема состоит вот в чем: при sy=117 рисуется не то, что нужно. А точнее
в операторе
Код

x1:=round(A.x+(sy-A.y)*(C.x-A.x)/(C.y-A.y));

вместо ~103 x1 принимает отрицательное значение, хотя виндовый калькулятор выдает нужные 103.42424242... blink.gif
Почему это так?


--------------------
Доброго времени суток.
:nnn:
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
 
 Ответить  Открыть новую тему 
Ответов
volvo
сообщение 14.05.2005 22:29
Сообщение #2


Гость






Очень странно, что это у тебя происходит... Я только что попробовал распечатать значения sy и x1 вместо того чтобы их отрисовывать. Вот так:
While sy<>C.y do begin
sy:=sy+1;
x1:=round(A.x+(sy-A.y)*(C.x-A.x)/(C.y-A.y));
writeln('sy = ', sy:5, ' x1 = ', x1); { <--- Печатаем здесь }
If sy<B.y then begin
x2:=round(A.x+(sy-A.y)*(B.x-A.x)/(B.y-A.y));
...

Вот что получилось:
Цитата
sy =  113 x1 = 100
sy =  114 x1 = 101
sy =  115 x1 = 102
sy =  116 x1 = 103
sy =  117 x1 = 103 <--- Здесь проблем нет
sy =  118 x1 = 104
sy =  119 x1 = 105
sy =  120 x1 = 106


Как видишь, все нормально - никаких проблем, никаких отрицательных чисел...

P.S. А теперь, внимание, вопрос: :D
Зачем опять же изобретать свой велосипед и делать такую процедуру, когда можно воспользоваться процедурой FillPoly? Или ты думаешь, что у тебя получится лучше, чем у Борланда? Сомневаюсь...
 К началу страницы 
+ Ответить 

Сообщений в этой теме


 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 



- Текстовая версия 22.06.2025 16:23
Хостинг предоставлен компанией "Веб Сервис Центр" при поддержке компании "ДокЛаб"