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

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

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

 
 Ответить  Открыть новую тему 
> Сжатие и растяжение графика
сообщение
Сообщение #1


Пионер
**

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

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


Вот значит написал программу выводящую на экран график функции, оси, деление и подпись осей....
Помогите плиз организовать сжатие и растяжение графика вдоль оси Ох: т.е. при нажатии стрелки вправо - растяжение, стрелка влево - сжатие...
Код

uses Crt, Graph;
var
x,y,h:real;
I1,I2,J1,J2,k:integer;
x1,x2,y1,y2:integer;
i,n,j:integer;
s:string;
driver,Regim:integer;

function II(x:real):Integer;
begin
  II:=I1 + Trunc ((x-x1)*(I2-I1)/(x2-x1))
end;

function JJ(y:real):Integer;
begin
  JJ:=J1 + Trunc ((y-y1)*(J2-J1)/(y2-y1))
end;

begin
n:=30;
x1:=-3;x2:=5;
y1:=-7;y2:=2;
I1:=10;I2:=400;
j1:=10;J2:=300;
h:=(x2-x1)/n;
driver:=VGA;
Regim:=1;
InitGraph(Driver,Regim,'');
SetColor(blue);
SetFillStyle(blue,yellow);
Bar(I1,J1,I2,J2);
rectangle(I1,J1,I2,J2);
SetColor(LightRed);

MoveTo(II(x1),JJ(0));LineTo(II(x2),JJ(0));
MoveTo(II(0),JJ(y1));LineTo(II(0),JJ(y2));

for i:=x1 to x2 do
begin
  PutPixel(II(x1+i+3),JJ(0),15);  {cena deleniya}
  str(i,s);
  OutTextXY(II(x1+i+3-0.05),JJ(0.1),s)
end;

for j:=y1 to y2 do   {-5,1}        
begin
  if j=0 then
  else
   begin
    str(-j,s);
    PutPixel(II(0),JJ(y1+j+(-y1)),15);      {думаю, что в этом цикле ошибка}
    OutTextXY(II(0.1),JJ(y1+j+(-y1)),s)
   end
end;

OutTextXY(II(x2),JJ(0.1),'x');
Line(II(x2),JJ(0),II(x2-0.1),JJ(0+0.05));
Line(II(x2),JJ(0),II(x2-0.1),JJ(0-0.05));

OutTextXY(II(-0.2),JJ(y1-0.18),'y');
Line(II(0),JJ(y1),II(0.1),JJ(y1+0.15));
Line(II(0),JJ(y1),II(-0.1),JJ(y1+0.15));
SetBkColor(white);
SetColor(green);x:=x1;y:=sqrt(x*x+2);
MoveTo(II(x),JJ(-y));

for i:=1 to n do
begin
   x:=x+h;
   y:=sqrt(x*x+2);
   LineTo(II(x),JJ(-y))
  end;
readln;
closegraph
end.


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


Пионер
**

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

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


Да,я понимаю, что это нудная задачка...Ну, помогите хотя бы правильно обозначить деление осей координат
Я разделил на отрезки, но что-то для Оу-оси деление неправильное. И вообще, я думаю, чтобы справиться с этой задачей, нужно организовать цикл, в котором при нажатии стрелок будет увеличиваться(уменьшаться) кол-во делений оси Ох...Что скажете?


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


просто человек
******

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

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


а у тебя тот код, что ты привел, нормально компилируется и работает?

по поводу сжатия/растяжения. я бы хранила какой-то поправочный коэффициент, который бы при нажатии стрелки влево делился на, скажем, 2, а при нажатии вправо - умножался.
при рисовании графика его надо будет учитывать.


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Пионер
**

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

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


Ну,помогите вставить этот кфц. в нужную часть кода...


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


просто человек
******

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

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


ну ты сам хоть попробуй что ли.
для приличия.
и ответь на вопрос.


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


Пионер
**

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

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


Начнем с того, что эту прогу я сам написал. Но, по-моему здесь деление оси Оу выполнено неверно.


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


просто человек
******

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

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


