Головна » C++ Builder: построение графиков. Часть 4. Котангенсы (ctg)

C++ Builder: построение графиков. Часть 4. Котангенсы (ctg)

Продолжаю начатую серию заметок о построении графиков в C++ Builder. В этой серии уже имеются такие записи:

  1. Построение косинусов (cos);
  2. Построение синусов (sin);
  3. Построение тангенсов (tg);
  4. Построение котангенсов (ctg).

На сей раз (если вы еще не догадались) речь пойдет о котангенсах (ctg). Строить будем график вида: y = a * ctg(x) + k.

Построение линий сетки я рассматривала в первом посте серии (в построении косинусов), там же поясняла большинство обозначений (если не разберетесь – всегда можно спросить в комментариях).

Отмечу, что константы a и k должны быть заданы. Также важным моментом является таковой: в C++ Builder отсутствует функция получения котангенса (ctg). Для этих целей можно воспользоваться тригонометрическим выражением ctg(x)= cos(x)/sin(x).

Кроме того, следует учитывать и тот факт, что в некоторых точках котангенса функции просто не существует (в точках, где sin(x) = 0).

В общем, перейдем непосредственно к построению графика.

// делаем объект Image1 видимым
  Image1->Visible=true;

// циклически определяем максимальное и 
// минимальное значения Y
 for (X=Xmin;X<=Xmax;X+=dX)
  {
     if (sin(X)==0) X+=dX;
  Y=a*cos(X)/sin(X)+k;
   if(YmaxY) Ymin=Y;
  }

// задаем масштаб по оси Y
  if((Ymax-Ymin)==0) MasY=LY-40;
  else MasY=(LY-40)/(Ymax-Ymin);

// циклически проставляем значения по шкале Y
 float B[11];
 for (i=0;i<=10;i++)
{
 B[i]=50+LY/11*i;
 AnsiString S = FloatToStrF(Ymax-((Ymax-Ymin)/10)*i,ffFixed,5,2);
 Image1->Canvas->TextOutA(20,B[i]-15,S);
}

// на 0 делить нельзя
if (sin(Xmin)==0) Image1->Canvas->MoveTo(50,LY-(Ymin*(-1)+a*sin(Xmin+dX)/cos(Xmin+dX))*MasY);
else Image1->Canvas->MoveTo(50,LY-(Ymin*(-1)+a*cos(Xmin)/sin(Xmin))*MasY);

// непосредственно построение графика функции
 for (X=Xmin;X<=Xmax;X+=dX)
  {
    if (sin(X)==0) X+=dX;
   Y=a*cos(X)/sin(X)+k;
   PY=LY-(Ymin*(-1)+Y)*MasY;
       PX=X*MasX+50;
   Image1->Canvas->LineTo(PX-Xmin*MasX,PY);
  }

При заданных значениях Xmin=0, Xmax=10, dX=0.02, a=1, k=0 получился вот такой график.

Построенный график функции a*ctg(X)+k

femil

20 коментарів до “C++ Builder: построение графиков. Часть 4. Котангенсы (ctg)

  1. построила график с помощью Chart, а по одной оси значения ставят не по возрастанию, а наоборот, как это изменить?

    1. Снять галочку Inverted на вкладке Axis. Если все равное не получится – пишите в комментах к статье о чарте. Вот тут, вдруг кому-то еще понадобиться.

  2. Как хорошо написано, кратенько, без занудства. Прям хочется читать…
    Но я не просто так, у меня вопрос)).
    Можно ли как-нибудь сделать возможность выбора переменной, для которой будет создаваться массив значений (для функции нескольких переменных)?
    Что-то вроде:
    if (v==b)
    for (x=Xmin; x<Xmax; x+=dX)
    y = a * ctg(x) + k.

    if (v==c)
    for (a=Amin; a<Amax; a+=dA)
    y = a * ctg(x) + k.

    1. Конечно же да.
      Тот код, который привели вы, будет работать (если ; в конце y = a * ctg(x) + k поставить =)
      Но я бы пользовала else (если есть риск того, что b будет равно c).
      Ну и {} обязательно
      т.е.

      if (v==b)
      {
      for (x=Xmin; x
      				
      1. Я немного неправильно написал код. Я имел ввиду можно ли так сделать для одного и того же “куска” кода.

        if (v==b)
        for (x=Xmin; x<Xmax; x+=dX)
        
        else 
        
        for (a=Amin; a<Amax; a+=dA)
        {
        y = a * ctg(x) + k;
        }

        Но такой номер, естественно, не проходит.
        У меня есть большущий расчет и в конце нужны графики зависимости результата от разных переменных. Можно, конечно, сразу посчитать массивы от всех переменных, но это будет долго (от одной только переменной считается 2-3 сек.) и может быть не нужно одновременно. Уф.

        1. В приведенном вами коде ничего не поняла %|
          Вам нужно циклически менять х или а? Или и то, и другое, но в разных ситуациях?
          Конечно, так, как вы привели работать не будет.
          ЗЫ: Считать, конечно же, нужно только то, что интересно глядеть конечному пользователю…

          1. И х и а, но по желанию пользователя. Например, он в RadioGroup’е выбирает “х”, нажимает кнопку “Построить” и строится график y = f(х), а выбирает “а” – строится y = f(а).
            Не могу сделать этот выбор. Много чего перепробовал уже(.
            Можно, конечно, как в первом случае – скопировать сам расчет под каждый счетчик (с современными мегагерцами гигабайтами это не проблема), но хочется как-то пофункциональнее ;).

          2. Я не очень понимаю в чем именно сложность. Введите переменную, к примеру, ах и копируйте в нее значения а или х, в зависимости от того, что там выбрал пользователь. После стройте график у = f(ax) и все дела… ммм?

          3. Теперь уже я не понимаю).
            Если взять нашу любимую функцию y = a * ctg(x) + k,
            то график от а будет прямой линией, а от х – соответствующей кривой. Это же разные переменные. Как их можно объединить в одну?
            Или я туплю?

          4. В приведенном вами примере можно и не объединять )))
            Если пользователь выбрал график от х, то а = 1, если наоборот, то х = 45 градусам.
            Просто сделать заюзать if {} else {} при определении значений переменных, а непосредственно расчет сделать общим для всех вариантов.

          5. Сделал! Таанцуююю! Спасибо за помощь!!
            Код, если интересно:

            float Fsum(float a, float x, float k)
            {
             return a * tan(x) + k;
            }

            Это в самом начале после includ’ов. Ну а дальше “на кнопке” уже просто:

            float d;
            if (RG->ItemIndex==0)
            {
             Series1->Clear();
             for (float x1=1;x1AddXY(x1,d);
             }
            }
            else
            {
             Series1->Clear();
             for (float x2=1; x2AddXY(x2,d);
             }
            }

            Ещё раз спасибо!

          6. Потерялись строки:

            if (RG->ItemIndex==0)
            {
            for (float x1=1; x2AddXY(x1,d);
              }
            }

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *

Повернутись до верху