47228 (588470), страница 3
Текст из файла (страница 3)
Рисунок 3.1 – Проектируемый интерфейс
Когда сформированы ресурсы окна и подготовлен класс CFuzzyDlg для окна приложения, можно создавать объект этого класса в самой программе и выводить на экран связанное с ним диалоговое окно. В рассматриваемом случае, достаточно в методе CFuzzyApp::InitInstance() вывести диалоговое окно на экран сразу после запуска приложения, используя базовый метод CDialog::DoModal() класса диалогового окна CDialog.
Отображение результатов построения функции производится в элемент Picture. Для вывода графики в Windows и в Visual C++ используется понятие контекста устройства (device context). Контекст устройства ‑ это объект класса CDC, содержащий все методы для построения изображения в окне.
Таким образом спроектированная структура программного обеспечения является адекватной решению поставленной в техническом задании задачи.
4. ПРОГРАММНАЯ РЕАЛИЗАЦИЯ ПОСТАВЛЕННОЙ ЗАДАЧИ
Программная реализация разработанной выше структуры приложения состоит в разработке исполняемого Win32-приложения в среде визуального программирования MS Visual Studio. Проект программного обеспечения состоит из трех классов – CFuzzyApp, CFuzzyDlg, CFuzzy_.
В классе CFuzzy_ выполняются непосредственные расчеты значений функций неопределенности. Расчеты выполняются функциями-членами[6] этого класса:
- CFuzzy_::fisTriangleMf (double x, double *params) – вычисление значений треугольной функции принадлежности;
- CFuzzy_::fisTrapezoidMf(double x, double *params) – вычисление значений трапециидальной функции принадлежности;
- CFuzzy_::fisGaussianMf(double x, double *params) – вычисление значений гауссовской функции принадлежности;
- CFuzzy_::fisGaussian2Mf(double x, double *params) – вычисление значений расширенной гауссовской функции принадлежности;
- CFuzzy_::fisSigmoidMf(double x, double *params) – вычисление значений сигмоидальной функции принадлежности.
Например, функция CFuzzy_::fisTrapezoidMf(double x, double *params):
/* Trapezpoidal membership function */
double CFuzzy_::fisTrapezoidMf(double x, double *params)
{
double a = params[0], b = params[1], c = params[2], d = params[3];
double y1 = 0, y2 = 0;
if (a>b) {
fisError("Illegal parameters in fisTrapezoidMf() --> a > b");
}
if (b>c)
{
fisError("Illegal parameters in fisTrapezoidMf() --> b > c");
}
if (c>d) {
fisError("Illegal parameters in fisTrapezoidMf() --> c > d");
}
if (b <= x)
y1 = 1;
else if (x < a)
y1 = 0;
else if (a != b)
y1 = (x-a)/(b-a);
if (x <= c)
y2 = 1;
else if (d < x)
y2 = 0;
else if (c != d)
y2 = (d-x)/(d-c);
return(MIN(y1, y2));
}
Так же в классе CFuzzy_ находится функция-член fisError(char *msg), которая реализует выдачу сообщения об ошибке, если пользователь ввел неправильные данные. Само сообщение передается в функцию fisError(char *msg) в качестве параметра из функций, вычисляющих значение функций принадлежности.
В классе CFuzzyApp реализована базовая функциональность стандартного MFC-приложения. В частности, переопределен виртуальный метод базового класса CWinApp::InitInstance():
BOOL CFuzzyApp::InitInstance()
{
AfxEnableControlContainer();
#ifdef _AFXDLL
Enable3dControls();
#else
Enable3dControlsStatic();
#endif
CFuzzyDlg dlg;
m_pMainWnd = &dlg;
dlg.DoModal();
return FALSE;
}
В результате исполняемый код приложения был связан со спроектированным ранее визуальным интерфейсом (рисунок 3.1). В качестве члена в классе CFuzzyApp была введена переменная[6] dlg типа CFuzzyDlg. Она обеспечивает непосредственную связь приложения с интерфейсом, предоставляемого пользователю.
В классе CFuzzyDlg выполняется инициализация диалога и элементов управления.
BOOL CFuzzyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);
par_a.SetWindowText("1");
par_b.SetWindowText("3");
par_c.SetWindowText("5");
par_d.SetWindowText("9");
R_Tri=(CButton*)GetDlgItem(IDC_RADIO1);
R_Tra=(CButton*)GetDlgItem(IDC_RADIO2);
R_Ga=(CButton*)GetDlgItem(IDC_RADIO3);
R_Ga2=(CButton*)GetDlgItem(IDC_RADIO4);
R_Sig=(CButton*)GetDlgItem(IDC_RADIO5);
param = new double[3];
WIDTH = 600;
HEIGHT = 400;
return TRUE;
}
С помощью элементов управления, являющимися объектами класса CEdit – par_a, par_b, par_c, par_d реализуется ввод параметров для функций принадлежности.
В классе CFuzzyDlg имеются функции для построения координатных осей (функция CFuzzyDlg::Axis()) и отображения графика функции принадлежности (одна из функций CFuzzyDlg::PlotTriangle(), CFuzzyDlg::PlotTrapezoid(), CFuzzyDlg::PlotGaussian(),CFuzzyDlg::PlotGaussian2(), CFuzzyDlg::PlotSigmoid() в зависимости от типа функции, выбранной пользователем). Вывод графика осуществляется с помощью класса CDC, который
При нажатии пользователем кнопки «Построить!!» происходит выполнение функции CFuzzyDlg::OnButton1(), из которой вызываются функции построения осей и функции принадлежности, выбранной пользователем или, если не был выбран тип функции, выдается сообщение «Выберите тип функции!!».
Функции для построения координатных осей (функция CFuzzyDlg::Axis()) и отображения графика функции принадлежности (одна из функций CFuzzyDlg::PlotTriangle(), CFuzzyDlg::PlotTrapezoid(), CFuzzyDlg::PlotGaussian(),CFuzzyDlg::PlotGaussian2(), CFuzzyDlg::PlotSigmoid() в зависимости от типа функции, выбранной пользователем) вызываются так же при перерисовке окна (обработка сообщения WM_PAINT с помощью функции CFuzzyDlg::OnPaint()).
void CFuzzyDlg::OnPaint()
{
CDialog::OnPaint();
Axis();
if (function==GAUSSIAN)
PlotGaussian();
else
if (function==TRIANGLE)
PlotTriangle();
else
if (function==TRAPEZOID)
PlotTrapezoid();
else
if (function==GAUSSIAN2)
PlotGaussian2();
else
if (function==SIGMOID)
PlotSigmoid();
}
Для того чтобы определить значение данной функции распределения в конкретной точке, в класс CFuzzyDlg была добавлена функция обработки сообщения перемещения манипулятора «Мышь» WM_MOUSEMOVE ‑ CFuzzyDlg::OnMouseMove(UINT nFlags, CPoint point). При перемещении мыши выводится значение точки x (с учетом масштаба) и степень принадлежности (значение данной функции принадлежности) этой точки x.
void CFuzzyDlg::OnMouseMove(UINT nFlags, CPoint point)
{
if (point.x>10 && point.x10 && point.y { CDC *dc = m_grapho.GetDC(); CPen SolidPen; SolidPen.CreatePen(PS_SOLID,1,RGB(255,255,255)); CBrush brush; brush.CreateSolidBrush(RGB(255,255,255)); dc->SelectObject(brush); dc->SelectObject(SolidPen); dc->Rectangle(350,10,580,30); double _tmp; char crds[15]; CString coords; _tmp=(point.x-36)*1000/kX+_par; itoa((int)(_tmp),crds,10); coords=crds; itoa(ABS((int)(_tmp*100)%100),crds,10); (ABS((int)(_tmp*100)%100)<10)?coords+=".0":coords+="."; coords+=crds; if (function==GAUSSIAN) gcvt(fuzzy.fisGaussianMf(_tmp,param),2,crds); else if (function==TRIANGLE) gcvt(fuzzy.fisTriangleMf(_tmp,param),2,crds); else if (function==TRAPEZOID) gcvt(fuzzy.fisTrapezoidMf(_tmp,param),2,crds); else if (function==GAUSSIAN2) gcvt(fuzzy.fisGaussian2Mf(_tmp,param),2,crds); else if (function==SIGMOID) gcvt(fuzzy.fisSigmoidMf(_tmp,param),2,crds); else crds[0]='\0'; CFont *font = new CFont(); font->CreateFont(14, 10, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Courier"); dc->SelectObject(font); dc->TextOut(50,10,"Точка x:"+coords+" Степень принадлежности:"+crds); } CDialog::OnMouseMove(nFlags, point); } Результат выполнения программы изображен на рисунке 4.1. В данном случае построена сигмоидальная функция принадлежности. Рисунок 4.1 – Результат выполнения программы – сигмоидальная функция принадлежности ВЫВОДЫ Результатом работы является исполняемое Win32-приложение, позволяющее строить следующие функции принадлежности: - треугольную; - трапециидальную; - гауссовскую; - расширенную гауссовскую; - сигмоидальную. Так же программа позволяет определять значение степени принадлежности заданной точки x. В ходе разработки приложения были изучены структура и возможности набора классов MFC, принципы проектирования визуального интерфейса пользователя в операционной среде MS Windows с использованием среды разработки MS Visual Studio. Было замечено, что классы MFC существенно ускоряют процесс создания приложений для операционной системы Microsoft Windows. Так же были изучены основы теории нечетких множеств, в частности функции принадлежности. ПЕРЕЧЕНЬ ССЫЛОК 1. Microsoft Developer Network Library ‑ April 2003 2. Васильев В.И., Ильясов Б.Г. Интеллектуальные системы управления с использованием нечеткой логики: Учеб. пособие / Уфимск. гос. авиац. техн. ун-т. -Уфа, 1995. -80 c 3. Грегори К. Использование Visual C++ 6. Специальное издание.: Пер. с англ. – М.: СПб.; К.: Издательский дом «Вильямс», 2003. – 849 с. 4. Заде Л. Понятие лингвистической переменной и его применение к принятию приближенных решений. – М.: Мир, 1976. 5. Нечеткая логика ‑ математические основы ‑ BaseGroup Labs http://www.basegroup.ru/fuzzylogic/math_print.htm 6. Страуструп Бьярн Язык программирования C++ Второе издание. – К.: ДиаСофт, 1993. – 480 с. ПРИЛОЖЕНИЕ Приложение А Листинг программы // Fuzzy_.h: interface for the CFuzzy_ class. class CFuzzy_ { public: void fisError(char *msg); CFuzzy_(); virtual ~CFuzzy_(); double CFuzzy_::fisTriangleMf(double x, double *params); double fisTrapezoidMf(double x, double *params); double fisGaussianMf(double x, double *params); double fisGaussian2Mf(double x, double *params); double fisSigmoidMf(double x, double *params); }; // Fuzzy_.cpp: implementation of the CFuzzy_ class. #include "stdafx.h" #include "fuzzy.h" #include "Fuzzy_.h" #include #ifndef ABS # define ABS(x) ( (x) > (0) ? (x): (-(x)) ) #endif #ifndef MAX # define MAX(x,y) ( (x) > (y) ? (x) : (y) ) #endif #ifndef MIN # define MIN(x,y) ( (x) < (y) ? (x) : (y) ) #endif CFuzzy_::CFuzzy_() { } CFuzzy_::~CFuzzy_() { } /* Triangular membership function */ double CFuzzy_::fisTriangleMf(double x, double *params) { double a = params[0], b = params[1], c = params[2]; if (a>b) {fisError("Illegal parameters in fisTriangleMf() --> a > b");return -1;} if (b>c) {fisError("Illegal parameters in fisTriangleMf() --> b > c");return -1;} if (a == b && b == c) return(x == a); if (a == b) return((c-x)/(c-b)*(b<=x)*(x<=c)); if (b == c) return((x-a)/(b-a)*(a<=x)*(x<=b)); return(MAX(MIN((x-a)/(b-a), (c-x)/(c-b)), 0)); } /* Trapezpoidal membership function */ double CFuzzy_::fisTrapezoidMf(double x, double *params) { double a = params[0], b = params[1], c = params[2], d = params[3]; double y1 = 0, y2 = 0; if (a>b) { fisError("Illegal parameters in fisTrapezoidMf() --> a > b"); } if (b>c) { fisError("Illegal parameters in fisTrapezoidMf() --> b > c"); } if (c>d) { fisError("Illegal parameters in fisTrapezoidMf() --> c > d"); } if (b <= x) y1 = 1; else if (x < a) y1 = 0; else if (a != b) y1 = (x-a)/(b-a); if (x <= c) y2 = 1; else if (d < x) y2 = 0; else if (c != d) y2 = (d-x)/(d-c); return(MIN(y1, y2)); } /* Gaussian membership function */ double CFuzzy_::fisGaussianMf(double x, double *params) { double sigma = params[0], c = params[1]; double tmp; if (sigma==0) fisError("Illegal parameters in fisGaussianMF() --> sigma = 0"); tmp = (x-c)/sigma; return(exp(-tmp*tmp/2)); } /* Extended Gaussian membership function */ double CFuzzy_::fisGaussian2Mf(double x, double *params) { double sigma1 = params[0], c1 = params[1]; double sigma2 = params[2], c2 = params[3]; double tmp1, tmp2; if ((sigma1 == 0) || (sigma2 == 0)) fisError("Illegal parameters in fisGaussian2MF() --> sigma1 or sigma2 is zero"); tmp1 = x >= c1? 1:exp(-pow((x-c1)/sigma1, 2.0)/2); tmp2 = x <= c2? 1:exp(-pow((x-c2)/sigma2, 2.0)/2); return(tmp1*tmp2); } /* Sigmoidal membership function */ double CFuzzy_::fisSigmoidMf(double x, double *params) { double a = params[0], c = params[1]; return(1/(1+exp(-a*(x-c)))); } void CFuzzy_::fisError(char *msg) { MessageBox(NULL,msg,"Error",MB_OK|MB_ICONSTOP); } // fuzzy.h : main header file for the FUZZY application CFuzzyApp #include "resource.h" class CFuzzyApp : public CWinApp { public: CFuzzyApp(); // Overrides // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CFuzzyApp) public: virtual BOOL InitInstance(); //}}AFX_VIRTUAL // Implementation //{{AFX_MSG(CFuzzyApp) // NOTE - the ClassWizard will add and remove member functions here. // DO NOT EDIT what you see in these blocks of generated code ! //}}AFX_MSG DECLARE_MESSAGE_MAP() }; // fuzzy.cpp : Defines the class behaviors for the application. CFuzzyApp #include "stdafx.h" #include "fuzzy.h" #include "fuzzyDlg.h" BEGIN_MESSAGE_MAP(CFuzzyApp, CWinApp) //{{AFX_MSG_MAP(CFuzzyApp) // NOTE - the ClassWizard will add and remove mapping macros here. // DO NOT EDIT what you see in these blocks of generated code! //}}AFX_MSG ON_COMMAND(ID_HELP, CWinApp::OnHelp) END_MESSAGE_MAP() CFuzzyApp::CFuzzyApp() { } CFuzzyApp theApp; // CFuzzyApp initialization BOOL CFuzzyApp::InitInstance() { AfxEnableControlContainer(); #ifdef _AFXDLL Enable3dControls(); #else Enable3dControlsStatic(); #endif CFuzzyDlg dlg; m_pMainWnd = &dlg; dlg.DoModal(); // Since the dialog has been closed, return FALSE so that we exit the // application, rather than start the application's message pump. return FALSE; } // fuzzyDlg.h : header file // CFuzzyDlg dialog class CFuzzyDlg : public CDialog { // Construction public: void PlotTrapezoid(); void PlotTriangle(); void PlotGaussian(); void PlotSigmoid(); void PlotGaussian2(); void Axis(); CButton *R_Tri, *R_Tra, *R_Ga, *R_Ga2, *R_Sig; CFuzzyDlg(CWnd* pParent = NULL);// standard constructor // Dialog Data //{{AFX_DATA(CFuzzyDlg) enum { IDD = IDD_FUZZY_DIALOG }; CEditpar_d; CEditpar_c; CEditpar_b; CEditpar_a; CStaticm_grapho; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CFuzzyDlg) protected: virtual void DoDataExchange(CDataExchange* pDX);// DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: HICON m_hIcon; // Generated message map functions //{{AFX_MSG(CFuzzyDlg) virtual BOOL OnInitDialog(); afx_msg void OnPaint(); afx_msg HCURSOR OnQueryDragIcon(); afx_msg void OnButton1(); afx_msg void OnMouseMove(UINT nFlags, CPoint point); afx_msg void OnRadio1(); afx_msg void OnRadio2(); afx_msg void OnRadio3(); afx_msg void OnRadio4(); afx_msg void OnRadio5(); //}}AFX_MSG DECLARE_MESSAGE_MAP() }; // fuzzyDlg.cpp : implementation file // #include "stdafx.h" #include "fuzzy.h" #include "fuzzyDlg.h" #include "fuzzy_.h" #ifndef ABS # define ABS(x) ( (x) > (0) ? (x): (-(x)) ) #endif #ifndef MAX # define MAX(x,y) ( (x) > (y) ? (x) : (y) ) #endif #ifndef MIN # define MIN(x,y) ( (x) < (y) ? (x) : (y) ) #endif CFuzzy_ fuzzy; double *param, x, y=0, kX=1000, _par=0; int WIDTH, HEIGHT; byte function=0; const byte TRIANGLE = 1; const byte TRAPEZOID = 2; const byte GAUSSIAN = 3; const byte GAUSSIAN2 = 4; const byte SIGMOID = 5; ///////////////////////////////////////////////////////////////////////////// // CFuzzyDlg dialog CFuzzyDlg::CFuzzyDlg(CWnd* pParent /*=NULL*/) : CDialog(CFuzzyDlg::IDD, pParent) { //{{AFX_DATA_INIT(CFuzzyDlg) //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CFuzzyDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CFuzzyDlg) DDX_Control(pDX, IDC_EDITD, par_d); DDX_Control(pDX, IDC_EDITC, par_c); DDX_Control(pDX, IDC_EDITB, par_b); DDX_Control(pDX, IDC_EDITA, par_a); DDX_Control(pDX, IDC_GRAPHO, m_grapho); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CFuzzyDlg, CDialog) //{{AFX_MSG_MAP(CFuzzyDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_BUTTON1, OnButton1) ON_WM_MOUSEMOVE() ON_BN_CLICKED(IDC_RADIO1, OnRadio1) ON_BN_CLICKED(IDC_RADIO2, OnRadio2) ON_BN_CLICKED(IDC_RADIO3, OnRadio3) ON_BN_CLICKED(IDC_RADIO4, OnRadio4) ON_BN_CLICKED(IDC_RADIO5, OnRadio5) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CFuzzyDlg message handlers BOOL CFuzzyDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE);// Set big icon SetIcon(m_hIcon, FALSE); par_a.SetWindowText("1"); par_b.SetWindowText("3"); par_c.SetWindowText("5"); par_d.SetWindowText("9"); R_Tri=(CButton*)GetDlgItem(IDC_RADIO1); R_Tra=(CButton*)GetDlgItem(IDC_RADIO2); R_Ga=(CButton*)GetDlgItem(IDC_RADIO3); R_Ga2=(CButton*)GetDlgItem(IDC_RADIO4); R_Sig=(CButton*)GetDlgItem(IDC_RADIO5); param = new double[3]; WIDTH = 600; HEIGHT = 400; // Set small icon return TRUE; // return TRUE unless you set the focus to a control } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CFuzzyDlg::OnPaint() { CDialog::OnPaint(); Axis(); if (function==GAUSSIAN) PlotGaussian(); else if (function==TRIANGLE) PlotTriangle(); else if (function==TRAPEZOID) PlotTrapezoid(); else if (function==GAUSSIAN2) PlotGaussian2(); else if (function==SIGMOID) PlotSigmoid(); } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CFuzzyDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CFuzzyDlg::OnButton1() { Axis(); if (R_Tri->GetState()==1) { PlotTriangle(); } else if (R_Tra->GetState()==1) { PlotTrapezoid(); } else if (R_Ga->GetState()==1) { PlotGaussian(); } else if (R_Ga2->GetState()==1) { PlotGaussian2(); } else if (R_Sig->GetState()==1) { PlotSigmoid(); } else AfxMessageBox("Выберите тип функции!!", MB_ICONWARNING|MB_OK, 0); } void CFuzzyDlg::OnMouseMove(UINT nFlags, CPoint point) { if (point.x>10 && point.x10 && point.y { CDC *dc = m_grapho.GetDC(); CPen SolidPen; SolidPen.CreatePen(PS_SOLID,1,RGB(255,255,255)); CBrush brush; brush.CreateSolidBrush(RGB(255,255,255)); dc->SelectObject(brush); dc->SelectObject(SolidPen); dc->Rectangle(350,10,580,30); double _tmp; char crds[15]; CString coords; _tmp=(point.x-36)*1000/kX+_par; itoa((int)(_tmp),crds,10); coords=crds; itoa(ABS((int)(_tmp*100)%100),crds,10); (ABS((int)(_tmp*100)%100)<10)?coords+=".0":coords+="."; coords+=crds; if (function==GAUSSIAN) gcvt(fuzzy.fisGaussianMf(_tmp,param),2,crds); else if (function==TRIANGLE) gcvt(fuzzy.fisTriangleMf(_tmp,param),2,crds); else if (function==TRAPEZOID) gcvt(fuzzy.fisTrapezoidMf(_tmp,param),2,crds); else if (function==GAUSSIAN2) gcvt(fuzzy.fisGaussian2Mf(_tmp,param),2,crds); else if (function==SIGMOID) gcvt(fuzzy.fisSigmoidMf(_tmp,param),2,crds); else crds[0]='\0'; CFont *font = new CFont(); font->CreateFont(14, 10, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Courier"); dc->SelectObject(font); dc->TextOut(50,10,"Точка x:"+coords+" Степень принадлежности:"+crds); } CDialog::OnMouseMove(nFlags, point); } void CFuzzyDlg::OnRadio1() { par_d.EnableWindow(false); } void CFuzzyDlg::OnRadio2() { par_c.EnableWindow(true); par_d.EnableWindow(true); } void CFuzzyDlg::OnRadio3() { par_c.EnableWindow(false); par_d.EnableWindow(false); } void CFuzzyDlg::OnRadio4() { par_c.EnableWindow(true); par_d.EnableWindow(true); } void CFuzzyDlg::OnRadio5() { par_c.EnableWindow(false); par_d.EnableWindow(false); } void CFuzzyDlg::Axis() { CDC *_dc = m_grapho.GetDC(); CPen DotPen; DotPen.CreatePen(PS_DOT,1,RGB(0,0,0)); CPen SolidPen; SolidPen.CreatePen(PS_SOLID,1,RGB(0,0,0)); CBrush brush; brush.CreateSolidBrush(RGB(255,255,255)); _dc->SelectObject(brush); _dc->Rectangle(0,0,WIDTH, HEIGHT); _dc->SelectObject(SolidPen); _dc->MoveTo(25,10); _dc->LineTo(25, HEIGHT-40); _dc->MoveTo(20,HEIGHT-40); _dc->LineTo(WIDTH-20, HEIGHT-40); _dc->SelectObject(DotPen);; CFont *font = new CFont(); font->CreateFont(12, 7, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY, DEFAULT_PITCH | FF_SWISS, "Courier"); _dc->SelectObject(font); _dc->TextOut(1,360-5,CString(" 0")); for (int q=1;q<=10;q++) { _dc->MoveTo(20,360-q*32); _dc->LineTo(580,360-q*32); char iY[5]; gcvt(q*0.1,2,iY); (q!=10)?_dc->TextOut(1,360-q*32-5,iY,3):_dc->TextOut(1,360-q*32-5,CString(" 1")); } _dc->TextOut(580,360,"x"); } void CFuzzyDlg::PlotTriangle() { function=TRIANGLE; CDC *dc = m_grapho.GetDC(); double tmp; CString par_tmp; par_a.GetWindowText(par_tmp); param[0]=atof(par_tmp); par_b.GetWindowText(par_tmp); param[1]=atof(par_tmp); par_c.GetWindowText(par_tmp); param[2]=atof(par_tmp); kX = 520000/ABS(param[2]-param[0]); _par=param[0]; for (x=param[0];x { tmp = fuzzy.fisTriangleMf(x,param); tmp*=320; dc->SetPixel((int)(((x)-param[0])*kX/1000+25),HEIGHT-40-(int)tmp, RGB(255,100,120)); } dc->Rectangle((int)((param[0]-param[0])*kX/1000+25-4),HEIGHT-40-0*320-4, (int)((param[0]-param[0])*kX/1000+25+4),HEIGHT-40-0*320+4); dc->Rectangle((int)((param[1]-param[0])*kX/1000+25-4),HEIGHT-40-1*320-4, (int)((param[1]-param[0])*kX/1000+25+4),HEIGHT-40-1*320+4); dc->Rectangle((int)((param[2]-param[0])*kX/1000+25-4),HEIGHT-40-0*320-4, (int)((param[2]-param[0])*kX/1000+25+4),HEIGHT-40-0*320+4); } void CFuzzyDlg::PlotTrapezoid() { function=TRAPEZOID; CDC *dc = m_grapho.GetDC(); double tmp; CString par_tmp; par_a.GetWindowText(par_tmp); param[0]=atof(par_tmp); par_b.GetWindowText(par_tmp); param[1]=atof(par_tmp); par_c.GetWindowText(par_tmp); param[2]=atof(par_tmp); par_d.GetWindowText(par_tmp); param[3]=atof(par_tmp); kX = 520000/ABS(param[3]-param[0]); _par=param[0]; for (x=param[0];x { tmp = fuzzy.fisTrapezoidMf(x,param); tmp*=320; dc->SetPixel((int)(((x-param[0]))*kX/1000+25),HEIGHT-40-(int)tmp, RGB(255,100,100)); } dc->Rectangle((int)((param[0]-param[0])*kX/1000+25-4),HEIGHT-40-0*320-4, (int)((param[0]-param[0])*kX/1000+25+4),HEIGHT-40-0*320+4); dc->Rectangle((int)((param[1]-param[0])*kX/1000+25-4),HEIGHT-40-1*320-4, (int)((param[1]-param[0])*kX/1000+25+4),HEIGHT-40-1*320+4); dc->Rectangle((int)((param[2]-param[0])*kX/1000+25-4),HEIGHT-40-1*320-4, (int)((param[2]-param[0])*kX/1000+25+4),HEIGHT-40-1*320+4); dc->Rectangle((int)((param[3]-param[0])*kX/1000+25-4),HEIGHT-40-0*320-4, (int)((param[3]-param[0])*kX/1000+25+4),HEIGHT-40-0*320+4); } void CFuzzyDlg::PlotGaussian() { function=GAUSSIAN; CDC *dc = m_grapho.GetDC(); double tmp; CString par_tmp; par_a.GetWindowText(par_tmp); param[0]=atof(par_tmp); par_b.GetWindowText(par_tmp); param[1]=atof(par_tmp); par_c.GetWindowText(par_tmp); param[2]=atof(par_tmp); par_d.GetWindowText(par_tmp); param[3]=atof(par_tmp); double _0=param[1]; do { tmp = fuzzy.fisGaussianMf(_0,param); _0-=ABS(param[1])/1000; } while (tmp>=0.001); kX = 520000/(2*ABS(param[1]-_0)); _par = _0; for (x=_0;x<(param[1]+ABS(param[1]-_0));x+=ABS((param[1]+ABS(param[1]-_0))-_0)/8000) { tmp = fuzzy.fisGaussianMf(x,param); tmp*=320; dc->SetPixel((int)(((x)-_0)*kX/1000+25),HEIGHT-40-(int)tmp, RGB(255,100,100)); } dc->Rectangle((int)((param[1]-_0)*kX/1000+25-4),HEIGHT-40-1*320-4, (int)((param[1]-_0)*kX/1000+25+4),HEIGHT-40-1*320+4); } void CFuzzyDlg::PlotGaussian2() { function=GAUSSIAN2; CDC *dc = m_grapho.GetDC(); double tmp; CString par_tmp; par_a.GetWindowText(par_tmp); param[0]=atof(par_tmp); par_b.GetWindowText(par_tmp); param[1]=atof(par_tmp); par_c.GetWindowText(par_tmp); param[2]=atof(par_tmp); par_d.GetWindowText(par_tmp); param[3]=atof(par_tmp); double _0=MIN(param[1], param[3]); do { tmp = fuzzy.fisGaussian2Mf(_0,param); _0-=ABS(MIN(param[1], param[3]))/10000; } while (tmp>=0.001); kX = 520000/(ABS(MAX(param[1], param[3])-_0)); _par = _0; for (x=_0;x<=MAX(param[1], param[3]);x+=ABS((MAX(param[1], param[3])-_0))/10000) { tmp = fuzzy.fisGaussian2Mf(x,param); tmp*=320; dc->SetPixel((int)(((x)-_0)*kX/1000+25),HEIGHT-40-(int)tmp, RGB(255,100,100)); } dc->Rectangle((int)((MAX(param[1], param[3])-_0)*kX/1000+25-4),HEIGHT-40-1*320-4, (int)((MAX(param[1], param[3])-_0)*kX/1000+25+4),HEIGHT-40-1*320+4); } void CFuzzyDlg::PlotSigmoid() { function=SIGMOID; CDC *dc = m_grapho.GetDC(); double tmp; CString par_tmp; par_a.GetWindowText(par_tmp); param[0]=atof(par_tmp); par_b.GetWindowText(par_tmp); param[1]=atof(par_tmp); par_c.GetWindowText(par_tmp); param[2]=atof(par_tmp); par_d.GetWindowText(par_tmp); param[3]=atof(par_tmp); double _0=param[1],_1=param[1]; do { tmp = fuzzy.fisSigmoidMf(_0,param); _0-=param[1]*0.0001; } while (tmp>=0.0001); do { tmp = fuzzy.fisSigmoidMf(_1,param); _1+=param[1]*0.0001; } while(tmp<0.99999); kX = 520000/(ABS(_1-_0)); _par = _0; for (x=_0;x<=_1;x+=ABS(param[1]*0.0001)) { tmp = fuzzy.fisSigmoidMf(x,param); tmp*=320; dc->SetPixel((int)(((x)-_0)*kX/1000+25),HEIGHT-40-(int)tmp, RGB(255,100,100)); } dc->Rectangle((int)((param[1]-_0)*kX/1000+25-4),(int)(HEIGHT-40-0.5*320-4),(int)((param[1]-_0)*kX/1000+25+4),(int)(HEIGHT-40-0.5*320+4)); }