графика на C
#include <graphics.h>
#include <conio.h>
#include <process.h>
#include <math.h>
#include <alloc.h>
/*
n - kol-vo to4ek
x - mass X
y - mass Y
txt - imya funkcii
*/
int q=0, d=0;
void gr(int n, double *x, double *y, char *txt)
{
char t[20];
struct text_info ti;
int *xx,*yy, i, mX, mY, ax, ay;
double minx=x[0], miny=y[0], maxx=x[0], maxy=y[0];
double kx=0,ky=0, ratioX, ratioY;
int gdriver = DETECT, gmode, errorcode;
gettextinfo(&ti);
window(1,1,80,25);
/* Ishem min i max x i y*/
for (i=1; i<n; i++)
{
if (x<minx)
minx=x;
else
if (x>maxx)
maxx=x;
if (y<miny)
miny=y;
else
if (y>maxy)
maxy=y;
}
gmode=EGAHI;
initgraph(&gdriver, &gmode, "c:\\tc\\bgi");
errorcode = graphresult();
if (errorcode != grOk)
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
exit(1);
}
mX=getmaxx();
mY=getmaxy();
/* Ispol`zuem esli hotim setku
ot nilya, ina4e - kx=minx; ky=miny; */
if (minx<0)
kx=0;
if (miny<0)
ky=0;
/* Koefficient perescheta koordinat */
ratioX=(mX*pow(2.,q))/(maxx-kx);
ratioY=(mY*pow(2.,q))/(maxy-ky);
ax=(int)floor((-kx)*ratioX);
ay=mY-(int)floor((-ky)*ratioY);
/* Osi */
setcolor(YELLOW);
line(0,ay,mX,ay);
line(ax,0,ax,mY);
/* Rass4ityvaem ekrannye
koordinaty */
xx=(int*)malloc(n*sizeof(int));
yy=(int*)malloc(n*sizeof(int));
xx[0]=(int)floor((x[0]-kx)*ratioX);
yy[0]=mY-(int)floor((y[0]-ky)*ratioY);
putpixel(xx[0],yy[0],0);
moveto(xx[0],yy[0]);
setcolor(10);
/* Risuem graphic */
for (i=1; i<n; i++)
{
xx=(int)floor((x-kx)*ratioX);
yy=mY-(int)((y-ky)*ratioY);
lineto(xx,yy);
}
setcolor(YELLOW);
outtextxy(ax+1,0,txt);
/* Vyvodim podpisi */
sprintf(t,"%6.2f",maxy);
outtextxy(ax+1,15,t);
sprintf(t,"X %6.2f",maxx);
outtextxy(mX-70,ay-10,t);
sprintf(t,"%6.2f",minx);
outtextxy(0,ay-10,t);
getch();
/* Posmotreli graphic, zakryvaem
graphi4eskyi videorezhim */
closegraph();
/* Vosstanavlivaem attribut
i osvobozhdaem pamyat` */
window(ti.winleft,ti.wintop,ti.winright,ti.winbottom);
textattr(ti.attribute);
free(xx);
free(yy);
}
int main()
{
double x[100], y[100];
int i;
for (i=0; i<100; i++)
{
x = i;
y = i*i;
}
gr(100, x, y, "y=x^2");
return 0;
}
но преподаватель попросил модифицировать немного её:
1) Добавить возможность масштабирования по нажатию клавиш "+" и "-" и перемещения по оси х по нажатию клавиш "стрелка влево" и "стрелка вправо"
2) Сделать с вышеперечисленными добавлениями график для ф-ций y=x^3-10-a*(x-2)^(1/2) (при а=1.8) и y=(e^x)*cosx
столкнулся со следующими проблемами: код клавиш "+" и "-" - чила основного кода, а стрелок - дополнительного (при нажатие "+", "-" - увеличиваем q на 1 и пересчитываем RatioX, при нажатие стрелок - перемещаем график на d)
также нужно сделать массив float а не double чисел. Кто знает - помогите пожалуйста))
но проблема с стрелками остается
но преподаватель попросил модифицировать немного её:
1) Добавить возможность масштабирования по нажатию клавиш "+" и "-" и перемещения по оси х по нажатию клавиш "стрелка влево" и "стрелка вправо"
2) Сделать с вышеперечисленными добавлениями график для ф-ций y=x^3-10-a*(x-2)^(1/2) (при а=1.8) и y=(e^x)*cosx
столкнулся со следующими проблемами: код клавиш "+" и "-" - чила основного кода, а стрелок - дополнительного (при нажатие "+", "-" - увеличиваем q на 1 и пересчитываем RatioX, при нажатие стрелок - перемещаем график на d)
Если почитать описание getch, например здесь:
http://www.codenet.ru/progr/cpp/spr/175.php
то вроде должно быть понятно как сделать... Если getch при первом вызове возвращает не 0 - то значит нажата клавиша с основным кодом, который надо использовать для определения клавиши. Если 0 - то значит клавиша с расширенным кодом, и тогда надо считать с помощью getch() значение второй раз. Если как вы говорите, '+' и '-' - клавиши основного кода, а стрелки - дополнительного (я честно говоря уже не помню, а проверять лень), то примерно так:
c = getch();
if(c == /*код клавиши +*/)
{
// действия при нажатии +
}
else if(c == /*код клавиши -*/)
{
// действия при нажатии -
}
else if(c == 0 /*или !c*/) // клавиша расширенного кода
{
c = getch(); // считываем второй раз
if(c == /*код стрелки влево*/)
{
// действия при нажатии стрелки влево
}
else if(c == /*код стрелки вправо*/)
{
// действия при нажатии стрелки вправо
}
else // нажата другая клавиша
{
// ...
}
}
else // нажата другая клавиша
{
// ...
}
но проблема с стрелками остается
Не понял - в чем проблема сделать вместо массива double массив float? Просто заменить массивы double на float - не подойдет что ли?
"+" - 43
"-" - 45
"стрелка влево" - 0 75
"стрелка вправо" - 0 77
При рисовании графика, у вас есть некоторая точка экрана, которая соответствует центральной точке (0,0) системы координат, и при прорисовке графика, координаты очередной точки графика на экране вычисляются относительно этой центральной точки. Вот эту точку, по идее, и надо двигать (менять ее координаты), когда требуется сдвигать оси на экране.
Я так понимаю, координатами (на экране) этой центральной точки у вас являются kx и ky:
double kx=0,ky=0, ratioX, ratioY;
// ...
/* Ispol`zuem esli hotim setku
ot nilya, ina4e - kx=minx; ky=miny; */
if (minx<0)
kx=0;
if (miny<0)
ky=0;
/* Koefficient perescheta koordinat */
ratioX=(mX*pow(2.,q))/(maxx-kx);
ratioY=(mY*pow(2.,q))/(maxy-ky);
ax=(int)floor((-kx)*ratioX);
ay=mY-(int)floor((-ky)*ratioY);
// ...
xx[0]=(int)floor((x[0]-kx)*ratioX);
yy[0]=mY-(int)floor((y[0]-ky)*ratioY);
// ...
/* Risuem graphic */
for (i=1; i<n; i++)
{
xx=(int)floor((x-kx)*ratioX);
yy=mY-(int)((y-ky)*ratioY);
lineto(xx,yy);
}
// ...
Правда, сейчас у вас реализовано, что эти переменные всегда имеют значение 0.
Update. Хотя если быть точным, то kx и ky - это не координаты на экране центральной точки (0,0), а некоторые числовые значения, которые в вашем коде эти координаты представляют (может и несколько коряво выражаюсь, но как сказать точнее - затрудняюсь; впрочем, думаю суть понятна).
Вот теперь подумайте сами, как менять значения этих переменных, чтобы двигать оси графика.
"+" - 43
"-" - 45
"стрелка влево" - 0 75
"стрелка вправо" - 0 77
Ну вот берете коды этих клавиш, и подставляете в тот код который я вам дал:
c = getch();
if(c == 43 /*код клавиши +*/)
{
// действия при нажатии +
}
else // и так далее
И вам остается теперь реализовать действия, которые надлежит выполнять при нажатии той или иной клавиши.