Продолжаю начатую серию заметок о построении графиков в C++ Builder. В этой серии уже имеются такие записи:
- Построение косинусов (cos);
- Построение синусов (sin);
- Построение тангенсов (tg);
- Построение котангенсов (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
получился вот такой график.
hi??
Спасибо! Давно искал помощь в интернете, ваша статья помогла!
построила график с помощью Chart, а по одной оси значения ставят не по возрастанию, а наоборот, как это изменить?
Снять галочку Inverted на вкладке Axis. Если все равное не получится – пишите в комментах к статье о чарте. Вот тут, вдруг кому-то еще понадобиться.
Как хорошо написано, кратенько, без занудства. Прям хочется читать…
Но я не просто так, у меня вопрос)).
Можно ли как-нибудь сделать возможность выбора переменной, для которой будет создаваться массив значений (для функции нескольких переменных)?
Что-то вроде:
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.
Конечно же да.
Тот код, который привели вы, будет работать (если ; в конце y = a * ctg(x) + k поставить =)
Но я бы пользовала else (если есть риск того, что b будет равно c).
Ну и {} обязательно
т.е.
Спасибо, кстати, за похвалу 😉
Я немного неправильно написал код. Я имел ввиду можно ли так сделать для одного и того же “куска” кода.
Но такой номер, естественно, не проходит.
У меня есть большущий расчет и в конце нужны графики зависимости результата от разных переменных. Можно, конечно, сразу посчитать массивы от всех переменных, но это будет долго (от одной только переменной считается 2-3 сек.) и может быть не нужно одновременно. Уф.
В приведенном вами коде ничего не поняла %|
Вам нужно циклически менять х или а? Или и то, и другое, но в разных ситуациях?
Конечно, так, как вы привели работать не будет.
ЗЫ: Считать, конечно же, нужно только то, что интересно глядеть конечному пользователю…
И х и а, но по желанию пользователя. Например, он в RadioGroup’е выбирает “х”, нажимает кнопку “Построить” и строится график y = f(х), а выбирает “а” – строится y = f(а).
Не могу сделать этот выбор. Много чего перепробовал уже(.
Можно, конечно, как в первом случае – скопировать сам расчет под каждый счетчик (с современными мегагерцами гигабайтами это не проблема), но хочется как-то пофункциональнее ;).
Я не очень понимаю в чем именно сложность. Введите переменную, к примеру, ах и копируйте в нее значения а или х, в зависимости от того, что там выбрал пользователь. После стройте график у = f(ax) и все дела… ммм?
Теперь уже я не понимаю).
Если взять нашу любимую функцию y = a * ctg(x) + k,
то график от а будет прямой линией, а от х – соответствующей кривой. Это же разные переменные. Как их можно объединить в одну?
Или я туплю?
В приведенном вами примере можно и не объединять )))
Если пользователь выбрал график от х, то а = 1, если наоборот, то х = 45 градусам.
Просто сделать заюзать if {} else {} при определении значений переменных, а непосредственно расчет сделать общим для всех вариантов.
Сделал! Таанцуююю! Спасибо за помощь!!
Код, если интересно:
Это в самом начале после includ’ов. Ну а дальше “на кнопке” уже просто:
Ещё раз спасибо!
Потерялись строки:
Поздравляю )))
и мне помогите пожалуйста
решить и мою задачу
Вы б задачу сразу написали… а то как-то непонятно с чем помочь.