Функции изменения параметров рисования
setcolor(char Color) Установить цвет рисования
setbkcolor(char Color) Установить цвет фона
Внимание! эта команда меняет все цвета экрана
setfillstyle(<Шаблон>,cahr Color) Установить цвет и стиль закраски фигур
setlinestyle(<Шаблон>,int Bit,char h) Установить стиль и толщину линий.
Шаблоны линий Шаблоны закраски
Шаблон | Ном | Изображение | Шаблон | Ном. | Изображение | |
SOLID_LINE | Сплошная линия | EMPTY_FILL | Цветом фона | |||
DOTTED_LINE | Линия из точек | SOLID_FILL | Выбранным цветом | |||
CENTER_LINE | Centered line | |LINE_FILL | --- | |||
DASHED_LINE | Dashed line | LTSLASH_FILL | /// | |||
SLASH_FILL | /// | |||||
BKSLASH_FILL | \\\ | |||||
LTBKSLASH_FILL | \\\ | |||||
HATCH_FILL | Light hatch | |||||
XHATCH_FILL | Heavy crosshatch | |||||
INTERLEAVE_FILL | Interleaving line | |||||
WIDE_DOT_FILL | Точками | |||||
CLOSE_DOT_FILL | Частыми точками |
Функции получения информации
MaxX=getmaxx() Получить макс. значение по оси Х
MaxY=getmaxy() Получить макс. значение по оси Y
DX=textwitdh("C") Получить размер символа (строки) по оси X
DY=textheight("T") Получить размер символа (строки) по оси Y
|
Рисование графиков
Постановка задачи
Заданна функция float F(float x), необходимо на выбранном пользователем интервале построить ее график. Программа должна автоматически определять масштаб, содержать разметку, линейку для сканирования точек графика. Значения сканируемых точек должны писаться под графиком.
Этапы реализации
Программа реализуется в 4 этапа: Рисование разметки; Нахождение минимума и максимума функции; Оцифровка; Вывод графика; и Сканирование значений точек.
Рисование разметки
Для рисования разметки рекомендуется воспользоваться стилем линий DOTTED_LINE. После завершения рисования, не забудьте вернуться к стилю SOLID_LINE. Рисовать удобнее функцией line(...) выводимой в цикле.
|
Нахождение минимума и максимума функции
|
t0..tmax. Кол-во точек N. Шаг между точками
dt=(tmax-t0)/N. float t0,tmax,dt; int N;
В начале считаем что макс.=мин.= значение в
первой точке.
Просматриваем все остальные точки графика.
Каждая точка сравнивается
с макс. значение, если
больше то макс. берется
эта точка.
t0+i*dt - значение по
горизонтали i точки.
F(t0+i*dt) - значение
функции в i точки.
Оцифровка
Для вывода цифр около линий разметки необходимо использовать функцию outtextxy(...), но предварительно число необходимо записать в строку, т.к. outtextxy(...) работает только со строками. Для этого удобнее всего пользоваться функцией sprintf(<Строка>,<"Текст, метки форматов",[<Переменные>]>). Эта функция аналогична printf(...), но вывод происходит не на экран, а в строку.
Пример:
char st[80] ;
. . . . .
sprintf(st,"x=%f , F(x)=%f",x,F(x)) ;
outtextxy(100,100,st) ;
При выводе на экран, необходимо помнить что координаты переданные в функцию outtextxy(...), относятся к левому верхнему углу строки. Чтобы строка была напротив (под) линей разметки, ее необходимо сдвинуть. Полезно учесть размер символа (функции textwidth(...) и textheight(..).
Вывод графика
Для вывода графика рекомендуется ввести целые переменные: x1,y1,x2,y2 - координаты точек, WX1,WY1,WX2,WY2 - координаты окна вывода. Алгоритм рисования графика следующий.
|
Сложность заключается только в пересчете вертикальных координат. Обычно они направленны снизу вверх, а у машины наоборот.
Сканирование значений точек
Под сканированием точек в задании понимается вертикальная линия перемещающаяся по графику, и выводимые под графиком значения аргумента и функции. Как организовать движение по клавишам и вывод числовых значений в графики уже рассматривалось выше.
Новое: Изображение линии, с последующим восстановлением изображеного под ней. Это рекомендуется реализовать используя режим инверсии экрана. В Си существует несколько способов рисования линий и прямоугольников. Первый режим COPY_PUT, указанные объекты рисуются цветом установленным в setcolor(...). Другие режимы позволяют рисовать комбинацией текущего цвета и цвета точек находящихся под рисунком. Удобнее всего использовать режим XOR_PUT. Повторно проведя линию того же цвета, возвращаемся к исходным цветам XOR(XOR(X))==X.
Установку режима осуществляет функция setwritemode(<Режим>). Установленный режим действует до установки нового. По умолчанию используется режим COPY_PUT.
Для того чтобы не забыть отключить режим инверсии, удобнее вынести все это в отдельную функцию, которая будет и стирать, и рисовать линю курсора.
void PutLine(int x,int y1,int y2)
{
setwritemode(XOR_PUT) ;
setcolor(RED) ; /* Инверсия др. цветом даст др. резулт. */
/* Линия будет рисоваться не цветом RED */
line(x,y1,x,y2) ; /* Линия вертикальная x1=x2=x */
setwritemode(COPY_PUT) ; /* Иначе и все остальное будет с инверсией цветов. */
} /* Кон. PutLine() */
Работа со спрайтами
Спрайт - фрагмент видео памяти (прямоугольное изображение). Библиотека Си содержит функции getimage(...) и putimage(...) позволяющие запоминать фрагменты экрана в памяти и выводить их в указанное место.
Функция getimage(int x1,int y1,int x2,int y2,void far *Buf)
x1,y1,x2,y2 - Размеры запоминаемой области,
Buf - Адрес выделенного буфера для запоминания изображения.
Функция putimage(int x,int y,void far *Buf,<Режим>)
x,y - Куда выводить изображение, левый верхний угол.
Buf - Адрес буфера где хранится изображение.
<Режим> - Режим вывода. COPY_PUT
В месте с этими функциями используются функции работы с памятью: выделения malloc(), farmalloc() (calloc(),farcalloc()), освобождения free(),farfree()
Обычно удобнее использовать память за пределами рабочего сегмента данных, по этому чаще используются farmalloc() и farfree(). Выделенную в программе память обязательно надо освобождать в конце работы программы. Иначе с каждым запуском программы у компьютера будет оставаться все меньше ресурсов, и в конце концов их не хватит для нормальной работы. Если попытка выделения памяти закончилась неудачно, то функции возвращают значение NULL. Если Вы хотите чтобы Ваша программа работала без сбоев, обязательно проверяйте успешность операции выделения памяти. За один вызов невозможно выделить более 64 кило байт.
Функции работы с памятью описаны в модуле alloc.h
Функция farmalloc(<Размер>)
Функция farfree(<Адрес буфера>)
Для правильного выделения памяти необходимо знать сколько ее нужно для выбранного фрагмента экрана. Это делает функция imagesize(...).
Функция imagesize(int x1,int y1,int x2,int y2) x1,y1,x2,y2 - Координаты выбранной области. Функция возвращает размер в байтах.
Внимание!!! Размеры запоминаемой картинки должны совпадать с размером выделенного буфера!
Пример вывода картинки
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <alloc.h>
int main(void)
{
int GrDr, GrMod, Rez;
long size ; /* Переменная для хранения размера запоминаемой картинки */
void far *Buf; /* Указатель на начало буфера изображения */
GrDr=DETECT ;
initgraph(&GrDr, &GrMod, " ");
Rez = graphresult();
if(Rez != grOk)
{
printf("\n Ошибка инициализации памяти"); return(0) ;
} /* Кон. if */
circle(20,20,5) ; /* Рисование объекта который будет запомнен */
size=imagesize(10,10,30,30) ; /* Опред. требуемого объема памяти */
Buf=farmalloc(size) ; /* Выделение требуемой памяти */
if(Buf==NULL)
{ /* Проверка, что выделение прошло успешно */
printf("\n Ошибка выделения памяти.") ;
getch() ;
closegraph() ;
return(0) ;
} /* Кон. if */
getimage(10,10,30,30,Buf) ; /* Запоминание фрагмента экрана */
getch() ;
putimage(100,100,Buf,COPY_PUT) ; /* Вывод в другое место */
getch() ;
farfree(Buf) ; /* Освобождение памяти */
closegraph();
return(1);
} /* Кон. main() */
Программа “летающая тарелка”
|
Компьютерная анимация
Для организации анимации используются несколько фаз движения объекта. Каждый рисунок целесообразно пометить в свою функцию, в качестве параметров в нее передается точка с которой надо рисовать и направление рисунка по оси Х. Все функции удобнее объединить в одну функцию рисования:
void Ris(int *faza,int x,int y,int napr)
{
switch (*faza)
{
case 1:Ris1(x,y,napr) ; break ;
case 2:Ris2(x,y,napr) ; break ;
. . .
} /* Кон. switch */
(*faza)++
if(*faza>MAX_FAZA) *faza=0 ;
} /* Кон. Ris() */
Каждая функция начинает с очистки места для рисунка. Все координаты в функциях рисования отсчитываются от точки x,y и умножаются на направление ; 1 (направо) и -1 (налево). Этим же параметром при необходимости можно менять и масштаб изображения.
При организации изображения движения старайтесь делать минимум команд рисования. Например, в часах необходимо перемещать только стрелки и маятник, у движущегося автомобиля проще крутить колеса и двигать телеграфные столбы в доль дороги, чем каждый раз перерисовывать кузов машины.