Добавил:
СПбГУТ * ИКСС * Программная инженерия Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
АОПИ. Сортировка и интерполяция.pdf
Скачиваний:
19
Добавлен:
05.02.2022
Размер:
3.39 Mб
Скачать

ИСХОДНЫЕ ФАЙЛЫ DPIPE

draw.cpp

#include "draw_func.h"

#include <windows.h> #include <cstring>

/// Числовой тип

using NumericalType = long double;

int main () {

HANDLE hPipe; /// Дескриптор канала

int foreColor = WHITE, backColor = BLACK; /// Стандартные цвета char buffer[512]; /// Буфер

DWORD dwRead; /// Число действительно прочитанных байт

/// Создаем именованный канал (512 байт - размер сообщения) hPipe = CreateNamedPipe("\\\\.\\pipe\\GraphPipe", PIPE_ACCESS_DUPLEX,

PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 512, 512, NMPWAIT_USE_DEFAULT_WAIT, NULL);

while (hPipe != INVALID_HANDLE_VALUE) { /// Пока канал активен

if (ConnectNamedPipe(hPipe, NULL)) { /// Если клиент подключился

/// Принимаем сообщение

while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) !=

FALSE) {

buffer[dwRead] = '\0'; /// Ставим знак конца строки

/// Определяем команду клиента

///(сравнение со строками отсортировано по частоте использования) if (strncmp(buffer, "DrawPoint", 9) == 0) {

NumericalType x, y;

int

size = 3, color = foreColor;

sscanf(buffer + 10, "%Le %Le %d %d", &x, &y, &size, &color);

GraphLib::DrawPoint(x, y, size, color);

}

(strncmp(buffer, "DrawText", 8) == 0) {

else if

char

*p;

int

x, y, color = foreColor;

///

Перебираем пробелы

p =

strchr(buffer, ' ');

p =

strchr(p + 1, ' ');

p =

strchr(p + 1, ' ');

///

До четвертого: (там где начинается текст)

p =

strchr(p + 1, ' ');

sscanf(buffer + 9, "%d %d %d", &x, &y, &color);

GraphLib::DrawText(x, y, p + 1, color);

}

(strncmp(buffer, "DrawLinesAndValues", 18) == 0) {

else if

int

n = 6;

sscanf(buffer + 19, "%d", &n);

GraphLib::DrawLinesAndValues(n);

}

(strncmp(buffer, "DrawLine", 8) == 0) {

else if

int

x1, y1, x2, y2, color = foreColor;

sscanf(buffer + 9, "%d %d %d %d %d", &x1, &y1, &x2, &y2,

&color);

GraphLib::DrawLine(x1, y1, x2, y2, color);

}

else if (strncmp(buffer, "InitDrawPanel", 13) == 0) { sscanf(buffer + 14, "%d %d", &foreColor, &backColor);

GraphLib::InitDrawPanel(foreColor, backColor);

}

else if (strncmp(buffer, "ClearDevice", 11) == 0) {

40

GraphLib::ClearDevice();

}

else if (strncmp(buffer, "InitGraph", 9) == 0) { NumericalType MinXC, MaxXC, MinYC, MaxYC; NumericalType MaxXin, MaxYin, MarginLeft, MarginTop; MaxXin = 0.6L;

MaxYin = 0.6L; MarginLeft = 0.25L;

MarginTop = 0.2L;

sscanf(buffer + 10, "%Le %Le %Le %Le %Le %Le %Le %Le", &MinXC, &MaxXC, &MinYC, &MaxYC, &MaxXin, &MaxYin,

&MarginLeft, &MarginTop);

GraphLib::InitGraph(MinXC, MaxXC, MinYC, MaxYC, MaxXin, MaxYin, MarginLeft, MarginTop);

}

else if (strncmp(buffer, "DrawChartBorder", 15) == 0) { GraphLib::DrawChartBorder();

}

else if (strncmp(buffer, "DrawAxes", 8) == 0) { GraphLib::DrawAxes();

}

}

}

DisconnectNamedPipe(hPipe); /// Отсоединяемся с клиентом

}

return 0;

}

41

draw_func.h

///------------------

///Библиотека функций отрисовки (H)

///------------------

#include

<graphics.h>

 

 

 

#ifndef _MGRAPH_LIB_

 

 

 

#define _MGRAPH_LIB_

 

 

 

namespace

GraphLib {

 

 

 

using

NumericalType = long double;

 

void

InitDrawPanel(int foreColor, int backColor);

 

void

InitGraph(

MinXC,

 

 

NumericalType

 

 

NumericalType

MaxXC,

 

 

NumericalType

MinYC,

 

 

NumericalType

MaxYC,

 

 

NumericalType

COEF_MAX_X_IN,

 

NumericalType

COEF_MAX_Y_IN,

 

NumericalType

COEF_MARGIN_LEFT_IN,

 

NumericalType

COEF_MARGIN_TOP_IN);

 

void

ClearDevice();

 

 

void

CloseWindow();

 

 

void

DrawPoint(NumericalType x, NumericalType y, int size = 3, int color = 15);

void

DrawChartBorder(int color = LIGHTBLUE);

 

void

DrawAxes();

x1, int y1, int x2, int y2, int color);

