float func1(float x,float a,float b)
{
if (x<=a) return 0;
if ((a<=x)&&(x<=(a+b)/2)) return 2*(x-a)*(x-a)/((b-a)*(b-a));
if ((x>=((a+b)/2))&&(x<=b)) return 1-2*(x-b)*(x-b)/((b-a)*(b-a));
if (x>=b) return 1;
}
/...
Form1->Canvas->MoveTo(a,-func1(a,a,b));
for( float x = a; x <= b; x += 1e-3 )
{
y=func1(x,a,b,c,d);
Form1->Canvas->LineTo(x,-y);
}
График в квадрате
Подскажите как нарисовать график функции func1 в квадрате x:a..b,y:0..1
ну.... квадрат [a;b]x[0;1] это вообще круто.... но чёт нифига не понял -- что надо и что не получается
график толком увидеть.Вот файл:http://slil.ru/24056584
Код:
xs=(x-a)*(xend-xstart)*(b-a)+xstart;
ys=ystart-y*(yend-ystart);
ys=ystart-y*(yend-ystart);
xstart,ystart - координаты левого верхнего угла прямоугольника, где будешь рисовать.
xend,yend - координаты правого нижнего угла прямоугольника, где будешь рисовать.
x,y - значения аргумента и функции
xs,ys - координаты соотв. точки на экране.
Немного исправил,но все равно рисует плохо:
Код:
float a = 0, b = 2;
int x_start = 50, y_start = 50;
int height = 200;
int width = (b-a)*height;
Form1->Canvas->Rectangle(x_start, y_start, x_start + width, y_start + height);
Form1->Canvas->MoveTo(x_start, y_start + height);
for(int i = 0; i <= width; i++)
{
float x = b + (a-b)*(width - i)/width;
float y = func1(x,a,b);
int j = height*y;
Form1->Canvas->LineTo(x_start + i, y_start + height - j);
}
int x_start = 50, y_start = 50;
int height = 200;
int width = (b-a)*height;
Form1->Canvas->Rectangle(x_start, y_start, x_start + width, y_start + height);
Form1->Canvas->MoveTo(x_start, y_start + height);
for(int i = 0; i <= width; i++)
{
float x = b + (a-b)*(width - i)/width;
float y = func1(x,a,b);
int j = height*y;
Form1->Canvas->LineTo(x_start + i, y_start + height - j);
}
Вроде нормально рисует :)
Код:
float func2(float x,float a,float b,float c,float d=0)
{
if ((a<x)&&(x<b)) return func1(x,a,b,0,0);
if ((x>=b)&&(x<=b*c)) return 1;
if ((x>c)&&(x<(c+a))) return 1-func1(x,c,c+b-a,0,0);else return 0;
}
{
if ((a<x)&&(x<b)) return func1(x,a,b,0,0);
if ((x>=b)&&(x<=b*c)) return 1;
if ((x>c)&&(x<(c+a))) return 1-func1(x,c,c+b-a,0,0);else return 0;
}
график опять же неправильно рисуется! :(
Вот изображение: http://slil.ru/24057558
Я думаю, если ты разберешь предыдущий пример, то научишься рисовать графики любых функций :)
Код:
float bb=c+a;
int x_start = 50, y_start = 50;
int height = 100;
int width = (bb-a)*height;
Form1->Canvas->Rectangle(x_start, y_start, x_start + width, y_start + height);
Form1->Canvas->MoveTo(x_start, y_start + height);
for(int i = 0; i <= width; i++)
{
float x = bb + (a-bb)*(width - i)/width;
float y = func2(x,a,b,c,d);
int j = height*y;
Form1->Canvas->LineTo(x_start + i, y_start + height - j);
}
int x_start = 50, y_start = 50;
int height = 100;
int width = (bb-a)*height;
Form1->Canvas->Rectangle(x_start, y_start, x_start + width, y_start + height);
Form1->Canvas->MoveTo(x_start, y_start + height);
for(int i = 0; i <= width; i++)
{
float x = bb + (a-bb)*(width - i)/width;
float y = func2(x,a,b,c,d);
int j = height*y;
Form1->Canvas->LineTo(x_start + i, y_start + height - j);
}
http://slil.ru/24057558, то правая граница там не a+c, а c+(b-a).
Да и код функции func2 у тебя неправильно написан. По-моему, он должен быть вот таким:
Ну, если посмотреть на график
Да и код функции func2 у тебя неправильно написан. По-моему, он должен быть вот таким:
Код:
float func2(float x,float a,float b,float c,float d=0)
{
if ((a<=x)&&(x<=b)) return func1(x,a,b,0,0);
if ((b<=x)&&(x<=c)) return 1;
if ((c<=x)&&(x<=c+b-a)) return 1-func1(x,с,с+b-a,0,0); else return 0;
}
{
if ((a<=x)&&(x<=b)) return func1(x,a,b,0,0);
if ((b<=x)&&(x<=c)) return 1;
if ((c<=x)&&(x<=c+b-a)) return 1-func1(x,с,с+b-a,0,0); else return 0;
}
http://slil.ru/24058912
Вроде ничего особенного (просто вставил ваш код:границы же там тоже a,b).Но рисует одну сплошную линию :(
Черт.Описался.См.рисую график функции:
Код:
float func5(float x,float a,float b,float c,float d)
{
if (a<=x) return 0;
if ((x>=a)&&(x<=c)) return (x-a)/(c-a);
if ((x>=c)&&(x<=d)) return 1;
if ((x>=d)&&(x<=b)) return (b-x)/(b-d);
if (x>=b) return 0;
}
{
if (a<=x) return 0;
if ((x>=a)&&(x<=c)) return (x-a)/(c-a);
if ((x>=c)&&(x<=d)) return 1;
if ((x>=d)&&(x<=b)) return (b-x)/(b-d);
if (x>=b) return 0;
}
Вроде ничего особенного (просто вставил ваш код:границы же там тоже a,b).Но рисует одну сплошную линию :(
Код:
float func5(float x,float a,float b,float c,float d)
{
if (a>=x) return 0;
if ((x>=a)&&(x<=c)) return (x-a)/(c-a);
if ((x>=c)&&(x<=d)) return 1;
if ((x>=d)&&(x<=b)) return (b-x)/(b-d);
if (x>=b) return 0;
}
{
if (a>=x) return 0;
if ((x>=a)&&(x<=c)) return (x-a)/(c-a);
if ((x>=c)&&(x<=d)) return 1;
if ((x>=d)&&(x<=b)) return (b-x)/(b-d);
if (x>=b) return 0;
}
А можно оптимизировать код.Т.е. создать отдельную функцию для рисования Draw,туда передавать параметры a,b,c,d и функцию,
которую надо нарисовать?
Вот так прокатит?
Код:
class Tclass
{
float func1(float x,float a,float b,float c,float d)
{
if (x<=a) return 0;
if ((a<=x)&&(x<=(a+b)/2)) return 2*(x-a)*(x-a)/((b-a)*(b-a));
if ((x>=((a+b)/2))&&(x<=b)) return 1-2*(x-b)*(x-b)/((b-a)*(b-a));
if (x>=b) return 1;
}
float func2(float x,float a,float b,float c,float d=0)
{
if ((a<=x)&&(x<=b)) return func1(x,a,b,0,0);
if ((x>=b)&&(x<=c)) return 1;
if ((x>=c)&&(x<=c+b-a)) return 1-func1(x,c,c+b-a,0,0);else return 0;
}
void Draw(float *func,float a,float b,float c=0,float d=0)
{
int x_start = 50, y_start = 50;
int height = -100+Form1->Height;
// int width = (b-a)*height;
int width=-100+Form1->Width;
Form1->Canvas->Rectangle(x_start, y_start, x_start + width, y_start + height);
Form1->Canvas->MoveTo(x_start, y_start + height);
for(int i = 0; i <= width; i++)
{
float x = b + (a-b)*(width - i)/width;
float y = func(x,a,b,c,d);
int j = height*y;
Form1->Canvas->LineTo(x_start + i, y_start + height - j);
}
}
float (Tclass::*func[2])(float ,float ,float ,float ,float );
public:
Tclass(int flag, float a,float b,float c=0,float d=0)
{
func[0]=func1;
func[1]=func2;
switch(flag)
{
case 1:Draw(func[0],a,b,c,d);
case 2:Draw(func[1],a,b,c,d);
}
}
}
{
float func1(float x,float a,float b,float c,float d)
{
if (x<=a) return 0;
if ((a<=x)&&(x<=(a+b)/2)) return 2*(x-a)*(x-a)/((b-a)*(b-a));
if ((x>=((a+b)/2))&&(x<=b)) return 1-2*(x-b)*(x-b)/((b-a)*(b-a));
if (x>=b) return 1;
}
float func2(float x,float a,float b,float c,float d=0)
{
if ((a<=x)&&(x<=b)) return func1(x,a,b,0,0);
if ((x>=b)&&(x<=c)) return 1;
if ((x>=c)&&(x<=c+b-a)) return 1-func1(x,c,c+b-a,0,0);else return 0;
}
void Draw(float *func,float a,float b,float c=0,float d=0)
{
int x_start = 50, y_start = 50;
int height = -100+Form1->Height;
// int width = (b-a)*height;
int width=-100+Form1->Width;
Form1->Canvas->Rectangle(x_start, y_start, x_start + width, y_start + height);
Form1->Canvas->MoveTo(x_start, y_start + height);
for(int i = 0; i <= width; i++)
{
float x = b + (a-b)*(width - i)/width;
float y = func(x,a,b,c,d);
int j = height*y;
Form1->Canvas->LineTo(x_start + i, y_start + height - j);
}
}
float (Tclass::*func[2])(float ,float ,float ,float ,float );
public:
Tclass(int flag, float a,float b,float c=0,float d=0)
{
func[0]=func1;
func[1]=func2;
switch(flag)
{
case 1:Draw(func[0],a,b,c,d);
case 2:Draw(func[1],a,b,c,d);
}
}
}
Можете подсказать:как сделать,чтобы компилировалось нормально?
Но в твоем случае оптимизировать можно и без классов. Имхо, вполне приличный код получился:
Код:
#define Draw( a, b, expr, x_start, y_start )\
{\
int height = 100;\
int width = (b-a)*height;\
Form1->Canvas->Rectangle(x_start, y_start, x_start + width, y_start + height);\
TColor color1 = Form1->Canvas->Pen->Color;\
Form1->Canvas->Pen->Color = clRed;\
Form1->Canvas->MoveTo(x_start, y_start + height);\
for(int i = 0; i <= width; i++)\
{\
float x = b + (a-b)*(width - i)/width;\
float y = expr;\
int j = height*y;\
Canvas->LineTo(x_start + i, y_start + height - j);\
}\
Form1->Canvas->Pen->Color = color1;\
}
float func1(float x, float a, float b)
{
if (x<=a) return 0;
if ((a<=x)&&(x<=(a+b)/2)) return 2*(x-a)*(x-a)/((b-a)*(b-a));
if ((x>=((a+b)/2))&&(x<=b)) return 1-2*(x-b)*(x-b)/((b-a)*(b-a));
else return 1;
}
float func2(float x, float a, float b, float c, float d)
{
if ((a<=x)&&(x<=c)) return func1(x,a,c);
if ((c<=x)&&(x<=d)) return 1;
if ((d<=x)&&(x<=b)) return 1-func1(x,d,b);
else return 0;
}
float func5(float x, float a, float b, float c, float d)
{
if ((x>=a)&&(x<=c)) return (x-a)/(c-a);
if ((x>=c)&&(x<=d)) return 1;
if ((x>=d)&&(x<=b)) return (b-x)/(b-d);
else return 0;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
float a = Edit1->Text.ToDouble();
float b = Edit2->Text.ToDouble();
float c = Edit3->Text.ToDouble();
float d = Edit4->Text.ToDouble();
Draw( a, b, func1(x,a,b), 50, 50 );
Draw( a, b, func2(x,a,b,c,d), 50, 200 );
Draw( a, b, func5(x,a,b,c,d), 50, 350 );
}
{\
int height = 100;\
int width = (b-a)*height;\
Form1->Canvas->Rectangle(x_start, y_start, x_start + width, y_start + height);\
TColor color1 = Form1->Canvas->Pen->Color;\
Form1->Canvas->Pen->Color = clRed;\
Form1->Canvas->MoveTo(x_start, y_start + height);\
for(int i = 0; i <= width; i++)\
{\
float x = b + (a-b)*(width - i)/width;\
float y = expr;\
int j = height*y;\
Canvas->LineTo(x_start + i, y_start + height - j);\
}\
Form1->Canvas->Pen->Color = color1;\
}
float func1(float x, float a, float b)
{
if (x<=a) return 0;
if ((a<=x)&&(x<=(a+b)/2)) return 2*(x-a)*(x-a)/((b-a)*(b-a));
if ((x>=((a+b)/2))&&(x<=b)) return 1-2*(x-b)*(x-b)/((b-a)*(b-a));
else return 1;
}
float func2(float x, float a, float b, float c, float d)
{
if ((a<=x)&&(x<=c)) return func1(x,a,c);
if ((c<=x)&&(x<=d)) return 1;
if ((d<=x)&&(x<=b)) return 1-func1(x,d,b);
else return 0;
}
float func5(float x, float a, float b, float c, float d)
{
if ((x>=a)&&(x<=c)) return (x-a)/(c-a);
if ((x>=c)&&(x<=d)) return 1;
if ((x>=d)&&(x<=b)) return (b-x)/(b-d);
else return 0;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
float a = Edit1->Text.ToDouble();
float b = Edit2->Text.ToDouble();
float c = Edit3->Text.ToDouble();
float d = Edit4->Text.ToDouble();
Draw( a, b, func1(x,a,b), 50, 50 );
Draw( a, b, func2(x,a,b,c,d), 50, 200 );
Draw( a, b, func5(x,a,b,c,d), 50, 350 );
}
Я добавила макрос Draw и изменила функцию func2, чтобы там границы были тоже a и b (просто для удобства).
И компилируется, и работает нормально. :)