молодец.
у меня твой код НЕ компилируется. Вообще.
потому и спрашиваю - у ТЕБЯ он работает?
Я знаю, что у меня TP на графике иногда глючит не по делу.
Если у тебя работает - буду искать проблемы у себя. Если не работает - приведи его в состояние, чтобы хоть как-то работал.
а ты даже не соизволиваешь ответить.

Цитата
Но, по-моему здесь деление оси Оу выполнено неверно.

что он должнен делать и что делает?


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Michael_Rybak
*****

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

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


Изменения:

1. x1, y1, x2, y2 стали типа real

2. Добавил цикл, о котором ты говоришь ("чтобы справиться с этой задачей, нужно организовать цикл...")

3. В тело цикла перенес инициализацию x1, x2, y1, y2, h и n. Область вывода (I1, J1, I2, J2) остается неизменной, меняется (по x) только часть графика, которую мы туда впихиваем. n меняем, потому что с увеличением масштаба точки улетают высоко вверх, а видимая часть рисуется с плохой детализацией.

4. Вот в этом цикле:

for i:=x1 to x2 do
begin
PutPixel(II(x1+i+3),JJ(0),15); {cena deleniya}
str(i,s);
OutTextXY(II(x1+i+3-0.05),JJ(0.1),s)
end;


Во-первых, добавил округление x1 и x2, т.к. они теперь дробные. Во-вторых, вместо x1+i-3 оставил просто i, потому что x1+3 изначально у тебя равно 0, а при масштабировании нужно было бы тройку домножать на коеффициент. На самом деле это не нужно:

for i:=trunc(x1)-1 to trunc(x2)+1 do
begin
PutPixel(II(i),JJ(0),15); {cena deleniya}
str(i,s);
OutTextXY(II(i-0.05),JJ(0.1),s)
end;


5. То же самое с циклом по Y. Ошибки там, мне кажется, нету. Ты все правильно понял, когда написал y1+j+(-y1). Именно это я имел ввиду в предыдущем пункте.

6. При обработке клавиш курсор_влево и курсов_вправо делаем то, что сказала мисс_граффити


uses Crt, Graph ;
var
x,y,h:real;
I1,I2,J1,J2,k:integer;
x1,x2,y1,y2:real;
i,n,j:integer;
s:string;
driver,Regim:integer;

xkoef: real;

c: char;

function II(x:real):Integer;
begin
II:=I1 + Trunc ((x-x1)*(I2-I1)/(x2-x1))
end;

function JJ(y:real):Integer;
begin
JJ:=J1 + Trunc ((y-y1)*(J2-J1)/(y2-y1))
end;

begin
I1:=10;I2:=400;
j1:=10;J2:=300;
driver:=VGA;
Regim:=1;
InitGraph(driver,regim,'');

xkoef := 1.0;

while true do begin

n:=trunc(30*xkoef);
x1:=-3*xkoef;x2:=5*xkoef;
y1:=-7;y2:=2;
h:=(x2-x1)/n;


SetColor(blue);
SetFillStyle(blue,yellow);
Bar(I1,J1,I2,J2);
rectangle(I1,J1,I2,J2);
SetColor(LightRed);

MoveTo(II(x1),JJ(0));LineTo(II(x2),JJ(0));
MoveTo(II(0),JJ(y1));LineTo(II(0),JJ(y2));

for i:=trunc(x1)-1 to trunc(x2)+1 do
begin
PutPixel(II(i),JJ(0),15); {cena deleniya}
str(i,s);
OutTextXY(II(i-0.05),JJ(0.1),s)
end;

for j:=trunc(y1)-1 to trunc(y2)+1 do {-5,1}
begin
if j=0 then
else
begin
str(-j,s);
PutPixel(II(0),JJ(j),15);
OutTextXY(II(0.1),JJ(j),s)
end
end;

OutTextXY(II(x2),JJ(0.1),'x');
Line(II(x2),JJ(0),II(x2-0.1),JJ(0+0.05));
Line(II(x2),JJ(0),II(x2-0.1),JJ(0-0.05));

