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

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

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

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> Закраска по методу Гуро и Фонга
сообщение
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


Мне нужно изобразить тетраэдр , выполнить закраску Фонга относительно выбранного источника света, разработать процедуру управления скоростью вращения тела с одинаковыми ускорениями по осям и обеспечения перехода на низкозатратную процедуру Гуро и далее на закраску с использованием таблиц освещенности при увеличении угловых скоростей вращения.

Вот... Не знаю даже, с чего начать... Теорию по методам закраски изучила.... но с таким никогда не сталкивалась, поэтому с реализацией большие проблемы....

вот на что думаю опираться:
1. Получить нормаль грани: выбрать два вектора, лежащие в этой грани и найти их векторное произведение, нормировать этот вектор.
2. Записать найденные нормали граней в массив (normg[i]). Чтобы определить нормаль каждой вершины, определяем из таблицы граней для каждой вершины, какие грани в ней сходятся, и для этих найденных граней их нормали суммируем, а сумму нор-мируем (массив normv[i]).
3. Алгоритм Гуро. После того, как нормали вершин найдены, вы-числяем согласно модели освещения освещенность каждой вершины и записываем освещенности в массив освещенностей. Этот массив будет использоваться в процедуре рисования грани.
Алгоритм Фонга. Координаты найденных нормалей вершин пе-реводятся в сферические координаты, так что нормали представле-ны двумя числами типа byte. Нормали в таком виде будут использо-ваны процедурой рисования грани.
4. Реализовать процедуру рисования грани, для чего необходимо провести интерполяцию для определения освещенности (в ме-тоде Гуро) и нормали (в методе Фонга) для каждой точки гра-ни.
Закраску граней можно произвести путем заполнения внутренней области этой грани отрезками прямых, параллельных оси OX. Для этого найдем вершины грани с наименьшей и наибольшей координатой Y.
В качестве начальной возьмем вершину с наименьшей координатой Y. Разобьем условно множество ребер, составляющих грань, на две группы – левую и правую. Будем по очереди брать одно ребро из левой и одно из правой части, т.е. всегда работать с парой ребер. Выбор ребер может производиться следующим образом: сначала берем в качестве левого ребра ребро, начинающееся в начальной вершине и заканчиваю-щееся в следующей по порядку при обходе влево. Это ребро (l0,lk). Аналогично, в качестве первого правого ребра – ребро (r0,rk). Теперь в цикле будем строить прямые, параллельные оси X, начиная с прямой Y = Ymin, каждый раз увеличивая ординату. Для каждой этой прямой бу-дем находить точки пересечения с нашей парой боковых ребер. Если одно из боковых ребер не имеет точки пересечения с этой прямой, то его отбрасываем и берем следующее из его группы (левой или правой).
Если точки пересечения найдены, то найдем, какая часть левого и правого ребра пройдена, это значение запишется соответственно в пе-ременные tl и tr. Значение переменных tl и tr используется на первом шаге билинейной интерполяции в методе Гуро для нахождения осве-щенности в точках пересечения прямой, параллельной оси Х, и ребер, а в методе Фонга для определения нормалей тела в этих точках. Второй шаг интерполяции ведется аналогично, только вдоль отрезка, заключен-ного между парой ребер. Таким образом, вычисляется необходимая ин-формация для каждой точки грани.

но как всё это реализовать - не знаю! С чего начинать! Может быть кто-нибудь может привести реализацию методов закраски?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


получилось нарисовать фигуру и вращать её, вот только с соединениями линий - путаница.... где ошибка?

uses Graph,crt;
const tetr: array[0..11] of real =
(-1,-1,-1,-1,-1,1,-1,1,-1,
-1,1,1);
line_: array[0..11] of integer = (0,1,0,4,0,2,1,3,1,5,2,3);
var xt,yt,zt:real;
x,y,z:real;
sx,sy,sx1,sy1,p,zoom: integer;

procedure draw(color:byte);
begin
for p:=0 to 5 do begin
sx:=round(zoom*tetr[line_[p*2]*3])+260;
sy:=round(zoom*tetr[line_[p*2]*3+1])+300;
sx1:=round(zoom*tetr[line_[p*2+1]*3])+260;
sy1:=round(zoom*tetr[line_[p*2+1]*3+1])+300;
setcolor(color);
line(SX,SY,sx1,sy1);
end;
end;

