Технический форум
Вернуться   Технический форум > Программирование > Форум программистов > Помощь студентам


Ответ
 
Опции темы Опции просмотра
Старый 03.04.2012, 14:26   #1 (permalink)
alexpauk
Новичок
 
Регистрация: 03.04.2012
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию Помогите разобраться в исходном коде

Помогите разобраться в исходном коде. Программа написана на PascalABC.NET

uses graphABC;
type Tpoint=record //пишем свой тип точка, он вообще-то есть в АВС,
//но нужно подключать модуль PointRect
x,y:integer;
end;
procedure Zvezda(x,y,r:integer);//рисование звезды
var i,a:integer;
p:array[1..11] of Tpoint;
begin
a:=18;
for i:=1 to 10 do
begin
if odd(i) then
begin
p[i].x:=x+round(r*cos(a*pi/180));
p[i].y:=y-round(r*sin(a*pi/180));
end
else
begin
p[i].x:=x+round(r*cos(a*pi/180)/2);
p[i].y:=y-round(r*sin(a*pi/180)/2);
end;
a:=a+36;
end;
p[11].x:=p[1].x;
p[11].y:=p[1].y;
MoveTo(p[1].x,p[1].y);
setpencolor(clred);
for i:=1 to 11 do
LineTo(p[i].x,p[i].y);
floodfill(x,y,clgreen);
end;
var xc,yc,x,y,w,h,r1,r:integer;
begin
xc:=windowwidth div 2;
yc:=windowheight div 2;
w:=200;
h:=100;
r:=round(w/30);
setpencolor(clGreen);
rectangle(xc-w,yc-h,xc+w,yc+h);
for x:=xc-w+r to xc+w-r do
for y:=yc-h+r to yc+h-r do
if (x mod (2*r)=0)and(y mod (2*r)=0) then Zvezda(x,y,r);
end.


Смысл программы в заполнении области своей заливкой(звёздочками).
Прошу помочь разобраться в исходном коде. Желательно все, что можно.
Буду благодарен за ответы.
alexpauk вне форума   Ответить с цитированием

Старый 03.04.2012, 14:26
Helpmaster
Member
 
Аватар для Helpmaster
 
Регистрация: 08.03.2016
Сообщений: 0

Может быть на нашем форуме проблема уже решена, попробуйте посмотреть в похожих темах

Помогите разобраться
Помогите разобраться

Старый 03.04.2012, 15:03   #2 (permalink)
Vladimir_S
Специалист
 
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
По умолчанию

Мне кажется, желающих написать по абзацу комментариев и разъяснений к каждой строчке не найдется. Задавайте конкретные вопросы (место программы, что непонятно и т.п.).
Vladimir_S вне форума   Ответить с цитированием
Старый 03.04.2012, 15:13   #3 (permalink)
alexpauk
Новичок
 
Регистрация: 03.04.2012
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

Давайте я прокомментирую, что знаю. А с остальным прошу помочь:


uses graphABC;
type Tpoint=record //пишем свой тип точка, он вообще-то есть в АВС,
//но нужно подключать модуль PointRect
x,y:integer;
end;
procedure Zvezda(x,y,r:integer);//это создание своей процедуры
var i,a:integer;
p:array[1..11] of Tpoint; // массив от 1 до 11
begin
a:=18;
for i:=1 to 10 do //если i равно от 1 до 10 то
begin
if odd(i) then //вот эта строчка непонятна
begin
p[i].x:=x+round(r*cos(a*pi/180)); //вот эта строчка непонятна
p[i].y:=y-round(r*sin(a*pi/180)); //вот эта строчка непонятна
end
else
begin
p[i].x:=x+round(r*cos(a*pi/180)/2); //аналогично
p[i].y:=y-round(r*sin(a*pi/180)/2); //аналогично
end;
a:=a+36;
end;
p[11].x:=p[1].x; //вот эта строчка непонятна
p[11].y:=p[1].y; //вот эта строчка непонятна
MoveTo(p[1].x,p[1].y); //здесь перемещается указатель в координаты
setpencolor(clred); //цвет
for i:=1 to 11 do //если i равно от 1 до 10 то
LineTo(p[i].x,p[i].y); //рисует линию, но по каким координатам?
floodfill(x,y,clgreen); //закрашивает область зелёным
end;
var xc,yc,x,y,w,h,r1,r:integer;
begin
xc:=windowwidth div 2; //вот эта строчка непонятна
yc:=windowheight div 2; //аналогично
w:=200;
h:=100;
r:=round(w/30); //похоже здесь что-то округляется
setpencolor(clGreen); //закрашивает зелёным
rectangle(xc-w,yc-h,xc+w,yc+h); //вот эта строчка непонятна
for x:=xc-w+r to xc+w-r do //вот эта строчка непонятна
for y:=yc-h+r to yc+h-r do //аналогично
if (x mod (2*r)=0)and(y mod (2*r)=0) then Zvezda(x,y,r); //не понятно условие
end.