OutTextXY(II(-0.2),JJ(y1-0.18),'y');
Line(II(0),JJ(y1),II(0.1),JJ(y1+0.15));
Line(II(0),JJ(y1),II(-0.1),JJ(y1+0.15));
SetBkColor(white);
SetColor(green);x:=x1;y:=sqrt(x*x+2);
MoveTo(II(x),JJ(-y));

for i:=1 to n do
begin
x:=x+h;
y:=sqrt(x*x+2);
LineTo(II(x),JJ(-y))
end;

while true do begin
c := ReadKey;

if Ord( c ) = 27 then
halt;

if Ord( c ) = 0 then begin
c := ReadKey;
if Ord( c ) = 75 then
xkoef := xkoef * 1.2
else if Ord( c ) = 77 then
xkoef := xkoef / 1.2
else
continue;

break;
end;

end;
end;

readln;
closegraph
end.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Пионер
**

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

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


Спасибо, за прекрасное объяснение. Я бы тебе плюсег поставил, но пока не могу
Р.С. Только, когда сжимаем график, остается что-то вроде шлейфа на экране


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


Пионер
**

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

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


Код
while true do begin

Что значит это?


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


просто человек
******

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

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


Цитата(}0pa @ 28.10.2006 19:37) *

Код
while true do begin

Что значит это?

вечный цикл.
правда, из него предусмотрен выход по break
странная конструкция...


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Michael_Rybak
*****

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

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


Цитата
Только, когда сжимаем график, остается что-то вроде шлейфа на экране


У меня "шлейф" остается только снаружи желтого прямоугольника. Если подобрать I1, I2, J1 и J2 так, чтоб он занимал весь экран - след оставаться не будет, потому что мы его каждый раз перерисовываем. Есть вроде функции типа GetMaxX и GetMaxY. Или, если хочешь не на весь экран - сначала закрашивай весь экран каждый раз, а уже потом рисуй все остальное.

Цитата
вечный цикл.
правда, из него предусмотрен выход по break
странная конструкция...


По-моему, совсем не странная. Предположим, нам надо сделать такую последовательность действий:

1) сделать набор действий А
2) если выполняется условие В, прекратить работу
3) сделать набор действий С
4) перейти к шагу 1

Ее можно осуществить либо так:
A();
while B do begin
C();
A();
end;

либо так:

while true do begin
A();
if not B then break;
C();
end;

Второй вариант мне кажется более естественным. Кроме того, если А - целый блок текста, то его придется (в первом случае) либо дублировать, либо выносить в процедуру.

Это один пример. А у нас другой случай - чтобы организовать эту конструкцию по-другому, понадобился бы дополнительный флаг:

repeat
stop:= false;

c := ReadKey;

if Ord( c ) = 27 then
halt;

if Ord( c ) = 0 then begin
c := ReadKey;
if Ord( c ) = 75 then begin
xkoef := xkoef * 1.2;
stop := true;
end else if Ord( c ) = 77 then begin
xkoef := xkoef / 1.2;
stop := true;
end;
end;

until stop;


Так тоже нормально, в принципе. Но мне без флага больше нравится.
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


просто человек
******

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

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


ну, еще бывают циклы с постусловием - это если говорить о первом случае.
  while true do begin
c := ReadKey;
if Ord( с ) = 27 then
halt;
if Ord( c ) = 0 then
begin
c := ReadKey;
if Ord( с ) = 75 then
xkoef := xkoef * 1.2
else
if Ord( с )= 77 then
xkoef := xkoef / 1.2
else
continue;
break;
end;

то есть выход из цикла происходит во вполне определенном случае - при ord( с )=77 или 75. так? почему бы это не сделать while (ord( с )<>77) and (ord( с )<>75), считав заранее первое с?я еще лучше - вообще в постусловие засунуть. Тогда и continue не нужно - мы в любом случае перейдем на следующий проход (кроме с=27, но это совсем другое).
хотя, конечно, лучшая программа - это работающая программа....

Сообщение отредактировано: volvo -


--------------------
Все содержимое данного сообщения (кроме цитат) является моим личным скромным мнением и на статус истины в высшей инстанции не претендует.
На вопросы по программированию, физике, математике и т.д. в аське и личке не отвечаю. Даже "один-единственный раз" в виде исключения!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

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

 





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