#include #include #include #include #include "..\header\rozklad.cpp" #include "..\header\simpson.cpp" #include "..\header\grn.cpp" #define ID_BUTTON1 3899 #define ID_BUTTON2 3999 #define ID_BUTTON3 4000 // przestrzen zmiennych globalnych i funkcji z ktorych korzysta // funkcja rysujaca histogram namespace histogram { // ilosc liczb losowych do wygenerowania long int k = 1000; // ilosc slupkow histogramu long int L = 10; // funkcja zwraca ilosc wystapien zmiennej losowej x // w przedziale otwartym (a,b) long int licznosc(double a, double b, double x[]); // funkcja porownuje dwa elementy, przekazywana do funkcji // sortwania szybkiego qsort int sort_function(const void* a, const void* b); // zmienna logiczna przjmuje wartosc true w przypadku // gdy zaszlo zadanie wyrysowania histogramu bool rysuj_histogram = false; } // funkcja wyrysowuje histogram korzstajac z przekazanego // uchwytu kontekstu urzadzenia i aktualnej rozdzielczosci // okna void histogram_rozkladu_normalnego(HDC hdc,int cx,int cy); // zmienne globalne rozkladu normalnego //------------------------------------------------------------------------------ // parametry rozkladu wraz ze wskaznikami oscylujacymi // pomiedzy ich wartosciami o skok wielkosci h1 // (opcja multiwykresu) static double mi = 0.0; static double sigma = 1.0; static double mi1 = 0.0; static double sigma1 = 1.0; static double wsk_mi = mi; static double wsk_sigma = sigma; static double h1 = 0.4; // empirycznie dobrana wartosc maksimum na osi OX // gestosci rozkladu static const double f_max_wykresu = 0.8; // przedzial dziedziny funkcji const double A = -4.0; const double B = 4.0; // dokladnosc wartosci gestosci rozkladu i dystrybuanty static const double h = 0.01; // ilosc podprzedzialow const long int il_h = (B-A)/h + 1; // tablica wartosci gestosci rozkladu i dystrybuanty ROZKLAD* N = new ROZKLAD[il_h]; // tablica przeskalowanych punktow wykresu gestosci POINT* PW = new POINT[il_h]; // tablica przeskalowanych punktow wykresu dystrybuanty POINT* PD = new POINT[il_h]; //bufor textowy do przechwytu wartosci z okna edycyjnego static char buff[10]; //adres znaku w buforze ktory spowodowal blad przechwytu static char* endptr; //-------------------------------------------------------------------------- //----------deklaracje funkcji--------------------------------------------- // funkcja gestosci rozkladu normalnego double dNf(double x); // funkcja podcalkowa dystrybuanty double dNfpdc(double x); // funkcja rysuje wspolrzedne rozkladu korzystajac z przekazanego // uchwytu urzadzenia i aktualnej rozdzielczosci okna void rys_wsp(HDC hdc,int cx,int cy); // funkcja wylicza, skaluje i rysuje krzywa gestosci i dystrybuante // rozkladu normalnego void rys_wykresy(HDC hdc,int cx,int cy); LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; //--------------------------------------------------------------------------- // funcja tworzy i rejestruje w systemie glowna klase okna programu // oraz obsluguje petle komunikatow do niego skierowanych int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = "rozklad normalny "; HWND hwnd; MSG msg ; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("Program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("Rozklad normalny"), WS_OVERLAPPEDWINDOW, 0, 0, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } // procedura okna glownego programu LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static HDC hdc ; static HINSTANCE hinstance; static HWND edit_mi, edit_sigma, edit_mi1, edit_sigma1, edit_h1, edit_liczby_losowe, edit_ilosc_przedzialow, button1, button2, button3; static int cx ; static int cy ; static PAINTSTRUCT ps ; // struktura zawierajaca wspolrzedne kwadratowej powierzchni okna // ktora chcemy odswierzyc static RECT kwadrat; // obsluga komunikatow sierowanych do okna switch (message) { case WM_SIZE: // pobierz rozdzielczosc aktuanego okna cx = LOWORD (lParam) ; cy = HIWORD (lParam) ; // ustaw wsporzedne powierzchni do uaktualnienia kwadrat.left = 0; kwadrat.top = cy /4; kwadrat.right = cx; kwadrat.bottom = cy; break ; // tworzenie obiektow w oknie programu case WM_CREATE: hinstance = ((LPCREATESTRUCT)lParam)->hInstance; edit_mi = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "0.00", WS_CHILD | WS_VISIBLE | WS_BORDER, 50, 60, 40, 22, hwnd, NULL, hinstance, NULL); edit_sigma = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "1.00", WS_CHILD | WS_VISIBLE | WS_BORDER, 50, 100, 40, 22, hwnd, NULL,hinstance, NULL); edit_mi1 = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "0.00", WS_CHILD | WS_VISIBLE | WS_BORDER, 170, 60, 40, 22, hwnd, NULL, hinstance, NULL); edit_sigma1 = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "1.00", WS_CHILD | WS_VISIBLE | WS_BORDER, 170, 100, 40, 22, hwnd, NULL,hinstance, NULL); edit_h1 = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "0.40", WS_CHILD | WS_VISIBLE | WS_BORDER, 110, 140, 40, 22, hwnd, NULL, hinstance, NULL); edit_liczby_losowe = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "10000", WS_CHILD | WS_VISIBLE | WS_BORDER, 610, 80, 50, 22, hwnd, NULL, hinstance, NULL); edit_ilosc_przedzialow = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "20", WS_CHILD | WS_VISIBLE | WS_BORDER, 610, 110, 40, 22, hwnd, NULL, hinstance, NULL); button1 = CreateWindowEx(WS_EX_CLIENTEDGE,"button","Rysuj", WS_CHILD | WS_VISIBLE, 220, 100, 50, 25, hwnd,(HMENU)ID_BUTTON1, hinstance, NULL); button2 = CreateWindowEx(WS_EX_CLIENTEDGE,"button","Wartosci", WS_CHILD | WS_VISIBLE, 300, 100, 100, 25, hwnd,(HMENU)ID_BUTTON2, hinstance, NULL); button3 = CreateWindowEx(WS_EX_CLIENTEDGE,"button","Histogram", WS_CHILD | WS_VISIBLE, 500, 50, 90, 23, hwnd,(HMENU)ID_BUTTON3, hinstance, NULL); break; case WM_COMMAND: switch(wParam) { case ID_BUTTON1: //-----------------------------------------pobierz wartosc mi SendMessage(edit_mi,WM_GETTEXT,5,(LPARAM)buff); strtod(buff, &endptr); if(*endptr != NULL) { MessageBox (hwnd, TEXT ("bledny format liczby"), TEXT("Blad krytyczny"), MB_ICONERROR) ; SendMessage(edit_mi,WM_SETTEXT,0,(LPARAM)TEXT("0.00")); } SendMessage(edit_mi,WM_GETTEXT,5,(LPARAM)buff); mi = strtod(buff, &endptr); //------------------------------------- pobierz wartosc sigma SendMessage(edit_sigma,WM_GETTEXT,5,(LPARAM)buff); strtod(buff, &endptr); if(*endptr != NULL) { MessageBox (hwnd, TEXT ("bledny format liczby"), TEXT("Blad krytyczny"), MB_ICONERROR) ; SendMessage(edit_sigma,WM_SETTEXT,0,(LPARAM)TEXT("1.00")); } SendMessage(edit_sigma,WM_GETTEXT,5,(LPARAM)buff); sigma = strtod(buff, &endptr); if (sigma <= 0) { MessageBox (hwnd, TEXT ("parametr sigma musi byc > 0"), TEXT("Blad krytyczny"), MB_ICONERROR) ; sigma = 1.0; SendMessage(edit_sigma,WM_SETTEXT,0,(LPARAM)TEXT("1.00")); } //--------------------------------------- pobierz wartosc mi1 SendMessage(edit_mi1,WM_GETTEXT,5,(LPARAM)buff); strtod(buff, &endptr); if(*endptr != NULL) { MessageBox (hwnd, TEXT ("bledny format liczby"), TEXT("Blad krytyczny"), MB_ICONERROR) ; SendMessage(edit_mi1,WM_SETTEXT,0,(LPARAM)TEXT("0.00")); } SendMessage(edit_mi1,WM_GETTEXT,5,(LPARAM)buff); mi1 = strtod(buff, &endptr); //------------------------------------ pobierz wartosc sigma1 SendMessage(edit_sigma1,WM_GETTEXT,5,(LPARAM)buff); strtod(buff, &endptr); if(*endptr != NULL) { MessageBox (hwnd, TEXT ("bledny format liczby"), TEXT("Blad krytyczny"), MB_ICONERROR) ; SendMessage(edit_sigma1,WM_SETTEXT,0,(LPARAM)TEXT("1.00")); } SendMessage(edit_sigma1,WM_GETTEXT,5,(LPARAM)buff); sigma1 = strtod(buff, &endptr); //---------------------------------------- pobierz wartosc h1 SendMessage(edit_h1,WM_GETTEXT,5,(LPARAM)buff); strtod(buff, &endptr); if(*endptr != NULL) { MessageBox (hwnd, TEXT ("bledny format liczby"), TEXT("Blad krytyczny"), MB_ICONERROR) ; SendMessage(edit_h1,WM_SETTEXT,0,(LPARAM)TEXT("0.20")); } SendMessage(edit_h1,WM_GETTEXT,5,(LPARAM)buff); h1 = strtod(buff, &endptr); //----------------------------------obsluga bledow pobierania if (h1 <= 0) { MessageBox (hwnd, TEXT ("rozdzielczosc musi byc > 0 "), TEXT("Blad krytyczny"), MB_ICONERROR) ; h1 = 0.2; SendMessage(edit_h1,WM_SETTEXT,0,(LPARAM)TEXT("0.20")); } if ( (mi > mi1) || (sigma > sigma1) ) { MessageBox (hwnd, TEXT ("parametry sigma1 i mi1 muszabyc wieksze od mi i sigma"), TEXT("Blad krytyczny"), MB_ICONERROR) ; mi = mi1 = 0; sigma = sigma1 = 1; SendMessage(edit_mi, WM_SETTEXT,0,(LPARAM)TEXT("0.00")); SendMessage(edit_mi1, WM_SETTEXT,0,(LPARAM)TEXT("0.00")); SendMessage(edit_sigma, WM_SETTEXT,0,(LPARAM)TEXT("1.00")); SendMessage(edit_sigma1,WM_SETTEXT,0,(LPARAM)TEXT("1.00")); } histogram::rysuj_histogram = false; InvalidateRect(hwnd, &kwadrat,TRUE); break; case ID_BUTTON2: // wypisz wartosci funkcji gestosci rozkladu i dystrybuanty // w nowym oknie wartosci_rozkladu(hwnd, N, il_h); break; case ID_BUTTON3: //------------------------------popbierz ilosc liczb losowych SendMessage(edit_liczby_losowe,WM_GETTEXT,5,(LPARAM)buff); strtod(buff, &endptr); if(*endptr != NULL) { MessageBox (hwnd, TEXT ("bledny format liczby"), TEXT("Blad krytyczny"), MB_ICONERROR) ; SendMessage(edit_liczby_losowe,WM_SETTEXT,0,(LPARAM)TEXT("1000")); } SendMessage(edit_liczby_losowe,WM_GETTEXT,5,(LPARAM)buff); histogram::k = strtod(buff, &endptr); //--------------------------popbierz ilosc slopkow histogramu SendMessage(edit_ilosc_przedzialow,WM_GETTEXT,5,(LPARAM)buff); strtod(buff, &endptr); if(*endptr != NULL) { MessageBox (hwnd, TEXT ("bledny format liczby"), TEXT("Blad krytyczny"), MB_ICONERROR) ; SendMessage(edit_ilosc_przedzialow,WM_SETTEXT,0,(LPARAM)TEXT("10")); } SendMessage(edit_ilosc_przedzialow,WM_GETTEXT,5,(LPARAM)buff); histogram::L = strtod(buff, &endptr); histogram::rysuj_histogram = true; InvalidateRect(hwnd, &kwadrat,TRUE); break; } // zakonczenie switch(wparam) break; // zakonczenie case WM_COMMAND case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; TextOut(hdc, 5, 2, "Rozklad normalny z parametrami mi i sigma (mi = R, sigma >0) dziedzina funkcji (-4,4)",85); TextOut(hdc, 5, 20, "Rysunek wielowykresowy w zakresie od mi -> mi1 i sigma -> sigma1 przy zadanej rozdzielczosci;",93); TextOut(hdc, 5, 38, " (mi >= mi1, sigma >= sigma1)",29); TextOut(hdc, 5, 62, "mi = ---> mi1",31); TextOut(hdc, 5, 102, "sigma ---> sigma1",29); TextOut(hdc, 5, 140, "Rozdzieczosc",12); TextOut(hdc, 500, 80, "Liczby losowe",13); TextOut(hdc, 490, 110, "ilosc przedzialow",17); // rysuj wsporzedne wykresu rys_wsp(hdc,cx,cy); // ustaw wskazniki oscylujace pomiedzy wartosciami // mi,sigma a wartosciami mi1 i sigma1 wsk_mi = mi; wsk_sigma = sigma; // jesli wystapilo zadanie rysowania histogramu if( histogram::rysuj_histogram ) histogram_rozkladu_normalnego(hdc, cx, cy); // petle wywolujace funkcje rysujaca rozklad. // kilkakrotnie jezeli wartosci mi,sigma oraz mi1 i sigma1 // roznia sie od siebie odpowiednio while(wsk_mi <= mi1) { while(wsk_sigma <= sigma1) { rys_wykresy(hdc,cx,cy); wsk_sigma +=h1; } wsk_sigma = sigma; wsk_mi +=h1; } EndPaint(hwnd, &ps); break ; case WM_DESTROY: delete[] N; delete[] PW; delete[] PD; PostQuitMessage (0) ; break ; } return DefWindowProc (hwnd, message, wParam, lParam) ; } //----------------------------------------------------------- void rys_wsp(HDC hdc,int cx,int cy) { //----------------------------------------------------------- MoveToEx (hdc, 0, cy/4, NULL); LineTo (hdc, cx, cy/4); //------------------liczby----------------------------------- TextOut(hdc, 2,(cy-20) - ((cy/2-20+6)/8*2),"--0.2",5); TextOut(hdc, 2,(cy-20) - ((cy/2-20+6)/8*4),"--0.4",5); //OY TextOut(hdc, 2,(cy-20) - ((cy/2-20+6)/8*6),"--0.6",5); TextOut(hdc, 2,(cy-20) - (cy/2-20+6), "--0.8",5); TextOut(hdc, 2+cx/2,(cy-20) - (cy/2-20+6), "--1",3); //OY dystryb TextOut(hdc, 0,(cy-15), "0",1); TextOut(hdc, (cx/2-10)/8 ,(cy-15), "-3",2); TextOut(hdc, (cx/2-10)/8*2,(cy-15), "-2",2); TextOut(hdc, (cx/2-10)/8*3,(cy-15), "-1",2); TextOut(hdc, (cx/2-10)/8*4,(cy-15), "0",1); TextOut(hdc, (cx/2-10)/8*5,(cy-15), "1",1); TextOut(hdc, (cx/2-10)/8*6,(cy-15), "2",1); TextOut(hdc, (cx/2-10)/8*7,(cy-15), "3",1); TextOut(hdc, (cx/2-10) ,(cy-15), "4",1); TextOut(hdc, 0+(cx/2)+5,(cy-15), "0",1); TextOut(hdc, (cx/2-10)/8 +(cx/2),(cy-15), "-3",2); TextOut(hdc, (cx/2-10)/8*2+(cx/2),(cy-15), "-2",2); TextOut(hdc, (cx/2-10)/8*3+(cx/2),(cy-15), "-1",2); TextOut(hdc, (cx/2-10)/8*4+(cx/2),(cy-15), "0",1); TextOut(hdc, (cx/2-10)/8*5+(cx/2),(cy-15), "1",1); TextOut(hdc, (cx/2-10)/8*6+(cx/2),(cy-15), "2",1); TextOut(hdc, (cx/2-10)/8*7+(cx/2),(cy-15), "3",1); TextOut(hdc, (cx/2-10) +(cx/2),(cy-15), "4",1); TextOut(hdc, 20,cy/2-30,"f(x)",4); TextOut(hdc,cx/2+20,cy/2-30,"F(x)",4); //-----wykres 2 cwartka okna-------------------------- MoveToEx (hdc, 0, cy-20, NULL); LineTo (hdc, cx/2, cy-20); //OX MoveToEx (hdc, 5, cy-20, NULL); LineTo (hdc, 5, cy/2-20); //OY MoveToEx (hdc, 0, cy-20, NULL); LineTo (hdc, 10, cy-30); //strzalka ox lewa MoveToEx (hdc, 0, cy-20, NULL); LineTo (hdc, 10, cy-10); MoveToEx (hdc, cx/2, cy-20, NULL); LineTo (hdc, cx/2-10, cy-30); //strzalka ox prawa MoveToEx (hdc, cx/2, cy-20, NULL); LineTo (hdc, cx/2-10, cy-10); MoveToEx (hdc, 5, cy/2-20, NULL); LineTo (hdc, 15, cy/2-10); //strzalka oy MoveToEx (hdc, 5, cy/2-20, NULL); LineTo (hdc, 0, cy/2-15); //--------wykres 1 cwartka--- // przesyniecie poprzedniego o vector [cx/2+5,0] MoveToEx (hdc, 0 +cx/2+5, cy-20, NULL); LineTo (hdc, cx/2 +cx/2, cy-20); //OX MoveToEx (hdc, cx/2+5, cy-20, NULL); LineTo (hdc, cx/2+5, cy/2-20); //OY MoveToEx (hdc, 0 +cx/2+5, cy-20, NULL); LineTo (hdc, 10 +cx/2+5, cy-30); MoveToEx (hdc, 0 +cx/2+5, cy-20, NULL); LineTo (hdc, 10 +cx/2+5, cy-10); MoveToEx (hdc, cx/2 +cx/2, cy-20, NULL); LineTo (hdc, cx/2-10 +cx/2, cy-30); MoveToEx (hdc, cx/2 +cx/2, cy-20, NULL); LineTo (hdc, cx/2-10 +cx/2, cy-10); MoveToEx (hdc, 0 +cx/2+5, cy/2-20, NULL); LineTo (hdc, 0 +cx/2+5+10, cy/2-10); MoveToEx (hdc, 0 +cx/2+5, cy/2-20, NULL); LineTo (hdc, 0 +cx/2+5-10, cy/2+10-20); } double dNf(double x) { return (1/(sqrt(2*M_PI)*wsk_sigma))*(exp(-((x-wsk_mi)*(x-wsk_mi))/(2*(wsk_sigma*wsk_sigma)))); } double dNfpdc(double x) { return exp(-((x-wsk_mi)*(x-wsk_mi))/(2*(wsk_sigma*wsk_sigma))); } //------------------------------------------------------------- void rys_wykresy(HDC hdc,int cx,int cy) { for(int i=0; i