procedure calc;
begin
for p:=0 to 3 do begin
Yt := tetr[p*3+1] * COS(X) - tetr[p*3+2] * SIN(X);
Zt := tetr[p*3+1] * SIN(X) + tetr[p*3+2] * COS(X);
tetr[p*3+1] := Yt;
tetr[p*3+2] := Zt;

Xt := tetr[p*3] * COS(Y) - tetr[p*3+2] * SIN(Y);
Zt := tetr[p*3] * SIN(Y) + tetr[p*3+2] * COS(Y);
tetr[p*3] := Xt;
tetr[p*3+2] := Zt;

Xt := tetr[p*3] * COS(Z) - tetr[p*3+1] * SIN(Z);
Yt := tetr[p*3] * SIN(Z) + tetr[p*3+1] * COS(Z);
tetr[p*3] := Xt;
tetr[p*3+1] := Yt;
end;
end;


var
gd,gm:integer;
t:char;
begin
gd:=detect; initgraph(gd,gm,'');
Z := 0.1;
Y := 0.1;
X := 0.1;
zoom:=70;

repeat
draw(15);
delay(20000);
draw(0);
calc;
if keypressed then begin
t:=readkey;
case t of
'=':zoom:=zoom+1; {+}
'-': zoom:=zoom-1;{-}
end;
end
until t=#13;;
closegraph;
end.





Сообщение отредактировано: 18192123 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


а как выбрать источник света и как с ним работать?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






Марина, загляни вот сюда:
Dasaev Demo Guide v1.1

Там у него описывается работа с закрасками и по Гуро и по Фонгу...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


Цитата(volvo @ 18.04.2007 0:07) *

Марина, загляни вот сюда:
Dasaev Demo Guide v1.1

Там у него описывается работа с закрасками и по Гуро и по Фонгу...

зашла по ссылке, скачала архив, но там полная ерунда - нужные файлы, где должны быть исходники, содержат только набор разных символов!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


а может есть ещё что-то такое?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


Нашла вот такую программу для закраски тетраэдра:


program lab5;
uses graph,crt;
const n=8;
procedure draw;
label
nextj;
type
tetr=array[1..n] of record x,y,z:integer end;
const
verts : tetr=(
(x:-1; y:1; z:1),
(x:1; y:1; z:1),
(x:-1; y:1; z:-1),
(x:-1; y:-1; z:1),
(x:1;y:-1;z:-1),
(x:1;y:-1;z:1),
(x:1;y:1;z:-1),
(x:-1;y:-1;z:-1) );
g:array[1..n,1..4] of shortint=
(
(1,4,2,3),
(1,3,2,4),
(3,4,2,1),
(4,1,3,2),
(2,4,1,3),
(3,2,4,1),
(2,4,3,1),
(4,1,2,3));
var
alfa,beta,gamma,
teta,
dt:real;
c:tetr;
procedure rotate(var x,y,z:integer);
var
cost,sint,one_cost,aone_cost,bone_cost,gsint:real;
xn,yn,zn:integer;
begin
cost:=cos(teta);
sint:=sin(teta);
one_cost:=1.0-cost;
aone_cost:=alfa*one_cost;
bone_cost:=beta*one_cost;
gsint:=gamma*sint;