Спасибо
alexpauk вне форума   Ответить с цитированием
Старый 03.04.2012, 16:22   #4 (permalink)
Vladimir_S
Специалист
 
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
По умолчанию

Хорошо, попробую. Только предупреждаю - АВС не знаю, поэтому буду исходить из здравого смысла.
Прежде всего по процедуре рисования звездочки. Тут так:
Код:
procedure Zvezda(x,y,r:integer);//это создание своей процедуры
var 
 i,a:integer;
 p:array[1..11] of Tpoint; // массив от 1 до 11
begin
 a:=18; 
 for i:=1 to 10 do //если i равно от 1 до 10 то
  begin
   if odd(i) then  //вот эта строчка непонятна {если i 
нечетное, то}
    begin
     p[i].x:=x+round(r*cos(a*pi/180)); //вот эта строчка непонятна
     p[i].y:=y-round(r*sin(a*pi/180));  //вот эта строчка непонятна
    end
{Здесь вычисляются координаты пяти удаленных на 
расстояние r от центра вершин звезды. Угол между ними - 
72°. Если i принимает нечетное значение, то вычисляются 
последовательно X и Y координаты "дальних" пяти точек}
   else {если i - четное}
    begin
     p[i].x:=x+round(r*cos(a*pi/180)/2); //аналогично
     p[i].y:=y-round(r*sin(a*pi/180)/2);  //аналогично
    end;
{Аналогично, но для "ближних" пяти вершин, отстоящих от 
центра на расстояние r/2.}
  a:=a+36;  
 end;
 p[11].x:=p[1].x;   //вот эта строчка непонятна
 p[11].y:=p[1].y;  //вот эта строчка непонятна
{Эти две строки "замыкают" звезду: первая точка (i=1) 
совпадает с последней (i=11)}
 MoveTo(p[1].x,p[1].y);  //здесь перемещается указатель в координаты {первой 
точки}
 setpencolor(clred);  //цвет
 for i:=1 to 11 do  //если i равно от 1 до 10 то
  LineTo(p[i].x,p[i].y); //рисует линию, но по каким координатам?
{Оператор LineTo(X,Y) проводит линию из исходного 
положения указателя в точку, координаты которой указаны 
в его параметрах. Таким образом, исходно установив 
указатель в первую точку, вы в течение цикла проходите 
все 11, последовательно соединяя их линией}
 floodfill(x,y,clgreen); //закрашивает область зелёным
end;
Цитата:
xc:=windowwidth div 2; //вот эта строчка непонятна
yc:=windowheight div 2; //аналогично
{Вычисляются
координаты центра рисунка, равные полуширине (по X) и
полувысоте (по Y) графического окна. Чего же тут
непонятного?}
Цитата:
r:=round(w/30); //похоже здесь что-то округляется
{Угу. Ищется радиус окружности, в
которую вписана звезда, составляющий 1/30 полуширины
окна}

Цитата:
rectangle(xc-w,yc-h,xc+w,yc+h); //вот эта строчка непонятна
{А мне, признаться, непонятно, чего тут
может быть непонятного. Рисуется прямоугольник размером
2*w x 2*h; в качестве параметров подставляются, как это
положено, координаты противолежащих по диагонали
вершин: центр-полуширина, центр-полувысота,
центр+полуширина, центр+полувысота}

Цитата:
for x:=xc-w+r to xc+w-r do //вот эта строчка непонятна
for y:=yc-h+r to yc+h-r do //аналогично
if (x mod (2*r)=0)and(y mod (2*r)=0) then Zvezda(x,y,r); //не понятно условие
{А это просто цикл, располагающий
звезды внутри прямоугольника так, чтобы они шли
последовательно впритык и не перекрывались. Для этого
делается (ужас, вообще-то!!!) перебор по всем пикселам
внутри прямоугольника, и те из них, координаты которых
кратны диаметру описанной вокруг звезды окружности,
принимаются за центры звезд.}
Vladimir_S вне форума   Ответить с цитированием
Старый 03.04.2012, 21:18   #5 (permalink)
alexpauk
Новичок
 
