Помощь - Поиск - Пользователи - Календарь
Полная версия: График функции
Форум «Всё о Паскале» > Pascal, Object Pascal > Задачи
Кина
Очень прошу помочь :o
Программа выводит сетку координат и метрическую сетку (разными цветами). Оси должны быть с графическими отметками и названиями. Рисует график y=x*x*x*Ln|x*x-4|. Если нажать мышкой на линию графика - отображаются координаты этой точки. Допускается использовать только вывод точки и получение координат. Возможность распечатки на матричном принтере.
Altair
Вот здесь есть шаблон для построения графика.

Только вместо y:=abs(x/(x-2))-1; написать y:=x*x*x*ln(abs(x*x-4));

Далее - здесь есть вся информация о программировании мыши.
Кина
Спасибо
Можно пару вопросов?
1. Я никак не могу понять как пересчитывать координаты из нормальных в графические (кстати, надо будет и обратно пересчитывать, координаты, полученные мышкой - хотя совершенно не представляю, как их передать в программу).
2. Функция getnum не компилируется, а остальные, связанные с мышью не работают sad.gif Вообщем, я явно чего-то не понимаю...
Программа пока выглядит так:
Код

{$N+}
{$E+}
{$X+}
uses graph,crt;
const
x0=500; {начало координат}
y0=400;
mtrx=10;
mtry=10;
shag=0.0001;
var
gm,gd:integer;
x1,y1,i, j:integer;
xmin, xmax, ax :real;
x,y:real;
sx, sy: integer;
 Coord: String;



Procedure ShowMouse; assembler; {показать мышь}
Asm
Mov AX,$01
Int $33
end;