xn:=trunc(
x*(cost +alfa*aone_cost)+
y*(gsint +beta *aone_cost)+
z*(-beta*sint +gamma*aone_cost));
yn:=trunc(
x*(-gsint+ beta*aone_cost)+
y*(cost +beta*bone_cost)+
z*(alfa*sint + gamma*bone_cost));
zn:=trunc(
x*(beta*sint + gamma*aone_cost)+
y*(-alfa*sint +gamma *bone_cost)+
z*(-beta*sint +gamma*one_cost));
x:=xn;y:=yn;z:=zn;
end;
function minz:integer;
var j,m:integer;
begin
m:=1;
for j:=1 to n do
if c[j].z<c[m].z then m:=j;
minz:=m;
end;
var
pnts:array[1..n] of record
x,y:integer end ;
min:integer;
x0,y0:integer;
a:integer;
i,j,k:integer;
page:word;
begin
page:=0;
x0:=300;
y0:=150;
a:=70;
alfa:=0.6;
beta:=0.7;
gamma:=sqrt(1.0-alfa*alfa-beta*beta);
teta:=0;
dt:=2*pi/100; for i:=1 to n do
begin
c[i].x:=verts[i].x*a;
c[i].y:=verts[i].y*a;
c[i].z:=verts[i].y*a;
rotate(c[i].x,c[i].y,c[i].z)
end;
min:=minz;
setvisualpage((page+1)mod 2);
for k:=0 to 2500 do
begin
setactivepage(page);
for j:=1 to 8 do
begin
for i:=1 to 5 do if min=g[j,i] then goto nextj;
for i:=1 to 5 do
begin
pnts[i].x:=x0+c[g[j,i]].x;
pnts[i].y:=y0+trunc(0.775*c[g[j,i]].y)
end;
setfillstyle(solidfill,word(j+4));
fillpoly(3,pnts) ; delay(100);
nextj:
end;
setvisualpage(page);
setactivepage((page+1)mod 2);
for i:=1 to n do
begin
c[i].x:=verts[i].x*a;
c[i].y:=verts[i].y*a;
c[i].z:=verts[i].z*a;
rotate(c[i].x,c[i].y,c[i].z)
end;
min:=minz;cleardevice;
teta:=teta+dt;
page:=(page+1)mod 2;
if keypressed then
exit;
end;
end;
var drv,mode:integer;
begin
drv:=ega;
mode:=egahi;
initgraph(drv,mode,'');
draw;
closegraph;
end.




мне здесь не понятно назначение функции minz, а также что хранится в этом массиве записей и для чего это нужно:

pnts:array[1..n] of record
x,y:integer end ;



а самое главное - не понятна главная часть процедуры Рисование(procedure draw;), каким образом там производится рисование и закраска? пожалуйста, объясните основные моменты этого куска!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


Если тетраэдр с его вершинами и сторонами задаётся таким образом (см. код), то как выбрать два вектора, лежащие в какой-то грани и так для всех граней?

tetr=array[1..n] of record x,y,z:integer end;
const
verts : tetr=(
(x:-1; y:1; z:1),
(x:1; y:1; z:1),
(x:-1; y:1; z:-1),
(x:-1; y:-1; z:1),
(x:1;y:-1;z:-1),
(x:1;y:-1;z:1),
(x:1;y:1;z:-1),
(x:-1;y:-1;z:-1) );
g:array[1..n,1..4] of shortint=
(
(1,4,2,3),
(1,3,2,4),
(3,4,2,1),
(4,1,3,2),
(2,4,1,3),
(3,2,4,1),
(2,4,3,1),
(4,1,2,3));




Сообщение отредактировано: 18192123 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


и что значит "нормировать" вектор? ( как это производится?)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Профи
****

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

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


Вот еще с далеких фидошных времен откопался примерчик заливки по фонгу, думаю поможет: Прикрепленный файл  PHONG.RAR ( 9.58 килобайт ) Кол-во скачиваний: 365
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


Цитата(Malice @ 19.04.2007 22:55) *

Вот еще с далеких фидошных времен откопался примерчик заливки по фонгу, думаю поможет: Прикрепленный файл  PHONG.RAR ( 9.58 килобайт ) Кол-во скачиваний: 365


Спасибо!
Но лучше уж я с чистого листа начну....
Вопросы из сообщений 8 и 9 до сих пор для меня не ясны...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


Цитата(18192123 @ 20.04.2007 0:26) *

Спасибо!
Но лучше уж я с чистого листа начну....
Вопросы из сообщений 8 и 9 до сих пор для меня не ясны...

Почему никто не хочет мне этого объяснить на моём примере?
Я хочу сделать сама, но мне нужно вначале понять, как начинать, а начинать нужно с взятия нормалей, нахождения их векторного произведения и нормирования полученного вектора....
Ну не пойму я, как выбрать в начале вектора!
( а в программе, которую оставил Malice для меня всё не понятно! Да и объёмчик внушительный!)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Цитата(18192123 @ 19.04.2007 22:49) *

и что значит "нормировать" вектор? ( как это производится?)

Я думаю, нормировать - это значит сделать так, чтобы его длина была равна 1, сохранив направление прежним.


Добавлено через 2 мин.
Цитата(18192123 @ 19.04.2007 19:19) *

задаётся таким образом (см. код),

Мне непонятен способ задания тетраедра. Это вершины? или что?
Поясни, пожалуйста.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


Цитата(Lapp @ 20.04.2007 9:18) *

