Версия для печати темы
Форум «Всё о Паскале» _ Задачи _ График функции
Автор: Кина 10.01.2005 19:12
Очень прошу помочь :o
Программа выводит сетку координат и метрическую сетку (разными цветами). Оси должны быть с графическими отметками и названиями. Рисует график y=x*x*x*Ln|x*x-4|. Если нажать мышкой на линию графика - отображаются координаты этой точки. Допускается использовать только вывод точки и получение координат. Возможность распечатки на матричном принтере.
Автор: Altair 10.01.2005 20:43
Вот http://forum.pascal.net.ru/forum/index.php?showtopic=2729&hl=Построение есть шаблон для построения графика.
Только вместо y:=abs(x/(x-2))-1; написать y:=x*x*x*ln(abs(x*x-4));
Далее - http://forum.pascal.net.ru/forum/index.php?showtopic=2383 есть вся информация о программировании мыши.
Автор: Кина 13.01.2005 14:48
Спасибо
Можно пару вопросов?
1. Я никак не могу понять как пересчитывать координаты из нормальных в графические (кстати, надо будет и обратно пересчитывать, координаты, полученные мышкой - хотя совершенно не представляю, как их передать в программу).
2. Функция getnum не компилируется, а остальные, связанные с мышью не работают Вообщем, я явно чего-то не понимаю...
Программа пока выглядит так:
Код
{$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 13.01.2005 15:34
Цитата
Функция 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 14.01.2005 13:04
или несовместим компилятор.
В ближайшее время материалы FAQ"a будут отредактированны, в целях повышения совместимости.
Цитата
Я никак не могу понять как пересчитывать координаты из нормальных в графические
Что значит из нормлаьных в графичесике?
INT33h возвращает всегда координаты по пикселам. Это в текстовом режиме 8 пикселей=1 виртуальный.
Автор: Кина 14.01.2005 17:53
2 volvo
Сэнкс
2 Oleg_Z
Пересчет координаты точки, например (2,4), в графические (где будет находится эта точка на экране?), например (468, 234)
Код
putpixel(zcrtx+trunc(x*mtrX),zcrty-trunc(y*mtrY),colorg) end;
Как составить такую (и обратную) формулу?
Автор: FreeMan 14.01.2005 20:37
Цитата
Возможный способ решения проблемы:
читать координаты и самотужки там рисовать подобие курсора, потом вытирать, снова читать...
Автор: Altair 14.01.2005 22:36
Кина, для перевода из координат точки на экране в координаты относительно графика делаем так:
- из координат на экране получаем координаты на экарне, но относительно начала координат.
- вычисляем координаты зная масштаб графика.
Например, то что вы дали.
сначала что я понял.
zcrtx - абсцисса начала координат.
zcrty - ордината начала координат.
mtrX - масштабный коээфициент по X...
ну и по Y соотв.
Тогда "нормальные" получаем из графических (на экране, где мышка кликнула) так:
x=(MouseX-zcrtx) div mtrX;
y=(MouseY-zcrty) div mtrY;
Цитата
(и обратную)
формулу так: (то есть зная нормальные координаты, получаем координаты на экране).
Здесь используем нашу формулу.
Да, еще - когда мышка кликает по графику, следует удостовериться что она кликнула именно по графику, а не на 1 пиксел например, правее.
Это можно реализовать, считав например цвет пиксела по которому кликнула мышка. GetPixel(x,y) вернет значение пиксела...
и сравнив его с цветом графика, узнаем кликнула ли мышка по графику.
Другой способ - сначала преобразовать в нормальные координаты, и подставив в формулу, проверитиь получим ли в экранных координатах точку..
Автор: Кина 19.01.2005 19:14
Oleg_Z Спасибо
Еще мне бы совсем не помешала консультация по печати - никогда не пробовала печатать из графического режима - вообще как задавать параметры печати? (если это имеет значение - принтер Epson LX1050+)
Автор: volvo 19.01.2005 19:38
Кина
Вот процедура... Она будет работать для всех граф. режимов на всех принтерах, воспринимающих систему команд 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.