• Добро пожаловать на компьютерный форум Tehnari.ru. Здесь разбираемся с проблемами ПК и ноутбуков: Windows, драйверы, «железо», сборка и апгрейд, софт и безопасность. Форум работает много лет, сейчас он переехал на новый движок, но старые темы и аккаунты мы постарались сохранить максимально аккуратно.

    Форум не связан с магазинами и сервисами – мы ничего не продаём и не даём «рекламу под видом совета». Отвечают обычные участники и модераторы, которые следят за порядком и качеством подсказок.

    Если вы у нас впервые, загляните на страницу о форуме и правила – там коротко описано, как задать вопрос так, чтобы быстро получить ответ. Чтобы создавать темы и писать сообщения, сначала зарегистрируйтесь, а затем войдите под своим логином.

    Не знаете, с чего начать? Создайте тему с описанием проблемы – подскажем и при необходимости перенесём её в подходящий раздел.
    Задать вопрос Новые сообщения Как правильно спросить
    Если пришли по старой ссылке со старого Tehnari.ru – вы на нужном месте, просто продолжайте обсуждение.

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

  • Автор темы Автор темы alexpauk
  • Дата начала Дата начала

alexpauk

Ученик
Регистрация
3 Апр 2012
Сообщения
6
Реакции
0
Баллы
0
Помогите разобраться в исходном коде

Помогите разобраться в исходном коде. Программа написана на 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.x:=x+round(r*cos(a*pi/180));
p.y:=y-round(r*sin(a*pi/180));
end
else
begin
p.x:=x+round(r*cos(a*pi/180)/2);
p.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.x,p.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.


Смысл программы в заполнении области своей заливкой(звёздочками).
Прошу помочь разобраться в исходном коде. Желательно все, что можно.
Буду благодарен за ответы.
 
Мне кажется, желающих написать по абзацу комментариев и разъяснений к каждой строчке не найдется. Задавайте конкретные вопросы (место программы, что непонятно и т.п.).
 
Давайте я прокомментирую, что знаю. А с остальным прошу помочь:


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.x:=x+round(r*cos(a*pi/180)); //вот эта строчка непонятна
p.y:=y-round(r*sin(a*pi/180)); //вот эта строчка непонятна
end
else
begin
p.x:=x+round(r*cos(a*pi/180)/2); //аналогично
p.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.x,p.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.

Спасибо
 
Хорошо, попробую. Только предупреждаю - АВС не знаю, поэтому буду исходить из здравого смысла.
Прежде всего по процедуре рисования звездочки. Тут так:
Код:
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  //вот эта строчка непонятна [COLOR=Red]{если i 
нечетное, то}[/COLOR]
    begin
     p[i].x:=x+round(r*cos(a*pi/180)); //вот эта строчка непонятна
     p[i].y:=y-round(r*sin(a*pi/180));  //вот эта строчка непонятна
    end
[COLOR=Red]{Здесь вычисляются координаты пяти удаленных на 
расстояние r от центра вершин звезды. Угол между ними - 
72°. Если i принимает нечетное значение, то вычисляются 
последовательно X и Y координаты "дальних" пяти точек}[/COLOR]
   else [COLOR=Red]{если i - четное}[/COLOR]
    begin
     p[i].x:=x+round(r*cos(a*pi/180)/2); //аналогично
     p[i].y:=y-round(r*sin(a*pi/180)/2);  //аналогично
    end;
[COLOR=Red]{Аналогично, но для "ближних" пяти вершин, отстоящих от 
центра на расстояние r/2.}[/COLOR]
  a:=a+36;  
 end;
 p[11].x:=p[1].x;   //вот эта строчка непонятна
 p[11].y:=p[1].y;  //вот эта строчка непонятна
[COLOR=Red]{Эти две строки "замыкают" звезду: первая точка (i=1) 
совпадает с последней (i=11)}
 [/COLOR]MoveTo(p[1].x,p[1].y);  //здесь перемещается указатель в координаты [COLOR=Red]{первой 
точки}[/COLOR]
 setpencolor(clred);  //цвет
 for i:=1 to 11 do  //если i равно от 1 до 10 то
  LineTo(p[i].x,p[i].y); //рисует линию, но по каким координатам?
[COLOR=Red]{Оператор LineTo(X,Y) проводит линию из исходного 
положения указателя в точку, координаты которой указаны 
в его параметрах. Таким образом, исходно установив 
указатель в первую точку, вы в течение цикла проходите 
все 11, последовательно соединяя их линией}
 [/COLOR]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); //не понятно условие
{А это просто цикл, располагающий
звезды внутри прямоугольника так, чтобы они шли
последовательно впритык и не перекрывались. Для этого
делается (ужас, вообще-то!!!) перебор по всем пикселам
внутри прямоугольника, и те из них, координаты которых
кратны диаметру описанной вокруг звезды окружности,
принимаются за центры звезд.}
 
Большое спасибо за столь развёрнутый ответ. В некоторых местах, как оказалось, я тупил)))).
 
Помогите разобраться в ещё одной программкой.

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.u:=a.u+0.1;
a.x:=x0+round(k*a.r*cos(a.u));
a.y:=y0-round(a.r*sin(a.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.r:=a.r*k;
a.x:=x0+round(a.r*cos(a.u));
a.y:=y0-round(a.r*sin(a.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.r:=Radius(x1,y1,a.x,a.y);
a.u:=Ugol(x1,y1,a.x,a.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.r:=Radius(x3,y1,c.x,c.y);
c.u:=Ugol(x3,y1,c.x,c.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.r:=Radius(x2,y1,b.x,b.y);
b.u:=Ugol(x2,y1,b.x,b.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.

Здесь меня интересует как задаются координаты буквы и как они изменяются. Пытался что-то сделать - ничего нормального не получилось.
 
Здесь меня интересует как задаются координаты буквы и как они изменяются. Пытался что-то сделать - ничего нормального не получилось.
Ну, даже и не знаю, как тут ответить... Исходные координаты ключевых точек (вершин) каждой из трех литер задаются в явном виде (x,y), кроме того, считаются длины и углы наклона к оси Х радиус-векторов, проведенных из центра литеры к вершинам. Потом при повороте или растяжении (сжатии) меняются эти радиусы и углы, и уже исходя из новых их значений рассчитываются новые декартовы координаты вершин с последующим соединением их линиями.
Не знаю, впрочем, стало ли понятнее...
 
Относительно понятно.
Вроде координаты задаются здесь для буквы А:

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;

Как поменять эту букву на другую?
 
Это понятно, но по какому алгоритму они изменяются?
 
Это понятно, но по какому алгоритму они изменяются?
Да ни по какому особому алгоритму. Задаете координаты центра, и относительно центра - смещение по вертикальной и горизонтальной осям всех вершин.
Ну хорошо, рассмотрим, например, построение буквы "О". Изобразим ее как вытянутый в вертикальном направлении прямоугольник высотой 2*D1 и шириной 2*D2 с центром в точке x1, y1. Требуется задать координаты четырех углов, а затем соединить их линиями.
a[1].x:=x1-D2; a[1].y:=y1+D1; {нижний левый угол}
a[2].x:=x1-D2; a[2].y:=y1-D1; {верхний левый угол}
a[3].x:=x1+D2; a[3].y:=y1-D1; {верхний правый угол}
a[4].x:=x1+D2; a[4].y:=y1+D1; {нижний правый угол}
Ну и т.п.
 
за счет изменения коэффициента приращения :)
 
Назад
Сверху