Я думаю, нормировать - это значит сделать так, чтобы его длина была равна 1, сохранив направление прежним.

blink.gif никогда о таком не слышала...а можно показать на примере, как это сделать?

Добавлено через 7 мин.
Цитата(Lapp @ 20.04.2007 9:18) *


Мне непонятен способ задания тетраедра. Это вершины? или что?
Поясни, пожалуйста.

х, у, z - это вершины
g:array[1..n,1..4] - линии

но мне кажется ,что лучше задавать эти величины так ,как я пыталась выше (не совсем удачно..)

const tetr: array[0..11] of real =
(-1,-1,-1,-1,-1,1,-1,1,-1,
-1,1,1);
line_: array[0..11] of integer = (0,1,0,4,0,2,1,3,1,5,2,3);



у меня тут линий не хватает вроде...
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Цитата(18192123 @ 20.04.2007 9:21) *

blink.gif никогда о таком не слышала...а можно показать на примере, как это сделать?

Ai'=Ai/|A|

Остальное позже. Машина в ремонте, автобус уходит.. smile.gif


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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


Цитата(Lapp @ 20.04.2007 9:37) *

Ai'=Ai/|A|

Остальное позже. Машина в ремонте, автобус уходит.. smile.gif


|A| - поясни пожалуйста, это модуль чего? (без i)
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Уникум
*******

Группа: Пользователи
Сообщений: 6 823
Пол: Мужской
Реальное имя: Лопáрь (Андрей)

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


Цитата(18192123 @ 20.04.2007 9:48) *

|A| - поясни пожалуйста, это модуль чего? (без i)

Модуль вектора А.


--------------------
я - ветер, я северный холодный ветер
я час расставанья, я год возвращенья домой
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Профи
****

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

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


Цитата(18192123 @ 19.04.2007 13:10) *

мне здесь не понятно назначение функции minz

поиск минимальной Z-координаты

Цитата(18192123 @ 19.04.2007 13:10) *

а также что хранится в этом массиве записей и для чего это нужно:

pnts:array[1..n] of record
x,y:integer end ;


а самое главное - не понятна главная часть процедуры Рисование(procedure draw;), каким образом там производится рисование и закраска? пожалуйста, объясните основные моменты этого куска!

pnts- массив всех вершин грани, используется для функции FillPoly, которая выполняет заливку.

Цитата
икогда о таком не слышала...а можно показать на примере, как это сделать?

находишь длину вектора нормали и дельшь все его координаты на длину. Получается вектор длиной =1.

Цитата
у меня тут линий не хватает вроде...

Как бы да smile.gif У тебя всего 4 точки (0..3), а в описаниях граней присутствуют цифры 4 и 5 smile.gif
Вот так попробуй чтоли:
array[0..11] of real =   (1,0,0, 0,1,0, 0,0,1, -0.5,-0.5,-0.5);
line_:array[0..11] of integer = (0,1, 0,2, 0,3, 1,2, 1,3, 2,3);
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

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



procedure draw(color:byte);
begin
for p:=0 to 5 do begin
sx:=round(zoom*tetr[line_[p*2]*3])+260;
sy:=round(zoom*tetr[line_[p*2]*3+1])+300;
sx1:=round(zoom*tetr[line_[p*2+1]*3])+260;
sy1:=round(zoom*tetr[line_[p*2+1]*3+1])+300;
setcolor(color);
line(SX,SY,sx1,sy1);
end;



кусок программы из 2-го поста
что значат такие записи
tetr[line_[p*2]*3])+260
tetr[line_[p*2]*3+1])+300
tetr[line_[p*2+1]*3])+260
tetr[line_[p*2+1]*3+1])+300

а именно, не пойму, для чего *2, *3, прибавляем 1 в разных местах???
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Профи
****

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

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


Цитата(18192123 @ 23.04.2007 22:32) *

а именно, не пойму, для чего *2, *3, прибавляем 1 в разных местах???

Что ж тут не понятного ? Массив Line_ заполнен так [что соединяем, с чем, что, с чем, ..] т.е. на четных местах стоих первая точка, на нечетных - вторая. По-этому p*2-четная точка, p*2+1 следующая, т.е. с которой соединение.
Массив tetr так [x, y, z, x,y,z, и т.д.], принцип тот же..
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

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

 





- Текстовая версия 27.09.2020 12:14
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name