void

DrawLine(int

void

DrawLinesAndValues(int

iDisplayedValues = 6);

void

DrawText(int

x, int y,

char *textString, int

color);

}

#endif

42

draw_func.cpp

///------------------

///Библиотека функций отрисовки (CPP)

///------------------

#include <graphics.h>

#include <cstring> namespace GraphLib {

/// Числовой тип

using NumericalType = long double;

/// Ширина и высота окна вывода графики const unsigned int MWINDOW_WIDTH = 700; const unsigned int MWINDOW_HEIGHT = 700;

/// Размер буфера для экспоненциальной записи числа const unsigned int SIZE_OF_BUFFER = 20;

/// Количество отображаемых значений unsigned int Displayed_Values = 6;

///Коэффициенты размера графика

NumericalType COEF_MAX_X = 0.6L; NumericalType COEF_MAX_Y = 0.6L;

///Коэффициенты расположения графика

NumericalType COEF_MARGIN_LEFT = 0.25L; NumericalType COEF_MARGIN_TOP = 0.2L;

///Максимальные значения координат для графика

NumericalType MaxX;

NumericalType MaxY;

/// Отступы

NumericalType margin_left; NumericalType margin_top;

/// Стандартные цвета int ForeColor = WHITE; int BackColor = BLACK;

/// Минимальные и максимальные координаты

NumericalType MinXCoordinate;

NumericalType MaxXCoordinate;

NumericalType MinYCoordinate;

NumericalType MaxYCoordinate;

/// Функции

void InitDrawPanel(int foreColor, int backColor); void ClearDevice();

void CloseWindow();

void DrawPoint(NumericalType, NumericalType, int size = 3, int color = WHITE); void InitGraph(

NumericalType MinXC,

NumericalType MaxXC,

NumericalType MinYC,

NumericalType MaxYC,

NumericalType COEF_MAX_X_IN,

NumericalType COEF_MAX_Y_IN,

NumericalType COEF_MARGIN_LEFT_IN,

NumericalType COEF_MARGIN_TOP_IN);

void DrawChartBorder(int color = LIGHTBLUE); void DrawAxes();

void DrawText(int x, int y, char *textString, int color); void DrawLinesAndValues(int iDisplayedValues = 6);

void DrawLine(int x1, int y1, int x2, int y2, int color);

}

/// Запуск окна вывода графики (стартовая функция)

void GraphLib::InitDrawPanel(int foreColor, int backColor) { initwindow(

MWINDOW_WIDTH, /// Ширина

MWINDOW_HEIGHT, /// Высота

43

(const char *)"", /// Заголовок

0, /// Отступ слева

0, /// Отступ сверху false, /// Флаг дебага false /// Флаг закрытия

);

BackColor = backColor; ForeColor = foreColor;

settextstyle(SANS_SERIF_FONT, 0, 1); setfillstyle(SOLID_FILL, ForeColor); setbkcolor(BackColor); setcolor(ForeColor);

}

/// Инициализация графика void GraphLib::InitGraph(

NumericalType MinXC, /// Минимальный X NumericalType MaxXC, /// Максимальный X NumericalType MinYC, /// Минимальный Y NumericalType MaxYC, /// Максимальный Y

NumericalType COEF_MAX_X_IN, /// Коэффициент размера по X NumericalType COEF_MAX_Y_IN, /// Коэффициент размера по Y NumericalType COEF_MARGIN_LEFT_IN, /// Коэффициент расположения по X NumericalType COEF_MARGIN_TOP_IN) /// Коэффициент расположения по Y

{

MinXCoordinate = MinXC;

MaxXCoordinate = MaxXC;

MinYCoordinate = MinYC;

MaxYCoordinate = MaxYC; COEF_MAX_X = COEF_MAX_X_IN; COEF_MAX_Y = COEF_MAX_Y_IN; MaxX = getmaxx() * COEF_MAX_X; MaxY = getmaxy() * COEF_MAX_Y;

COEF_MARGIN_LEFT = COEF_MARGIN_LEFT_IN; COEF_MARGIN_TOP = COEF_MARGIN_TOP_IN; margin_left = getmaxx() * COEF_MARGIN_LEFT; margin_top = getmaxy() * COEF_MARGIN_TOP;

}

/// Очистка окна

void GraphLib::ClearDevice() { cleardevice();

}

/// Закрытие окна

void GraphLib::CloseWindow() { closegraph(CURRENT_WINDOW);

}

/// Рисование линии