Регистрация: 03.04.2012
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

Большое спасибо за столь развёрнутый ответ. В некоторых местах, как оказалось, я тупил)))).
alexpauk вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Старый 05.04.2012, 10:31   #6 (permalink)
alexpauk
Новичок
 
Регистрация: 03.04.2012
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

Помогите разобраться в ещё одной программкой.

uses graphABC;
type tochka=record
x,y:integer;
u,r:real;
end;
bukva=array[1..20] of tochka;
{угол между лучем и осью Х}
function Ugol(x0,y0,x,y:integer):real;
begin
if (x>x0)and(y<=y0) then Ugol:=arctan((y0-y)/(x-x0)){I четверть}
else if (x>x0)and(y>y0) then Ugol:=arctan((y0-y)/(x-x0))+2*pi{IV четверть}
else if x<x0 then Ugol:=arctan((y0-y)/(x-x0))+pi{II-III четверти}
else if x=x0 then
begin
if y<y0 then Ugol:=pi/2{вертикально вверх}
else if y>y0 then Ugol:=3*pi/2{вертикально вниз}
{else Ugol:=0{центр координат, здесь не нужно}
end;
end;
function Radius(x1,y1,x2,y2:integer):real;
begin
Radius:=sqrt(sqr(x1-x2)+sqr(y1-y2));
end;

{вращение точки вокруг центра}
procedure Vrach(x0,y0,n,k:integer;var a:bukva);
var i:integer;
begin
for i:=1 to n do
begin
a[i].u:=a[i].u+0.1;
a[i].x:=x0+round(k*a[i].r*cos(a[i].u));
a[i].y:=y0-round(a[i].r*sin(a[i].u));
end;
end;

{расширение и сжатие фигуры}
procedure Rash(x0,y0,n:integer;k:real;var a:bukva);
var i:integer;
begin
for i:=1 to n do
begin
a[i].r:=a[i].r*k;
a[i].x:=x0+round(a[i].r*cos(a[i].u));
a[i].y:=y0-round(a[i].r*sin(a[i].u));
end;
end;
{буква А}
procedure AA(x,y:integer;a:bukva;c:Color);
begin
setpencolor(c);
line(a[1].x,a[1].y,a[3].x,a[3].y);
line(a[3].x,a[3].y,a[5].x,a[5].y);
line(a[2].x,a[2].y,a[4].x,a[4].y);
end;
{буква Б}
procedure BB(x,y:integer;a:bukva;c:Color);
begin
setpencolor(c);
line(a[1].x,a[1].y,a[3].x,a[3].y);
line(a[3].x,a[3].y,a[4].x,a[4].y);
line(a[2].x,a[2].y,a[5].x,a[5].y);
line(a[5].x,a[5].y,a[6].x,a[6].y);
line(a[1].x,a[1].y,a[6].x,a[6].y);
end;
{буква И}
procedure II(x,y:integer;a:bukva;c:Color);
begin
setpencolor(c);
line(a[1].x,a[1].y,a[2].x,a[2].y);
line(a[1].x,a[1].y,a[3].x,a[3].y);
line(a[3].x,a[3].y,a[4].x,a[4].y);
end;
var a,b,c:bukva;
x1,x2,x3,y1,i,d:integer;
u,k:real;
begin
x1:=windowwidth div 4;
y1:=windowheight div 2;
d:=x1 div 4;
a[1].x:=x1-d;a[1].y:=y1+d;
a[3].x:=x1;a[3].y:=y1-d;
a[5].x:=x1+d;a[5].y:=y1+d;
a[2].x:=(a[1].x+a[3].x) div 2;
a[2].y:=(a[1].y+a[3].y) div 2;
a[4].x:=(a[5].x+a[3].x) div 2;
a[4].y:=a[2].y;
for i:=1 to 5 do
begin
a[i].r:=Radius(x1,y1,a[i].x,a[i].y);
a[i].u:=Ugol(x1,y1,a[i].x,a[i].y);
end;
x3:=windowwidth-x1;
c[1].x:=x3-d;c[1].y:=y1+d;
c[2].x:=x3-d;c[2].y:=y1-d;
c[3].x:=x3+d;c[3].y:=y1-d;
c[4].x:=x3+d;c[4].y:=y1+d;
for i:=1 to 4 do
begin
c[i].r:=Radius(x3,y1,c[i].x,c[i].y);
c[i].u:=Ugol(x3,y1,c[i].x,c[i].y);
end;
x2:=2*x1;
b[1].x:=x2-d;b[1].y:=y1+d;
b[2].x:=x2-d;b[2].y:=y1;
b[3].x:=x2-d;b[3].y:=y1-d;
b[4].x:=x2+d;b[4].y:=y1-d;
b[5].x:=x2+d;b[5].y:=y1;
b[6].x:=x2+d;b[6].y:=y1+d;
for i:=1 to 6 do
begin
b[i].r:=Radius(x2,y1,b[i].x,b[i].y);
b[i].u:=Ugol(x2,y1,b[i].x,b[i].y);
end;
AA(x1,y1,a,clRed);
BB(x2,y1,b,clBlue);
II(x3,y1,c,clGreen);
k:=1.1;
u:=0;
lockdrawing;
repeat
clearwindow;
Vrach(x1,y1,5,-1,a);
Vrach(x3,y1,4,1,c);
Rash(x2,y1,6,k,b);
if b[3].x<=x2-2*d then k:=0.9;
if b[3].x>=x2-d div 2 then k:=1.1;
AA(x1,y1,a,clRed);
BB(x2,y1,b,clBlue);
II(x3,y1,c,clGreen);
sleep(100);
redraw;
u:=u+0.1;
until u>100;
end.

Здесь меня интересует как задаются координаты буквы и как они изменяются. Пытался что-то сделать - ничего нормального не получилось.
alexpauk вне форума   Ответить с цитированием
Старый 05.04.2012, 11:04   #7 (permalink)
Vladimir_S
Специалист
 
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
По умолчанию

Цитата:
Сообщение от alexpauk Посмотреть сообщение
Здесь меня интересует как задаются координаты буквы и как они изменяются. Пытался что-то сделать - ничего нормального не получилось.
Ну, даже и не знаю, как тут ответить... Исходные координаты ключевых точек (вершин) каждой из трех литер задаются в явном виде (x,y), кроме того, считаются длины и углы наклона к оси Х радиус-векторов, проведенных из центра литеры к вершинам. Потом при повороте или растяжении (сжатии) меняются эти радиусы и углы, и уже исходя из новых их значений рассчитываются новые декартовы координаты вершин с последующим соединением их линиями.
Не знаю, впрочем, стало ли понятнее...
Vladimir_S вне форума   Ответить с цитированием
Старый 05.04.2012, 12:01   #8 (permalink)
alexpauk
Новичок
 
Регистрация: 03.04.2012
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

Относительно понятно.
Вроде координаты задаются здесь для буквы А:

a[1].x:=x1-d;a[1].y:=y1+d;
a[3].x:=x1;a[3].y:=y1-d;
a[5].x:=x1+d;a[5].y:=y1+d;
a[2].x:=(a[1].x+a[3].x) div 2;
a[2].y:=(a[1].y+a[3].y) div 2;
a[4].x:=(a[5].x+a[3].x) div 2;
a[4].y:=a[2].y;

Как поменять эту букву на другую?
alexpauk вне форума   Ответить с цитированием
Старый 05.04.2012, 15:50   #9 (permalink)
Vladimir_S
Специалист
 
Регистрация: 27.08.2008
Адрес: Санкт-Петербург
Сообщений: 27,807
Сказал(а) спасибо: 340
Поблагодарили 583 раз(а) в 208 сообщениях
Репутация: 113184
По умолчанию

Цитата:
Сообщение от alexpauk Посмотреть сообщение
Как поменять эту букву на другую?
Расписать координаты вершин другой буквы.
Vladimir_S вне форума   Ответить с цитированием
Старый 05.04.2012, 17:42   #10 (permalink)
alexpauk
Новичок
 
Регистрация: 03.04.2012
Сообщений: 6
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 10
По умолчанию

Это понятно, но по какому алгоритму они изменяются?
alexpauk вне форума   Ответить с цитированием
Ads

Яндекс

Member
 
Регистрация: 31.10.2006
Сообщений: 40200
Записей в дневнике: 0
Сказал(а) спасибо: 0
Поблагодарили 0 раз(а) в 0 сообщениях
Репутация: 55070
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.
Trackbacks are Вкл.
Pingbacks are Вкл.
Refbacks are Выкл.




Часовой пояс GMT +4, время: 07:59.

Powered by vBulletin® Version 6.2.5.
Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.