Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

График в квадрате

7.3K
10 марта 2007 года
Mandel
21 / / 09.02.2005
Подскажите как нарисовать график функции func1 в квадрате x:a..b,y:0..1
Я написал вот так.но у меня не в этом квадрате рисует:
Код:
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);
        }
355
10 марта 2007 года
&lt;SCORP&gt;
786 / / 21.10.2006
ну.... квадрат [a;b]x[0;1] это вообще круто.... но чёт нифига не понял -- что надо и что не получается
7.3K
10 марта 2007 года
Mandel
21 / / 09.02.2005
Надо,чтобы график именно был нарисован при x:a..b:я рисую на форме,а у меня не масштабируется и не получается
график толком увидеть.Вот файл:http://slil.ru/24056584
247
10 марта 2007 года
wanja
1.2K / / 03.02.2003
 
Код:
xs=(x-a)*(xend-xstart)*(b-a)+xstart;
ys=ystart-y*(yend-ystart);

xstart,ystart - координаты левого верхнего угла прямоугольника, где будешь рисовать.
xend,yend - координаты правого нижнего угла прямоугольника, где будешь рисовать.
x,y - значения аргумента и функции
xs,ys - координаты соотв. точки на экране.
7.3K
10 марта 2007 года
Mandel
21 / / 09.02.2005
Немного исправил,но все равно рисует плохо:
http://slil.ru/24056846
15K
10 марта 2007 года
Sara
79 / / 04.01.2007
Код:
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);
}

Вроде нормально рисует :)
7.3K
10 марта 2007 года
Mandel
21 / / 09.02.2005
Да.Но,например,для функции (c лежит между a,b)
 
Код:
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;
        }

график опять же неправильно рисуется! :(
Вот изображение: http://slil.ru/24057558
15K
10 марта 2007 года
Sara
79 / / 04.01.2007
Я думаю, если ты разберешь предыдущий пример, то научишься рисовать графики любых функций :)
7.3K
10 марта 2007 года
Mandel
21 / / 09.02.2005
Сделал по аналогии (правая граница тепер:a+c).Но рисует закорючку вместо графика:
Код:
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);
            }
15K
10 марта 2007 года
Sara
79 / / 04.01.2007
Ну, если посмотреть на график http://slil.ru/24057558, то правая граница там не a+c, а c+(b-a).

Да и код функции 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;
}
7.3K
10 марта 2007 года
Mandel
21 / / 09.02.2005
Черт.Описался.См.рисую график функции: http://slil.ru/24058912
 
Код:
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;
        }

Вроде ничего особенного (просто вставил ваш код:границы же там тоже a,b).Но рисует одну сплошную линию :(
15K
11 марта 2007 года
Sara
79 / / 04.01.2007
Смени знак неравенства в первой строке и будет тебе счастье.
 
Код:
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;
}
7.3K
11 марта 2007 года
Mandel
21 / / 09.02.2005
Спасибо Sara
А можно оптимизировать код.Т.е. создать отдельную функцию для рисования 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);
          }
        }
}
7.3K
12 марта 2007 года
Mandel
21 / / 09.02.2005
Можете подсказать:как сделать,чтобы компилировалось нормально?
15K
13 марта 2007 года
Sara
79 / / 04.01.2007
Ну, в С++ я не шибко разбираюсь, поэтому с классами вряд ли смогу помочь :o
Но в твоем случае оптимизировать можно и без классов. Имхо, вполне приличный код получился:

Код:
#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 );
}


Я добавила макрос Draw и изменила функцию func2, чтобы там границы были тоже a и b (просто для удобства).

И компилируется, и работает нормально. :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог