Имя пользователя:
Пароль:
 

Показать сообщение отдельно

Аватара для Savant

Старожил


Сообщения: 300
Благодарности: 6

Профиль | Сайт | Отправить PM | Цитировать


Вложения
Тип файла: zip TEST.zip
(1017 байт, 54 просмотров)

Ruffo
Так как задана кокретная функция, то задача еще больше упрощается: не надо писать парсер для произвольной функции, которую пользователь вводит уже во время работы программы.

Рассмотрим шаг №2:
у меня он реализовался в таком виде
Код: Выделить весь код
#define MIN_COORD_X -8 // минимальный Х, для которого строится график
#define MAX_COORD_X 8 // максимальный
 
#define MIN_X -10 // минимальный Х, для которого строится координатная сетка
#define MAX_X 10 // ...(тут все по аналогии)...
#define MIN_Y -40 // .......
#define MAX_Y 15 // ........
 
#define STEP .01 // тот самый шаг (можно назвать и как приращение аргумента)
 
void main(void)
{
  // инициализация граф. режима
  ........
 
  // вычисление констант для преобразования относительных значений в абсолютные
  int rel_x =  getmaxx() / (MAX_X - MIN_X + 2);
  int add_x = (getmaxx() / (MAX_X - MIN_X)) * MAX_X;
  int rel_y = -getmaxy() / (MAX_Y - MIN_Y + 2);
  int add_y = (getmaxy() / (MAX_Y - MIN_Y)) * MAX_Y;
Формулы вопросов, надеюсь, не вызывают.
Таким образом вычисляется месторасположение точки (x;y) на экране - это будет пиксель с координатами (x*rel_x+add_x; y*rel_y+add_y). rel_x и rel_y задают масштаб преобразования из единиц в пиксели (вообще их надо было бы делать типа double, но обычно такой точности и не требуется).

Теперь переходим к шагу 3:
Код: Выделить весь код
  if (MAX_Y * MIN_Y < 0)
  {
	moveto(0, add_y);
	linerel(getmaxx(), 0);
  }
 
  if (MAX_X * MIN_X < 0)
  {
	moveto(add_x, 0);
	linerel(0, getmaxy());
  }
Строим координатные оси, проверяя по ходу, видны ли они на экране (в этом случае не строим). Как видно, все тоже просто: смещаемся в крайнюю точку оси и проводим прямую линию до противоположного края экрана.

Шаг 4: собственно постройка графика
Код: Выделить весь код
  double i = MIN_COORD_X;
  moveto(MIN_COORD_X * rel_x + add_x, f(i) * rel_y + add_y);
 
  for (i += STEP; i <= MAX_COORD_X; i += STEP)
  {
	lineto(i * rel_x + add_x, f(i) * rel_y + add_y);
  }
Здесь f() - функция, возвращающая значение заданной функции (тавтология млин ) при некотором аргументе. Я использовал такую :
Код: Выделить весь код
double f(double x)
{
  return (x*x-5.0*x*cos(x)-6.0);
}
Первым действием мы смещаемся (moveto()) на первую точку графика функции и далее в цикле просто проводим линию из старой точки в новую. При рассчетах используются вычисленные ранее константы rel_x, add_x и т.п.

Надеюсь, хоть что-то объяснил. Здесь представлен только скелет программы. Все необходимые навороты добавить труда не составит. Внизу он же прикреплен, только уже в более-менее рабочем состоянии (с наворотами) и без комментариев.

Единственное, чего тут потенциально не хватает - это обработчика исключительных ситуаций (при вычислении значения функции)...

Текст программы исправлен (14.07.2005)

Последний раз редактировалось Savant, 14-07-2005 в 08:58.


Отправлено: 14:06, 12-07-2005 | #4