1. Заголовок темы должен быть информативным. В противном случае тема удаляется ... 2. Все тексты программ должны помещаться в теги [code=pas] ... [/code], либо быть опубликованы на нашем PasteBin в режиме вечного хранения. 3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали! 4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора). 5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM! 6. Одна тема - один вопрос (задача) 7.Проверяйте программы перед тем, как разместить их на форуме!!! 8.Спрашивайте и отвечайте четко и по существу!!!
Объясните пожалуйста, как на основании ниже приведённой программы закрасить грани тетраэдра ( обычным способом, с помощью FloodFill или SetFillStyle или что-то в этом роде..)?
FloodFill'ом не получится, у тебя линии не соединены, между ними есть промежутки ... Собственно эту проблему я думаю и надо решить, а залить-то уже не сложно.
Должен заливать только верхнюю грань, но так как какая-то из пар линий принадлежащих этому ребру пересекаются не в одной точке, точнее говоря отрезки эти не пересекаются, по этому не создают замкнутого пространства которое можно залить, этого не происходит
--------------------
perl -e 'print for (map{chr(hex)}("4861707079204E6577205965617221"=~/(.{2})/g)), "\n";'
FloodFill'ом не получится, у тебя линии не соединены, между ними есть промежутки ... Собственно эту проблему я думаю и надо решить, а залить-то уже не сложно.
Должен заливать только верхнюю грань, но так как какая-то из пар линий принадлежащих этому ребру пересекаются не в одной точке, точнее говоря отрезки эти не пересекаются, по этому не создают замкнутого пространства которое можно залить, этого не происходит
FloodFill'ом не получится, у тебя линии не соединены, между ними есть промежутки
klem4, скажи, как так может случиться, что ты проводишь линии между тремя точками, и эти линии не пересекаются?.. Я не могу представить себе такую ситуацию..
Конечно, Марина в своем репертуаре - наворочала так, что конь ногу сломит.. Задавать координаты таким образом - это все равно, что назвать своих детей номерами, а потом еще домашних животных в эту же нумерацию свалить.. Если что-то советовать, то нужно советовать именно как это исправить. А точки - они точки и есть. Хотя Марина их и вычисляет по нескольку раз, все равно должно получиться замкнутое пространство. У меня, кстати, так все и отрисовалось. klem4, у тебя не так? и ты вставлял код заливки после процедуры Draw(15)? Я не понимаю, почему.. странно... Стирать нужно кодом:
Вот только работает это страшно медленно... Поэтому все же лучше использовать не FloodFill, а FillPoly (присоединяюсь к словам volvo - но, повторяю, только для ускорения и упрощения). Помимо прочего, отпадет неопределенность с выбором точки начала заполнения (очень существенно!!).
Еще один вопрос - как выделить верхние грани. Но мне кажется, Марина уже интересовалась им..
--------------------
я - ветер, я северный холодный ветер я час расставанья, я год возвращенья домой
Чтоб закрасить грань, надо внесть в прогу такое понятие. Т.е. заменить твой массив line_, в котором точки сгруппированы по 2, на массив граней, где группировка по 3 точки. Вот так например:
grn: array [0..11] of integer = (0,1,2, 0,1,3, 0,2,3, 1,2,3);
В этом случае процедура отрисоки поменяется например так:
procedure draw(color:byte);
var j,p:integer;
begin
setcolor(color);
for p:=0to3dobegin
sx1:=round(zoom*tetr[grn[p*2]*3])+260;
sy1:=round(zoom*tetr[grn[p*2]*3+1])+300;
for j:=1to2dobegin
sx:=round(zoom*tetr[grn[p*2+j]*3])+260;
sy:=round(zoom*tetr[grn[p*2+j]*3+1])+300;
line(SX,SY,sx1,sy1);
sx1:=sx; sy1:=sy;
end;
end;
end;
Правда для заливки тебе эта процедура не понадобится Твои следующие шаги: После поворота всех точек необходимо найти расстояние от наблюдателя до грани (до средней точки просто). Далее отрисовываешь все грани, начиная с самой удаленной. Самую дальнюю, кстати, можно вообще не рисовать, т.к. из 4-х граней в 1 момент может быть видно только 3.
решила сделать сначала... добилась заливки граней, но тетраэдра у меня не получается.... я полагаю, дело в неправильном соединении точек грани, это здесь:
with gran[1] dobegin a:=1;b:=2;c:=4;cl:=9;end;
with gran[2] dobegin a:=2;b:=4;c:=3;cl:=9;end;
with gran[3] dobegin a:=3;b:=4;c:=1;cl:=9;end;
with gran[4] dobegin a:=1;b:=2;c:=3;cl:=9;end;
здесь а, b, с - номера точек для каждой грани, а с помощью таких преобразований я и пытаюсь задать грани и их цвет.
вот вся программа:
Program Tetr_5;
Uses crt,graph;
Type
Tetr=record
mass1:array [1..4] ofrecord
x3d,y3d,z3d:real;
x2,y2:integer;
xold,yold:integer;
end;
gran:array [1..4] ofrecord
a,b,c:integer;
cl:integer;
end;
npixel:integer;
plosk:integer;
end;
matr=array [1..4,1..4] of real;
const S=150;
procedure otobragenie(var f:tetr);
var
n:integer;
t:array [1..3] of pointtype;
const
EYEY=400;
EYEL=200;
beginwith f dofor n:=1to npixel dowith mass1[n] dobegin
xold:=x2;yold:=y2;
x2:=trunc(x3d*EYEL/(z3d-EYEY));
y2:=trunc(y3d*EYEL/(z3d-EYEY));
end;
setcolor(0);
setfillstyle(1,0);
with f dofor n:=1to plosk dobegin
t[1].x:=300+mass1[gran[n].a].xold;t[1].y:=200-mass1[gran[n].a].yold;
t[2].x:=300+mass1[gran[n].b].xold;t[2].y:=200-mass1[gran[n].b].yold;
t[3].x:=300+mass1[gran[n].c].xold;t[3].y:=200-mass1[gran[n].c].yold;
fillpoly(3,t);
end;
setcolor(0);
with f dofor n:=1to plosk dobegin
setfillstyle(1,gran[n].cl);
t[1].x:=300+mass1[gran[n].a].x2;t[1].y:=200-mass1[gran[n].a].y2;
t[2].x:=300+mass1[gran[n].b].x2;t[2].y:=200-mass1[gran[n].b].y2;
t[3].x:=300+mass1[gran[n].c].x2;t[3].y:=200-mass1[gran[n].c].y2;
fillpoly(3,t);
end;
end;
procedure preobraz(var f:tetr;m:matr);
var
nx,ny,nz:real;
n:integer;
beginfor n:=1to f.npixel dowith f.mass1[n] dobegin
nx:=m[1,1]*x3d+m[1,2]*y3d+m[1,3]*z3d+m[1,4];
ny:=m[2,1]*x3d+m[2,2]*y3d+m[2,3]*z3d+m[2,4];
nz:=m[3,1]*x3d+m[3,2]*y3d+m[3,3]*z3d+m[3,4];
x3d:=nx;y3d:=ny;z3d:=nz;
end;
end;
procedure smeshenie(var mm:matr);
var n,m:integer;
beginfor n:=1to4dofor m:=1to4doif (n<>m) then mm[n,m]:=0else mm[n,m]:=1;
end;
procedure rotate(var m:matr;a:real;n:integer);
var
ax1,ax2:integer;
begin
smeshenie(m);
ax1:=n+1;if ax1=4then ax1:=1;
ax2:=ax1+1;if ax2=4then ax2:=1;
m[ax1,ax1]:=cos(a);
m[ax1,ax2]:=-sin(a);
m[ax2,ax1]:=sin(a);
m[ax2,ax2]:=cos(a);
end;
var
drv,mode:integer;
c:char;
fg:tetr;
rt:matr;
begin
drv:=DETECT;
mode:=VGAHI;
initgraph(drv,mode,'');
if (GraphResult=grOk) thenbeginwith fg dobegin
npixel:=4;
plosk:=4;
mass1[1].x3d:=S;mass1[1].y3d:=0;mass1[1].z3d:=0;
mass1[2].x3d:=0;mass1[2].y3d:=S;mass1[2].z3d:=0;
mass1[3].x3d:=-S;mass1[3].y3d:=0;mass1[3].z3d:=0;
mass1[4].x3d:=0;mass1[4].y3d:=-S;mass1[4].z3d:=0;
with gran[1] dobegin a:=1;b:=2;c:=4;cl:=9;end;
with gran[2] dobegin a:=2;b:=4;c:=3;cl:=9;end;
with gran[3] dobegin a:=3;b:=4;c:=1;cl:=9;end;
with gran[4] dobegin a:=1;b:=2;c:=3;cl:=9;end;
end;
rotate(rt,0.25,1);
preobraz(fg,rt);
rotate(rt,0.13,2);
repeat
otobragenie(fg);
delay(10000);
preobraz(fg,rt);
if (keypressed) thenbegin
c:=readkey;
endelse c:=' ';
until c=#27;
closegraph;
endelsebegin
writeln;
writeln('Error initialize !!!');
end;
end.
спасибо большое! вроде разобралась, только не понятен вот этот фрагмент. Объясни пожалуйста.
Это как раз сортировка: берем 3 координаты Z вершин грани после поворота и делим на 3, получает среднее расстояние до грани. Сравниваем по таким значениям все и сортируем.