{procedure get_mouse_status(var button: Byte: var x, y: Word);
begin
regs.AX:=$03;
intr($33, regs);
with regs do
button:=BL;
x:=CX;
y:=DX;
end;
end;


{Function getnum(num, {var x,y: real):word; {получить координаты при нажатии кнопки мыши}
{var
kn:word;
begin
asm
mov ax,$05
mov bx,num
int $33
mov x,cx
mov y,dx
mov kn,bx
end;
leftnum:=kn
end;  }


Function InitMouse:boolean; {Инициализация мыши}
var
ResultRegAX:word;
begin
asm
mov ax,$00
int $33
mov ResultRegAX,ax
end;
If ResultRegAX=$FFFF then InitMouse:=true else InitMouse:=false
End;

{function gx(x:real; sx:Integer):integer;
begin
gx:=trunc(sx*x)+Getmaxx div 2;
end;

function gy(y:real; sy:Integer):integer;
begin
gy:=trunc(sy*y)+Getmaxy div 2;
end; }



begin


writeln ('Vvedite predely izmeneniya X.');
write ('ot: ');
readln (xmin);
write ('do: ');
readln (xmax);
 gd:=InstallUserDriver('vesa256',nil);
 gm:=3;
 initgraph (gd,gm,'');

{------------------}
setcolor(8);
{Оси}
for i:=0 to 768 do putpixel(x0,i,8);
for i:=0 to 1024 do putpixel(i,y0,8);

OutTextXY(497,0,'^'); OutTextXY(999,397,'>'); {стрелки осей OX, OY}
SetColor(LightGreen);
OutTextXY(480,0,'y'); OutTextXY(999,410,'x');
OutTextXY(505,405,'0');
SetColor(Green); {установка зеленого цвета}
For i:=1 to 20 do {нанесение делений и числовых отметок на ось OY}

begin Str(20*(21-i), Coord); j:=i*20+10;
OutTextXY(2, j-5, Coord);
Line(28, j, 30, j)
end;
For i:=1 to 29 do {нанесение делений и числовых отметок на ось OX}
begin Str(20*i,Coord); j:=i*20+30;
If Odd(i) then OutTextXY(j-8, 436,Coord); Line(j,430, j,432)
end;
SetViewPort(31,4,630,429,FALSE); {установка текущего графического окна}

{sx:=getmaxx div 3 - 10;
sy:=getmaxy div 3 - 10; }
x:=xmin;
repeat
begin
y:=x*x*x*ln(abs(x*x-4));
{putpixel (x0+trunc(x*mtrX),y0-trunc(y*mtrY),yellow);}
{putpixel (gx(x, sx), gy(y,sy), yellow);}
 x:=x+shag;
end;
until x<=xmax;

if initMouse then
Begin
ShowMouse;
{getnum (0,x,y);   }

end;
readkey;
closegraph;
end.




Метрическую сетку и обозначения в нужном месте будут, когда я хоть увижу, как этот график выглядит...
Да, график пытается отображаться почему-то только когда максимум меньше минимума...
volvo
Цитата
Функция getnum не компилируется

Пробуем так:
Код
Function getnum(num:word; var x,y: word):word;
var px, py, kn:word;
begin
asm
mov ax,$05
mov bx,num
int $33
mov px,cx
mov py,dx
mov kn,bx
end;
x := px; y := py;
getnum:=kn
end;


Цитата
остальные, связанные с мышью не работают

А что собственно в этом странного? В ФАКе (откуда взяты все эти функции) есть замечания. Вот первое из них:
Цитата
При использовании некоторых видеодрайверов (например vesa256), в видеорежимах, с большим разрешением экрана (например 1024*768) указатель мыши не отображается.


Насколько я вижу, здесь инициализируется именно VESA256 1024x768... Возможный способ решения проблемы: работа с меньшим разрешением...
Altair
или несовместим компилятор.
В ближайшее время материалы FAQ"a будут отредактированны, в целях повышения совместимости.

Цитата
Я никак не могу понять как пересчитывать координаты из нормальных в графические
Что значит из нормлаьных в графичесике?
INT33h возвращает всегда координаты по пикселам. Это в текстовом режиме 8 пикселей=1 виртуальный.
Кина
2 volvo
Сэнкс
2 Oleg_Z
Пересчет координаты точки, например (2,4), в графические (где будет находится эта точка на экране?), например (468, 234)
Код
 putpixel(zcrtx+trunc(x*mtrX),zcrty-trunc(y*mtrY),colorg) end;

Как составить такую (и обратную) формулу?
FreeMan
Цитата
Возможный способ решения проблемы:

читать координаты и самотужки там рисовать подобие курсора, потом вытирать, снова читать...
Altair
Кина, для перевода из координат точки на экране в координаты относительно графика делаем так:
  • из координат на экране получаем координаты на экарне, но относительно начала координат.
  • вычисляем координаты зная масштаб графика.
Например, то что вы дали.
сначала что я понял.
zcrtx - абсцисса начала координат.
zcrty - ордината начала координат.
mtrX - масштабный коээфициент по X...
ну и по Y соотв.

Тогда "нормальные" получаем из графических (на экране, где мышка кликнула) так:
x=(MouseX-zcrtx) div mtrX;
y=(MouseY-zcrty) div mtrY;

Цитата
(и обратную)
формулу так: (то есть зная нормальные координаты, получаем координаты на экране).
Здесь используем нашу формулу.
Да, еще - когда мышка кликает по графику, следует удостовериться что она кликнула именно по графику, а не на 1 пиксел например, правее.
Это можно реализовать, считав например цвет пиксела по которому кликнула мышка. GetPixel(x,y) вернет значение пиксела...
и сравнив его с цветом графика, узнаем кликнула ли мышка по графику.
Другой способ - сначала преобразовать в нормальные координаты, и подставив в формулу, проверитиь получим ли в экранных координатах точку..
Кина
Oleg_Z Спасибо
Еще мне бы совсем не помешала консультация по печати - никогда не пробовала печатать из графического режима - вообще как задавать параметры печати? (если это имеет значение - принтер Epson LX1050+)
volvo
Кина
Вот процедура... Она будет работать для всех граф. режимов на всех принтерах, воспринимающих систему команд Epson...

Код

Uses Graph, Printer, Crt;

Procedure CopyToPRN( X1, Y1, X2, Y2 : Integer; Bk1, Bk2 : Word;
                    Inverse : Boolean; Mode : Byte );
Var
 ScanLine : Integer;
 N1, N2   : Byte;

 Function ConstructByte( X, Y : Integer ) : Byte;
 Const
   Bits : Array[ 0 .. 7 ] Of Byte = ( 128, 64, 32, 16, 8, 4, 2, 1 );
 Var P     : Word;
     CByte : Byte;
     Bit   : Byte;
     YY    : Integer;
 Begin
   CByte := 0;
   For Bit := 0 To 7 Do
     Begin
       YY := Y + Bit;
       P := GetPixel( X, YY );
       If ( YY <= Y2 ) AND ( P <> Bk1 ) AND ( P <> Bk2 )
         Then Inc( CByte, Bits[ Bit ] );
     End;
   ConstructByte := CByte;
 End;

 Procedure DoLine;
 Var
   XPixel : Integer;
   PrintByte : Byte;
 Begin
   If Mode = 1
     Then Write( Lst, #27'L' )
     Else Write( Lst, #27'*', Chr( Mode ) );
   Write( Lst, Chr( N1 ), Chr( N2 ) );
   For XPixel := X1 To X2 Do
     Begin
       PrintByte := ConstructByte( XPixel, ScanLine );
       If( Inverse ) Then PrintByte := NOT PrintByte;
       Write( Lst,  Chr( PrintByte ) );
     End;
   Write( Lst, #10 );
 End;

Label Quit;

Begin
 Mode := Mode MOD 7;
 If Mode In [ 0, 5 ]
   Then Mode := 4;
 Write( Lst, #27'3'#24 );
 N1 := Lo( Succ( X2 - X1 ) );
 N2 := Hi( Succ( X2 - X1 ) );
 ScanLine := Y1;
 While ScanLine < Y2 Do
   Begin
     If KeyPressed AND ( ReadKey = #27 )
       Then Goto Quit;
     DoLine;
     Inc( ScanLine, 8 );
   End;
 Quit:
 Write( Lst, #27#2 );
End;

Begin
 { Инициализация графики }
 { Построение изображения }
 CopyToPrn(0, 0, GetMaxX, GetMaxY, Black, Black, False, 1);
 { Закрываем графику }
End.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.