void GraphLib::DrawLine(int x1, int y1, int x2, int y2, int color) { setcolor(color);

/// Расчет относительной координаты X int kX1 = (x1 - MinXCoordinate)

* MaxX / (MaxXCoordinate - MinXCoordinate); int kX2 = (x2 - MinXCoordinate)

* MaxX / (MaxXCoordinate - MinXCoordinate);

/// Расчет относительной координаты Y int kY1 = (y1 - MinYCoordinate)

*MaxY / (MaxYCoordinate - MinYCoordinate); int kY2 = (y2 - MinYCoordinate)

*MaxY / (MaxYCoordinate - MinYCoordinate);

///Если выход за границы, то нормализация

kX1 = (kX1 < 0) ? 0 : (kX1 > MaxX ? MaxX : kX1);

kX2 = (kX2 < 0) ? 0 : (kX2 > MaxX ? MaxX : kX2);

kY1 = (kY1 < 0) ? 0 : (kY1 > MaxY ? MaxY : kY1);

44

kY2 = (kY2 < 0) ? 0 : (kY2 > MaxY ? MaxY : kY2);

/// Отрисовка line(

margin_left + kX1, margin_top + MaxY - kY1, margin_left + kX2, margin_top + MaxY - kY2

);

}

/// Рисование точки

void GraphLib::DrawPoint(NumericalType x, NumericalType y, int size, int color)

{

setfillstyle(SOLID_FILL, color);

/// Расчет относительной координаты X int kX = (x - MinXCoordinate)

* MaxX / (MaxXCoordinate - MinXCoordinate);

/// Расчет относительной координаты Y int kY = (y - MinYCoordinate)

* MaxY / (MaxYCoordinate - MinYCoordinate); fillellipse(

margin_left + kX, margin_top + MaxY - kY, size,

size

);

}

/// Рисование границы графика

void GraphLib::DrawChartBorder(int color) { setcolor(color);

rectangle( margin_left - 5, margin_top - 5,

margin_left + MaxX + 5, margin_top + MaxY + 5

);

}

/// Рисование осей

void GraphLib::DrawAxes() {

setcolor(ForeColor); int kX = MaxX * (

1.0L - MaxXCoordinate / (MaxXCoordinate - MinXCoordinate)

);

int kY = MaxY * MaxYCoordinate / (MaxYCoordinate - MinYCoordinate);

///Коррекция расположения отображаемых осей и их символов

///X

kX = (kX < 0) ? 0 : (kX > MaxX ? MaxX : kX);

/// Y

kY = (kY < 0) ? 0 : (kY > MaxY ? MaxY : kY);

/// Ось X

bar(margin_left + kX - 1, margin_top, margin_left + kX + 1, margin_top + MaxY);

/// Обозначение оси X

outtextxy(margin_left + MaxX + 10, margin_top + kY - 10, (char *)"X");

/// Ось Y

bar(margin_left, margin_top + kY - 1, margin_left + MaxX, margin_top + kY + 1);

/// Обозначение оси Y

outtextxy(margin_left + kX - 1, margin_top - 30, (char *)"Y");

}

void GraphLib::DrawText(int x, int y, char *textString, int color) {

45

setcolor(color); outtextxy(x, y, textString);

}

void GraphLib::DrawLinesAndValues(int iDisplayedValues) { Displayed_Values = iDisplayedValues;

///RDX - Реальная разница между двумя точками (X) NumericalType rdx = MaxX / (Displayed_Values - 1);

///RDY - Реальная разница между двумя точками (Y)

NumericalType rdy = MaxY / (Displayed_Values - 1);

///DX - Отображаемая разница между двумя точками (X)

NumericalType dx = (MaxXCoordinate - MinXCoordinate) / (Displayed_Values - 1); if (dx < 0) {

dx = -dx;

}

/// DY - Отображаемая разница между двумя точками (Y)

NumericalType dy = (MaxYCoordinate - MinYCoordinate) / (Displayed_Values - 1); if (dy < 0) {

dy = -dy;

}

///Размер шага для отображаемых линий (X)

NumericalType StepX = MinXCoordinate;

///Размер шага для отображаемых линий (Y)

NumericalType StepY = MaxYCoordinate;

///Буфер для работы с экспоненциальной записью числа char Buff[SIZE_OF_BUFFER];

///Тип линии: пунктир

setlinestyle(DOTTED_LINE, 1, 1);

/// Рисовать промежуточные линии с промежуточными значениями for (int i = 0; i < Displayed_Values; i++) {

setcolor(ForeColor);

sprintf(Buff, "%Le", StepX); /// X settextjustify(CENTER_TEXT, VCENTER_TEXT); outtextxy(

margin_left + (rdx + 2) * i,

margin_top + MaxY + 25 + 20 * (i % 2 != 0), Buff

);

sprintf(Buff, "%Le", StepY); /// Y settextjustify(RIGHT_TEXT, VCENTER_TEXT); outtextxy(

margin_left - 20, margin_top + (rdy + 1) * i, Buff

);

setcolor(DARKGRAY); line( /// Линия X

margin_left + (rdx + 0.5) * i - 1, margin_top + MaxY,

margin_left + (rdx + 0.5) * i - 1, margin_top - 4

);

line( /// Линия Y margin_left - 1,

margin_top + (rdy + 0.6) * i - 2, margin_left + MaxY + 10, margin_top + (rdy + 0.6) * i - 2

);

StepX += dx; StepY -= dy;

}

}

46