algorytm.org

Implementacja w C/C++

Baza Wiedzy
wersja offline serwisu przeznaczona na urządzenia z systemem Android
Darowizny
darowiznaWspomóż rozwój serwisu
Nagłówki RSS
Artykuły
Implementacje
Komentarze
Forum
Bookmarki






Sonda
Implementacji w jakim języku programowania poszukujesz?

Okrąg przechodzący przez dane trzy punkty - Implementacja w C/C++
Ocena użytkownikóww: *****  / 6
SłabyŚwietny
Nadesłany przez Krzysztof Zajączkowski, 07 stycznia 2009 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.
Pobierz pełne rozwiązanie.

Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.

Circle/main.cpp:
#include <windows.h>

#include <math.h>

// Autor programu:  Krzysztof Zajączkowski

/*  Declare Windows procedure  */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);

/*  Make the class name into a global variable  */
char szClassName[ ] = "CodeBlocksWindowsApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR lpszArgument,
                     int nCmdShow)
{
    HWND hwnd;               /* This is the handle for our window */
    MSG messages;            /* Here messages to the application are saved */
    WNDCLASSEX wincl;        /* Data structure for the windowclass */

    /* The Window structure */
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;      /* This function is called by windows */
    wincl.style = CS_DBLCLKS;                 /* Catch double-clicks */
    wincl.cbSize = sizeof (WNDCLASSEX);

    /* Use default icon and mouse-pointer */
    wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
    wincl.lpszMenuName = NULL;                 /* No menu */
    wincl.cbClsExtra = 0;                      /* No extra bytes after the window class */
    wincl.cbWndExtra = 0;                      /* structure or the window instance */
    /* Use Windows's default colour as the background of the window */
    wincl.hbrBackground = CreateSolidBrush(RGB(0,0,0));

    /* Register the window class, and if it fails quit the program */
    if (!RegisterClassEx (&wincl))
        return 0;

    /* The class is registered, let's create the program*/
    hwnd = CreateWindowEx (
           0,                   /* Extended possibilites for variation */
           szClassName,         /* Classname */
           "Autor: Krzysztof Zajączkowski",       /* Title Text */
           WS_OVERLAPPEDWINDOW, /* default window */
           CW_USEDEFAULT,       /* Windows decides the position */
           CW_USEDEFAULT,       /* where the window ends up on the screen */
           544,                 /* The programs width */
           375,                 /* and height in pixels */
           HWND_DESKTOP,        /* The window is a child-window to desktop */
           NULL,                /* No menu */
           hThisInstance,       /* Program Instance handler */
           NULL                 /* No Window Creation data */
           );

    /* Make the window visible on the screen */
    ShowWindow (hwnd, nCmdShow);

    /* Run the message loop. It will run until GetMessage() returns 0 */
    while (GetMessage (&messages, NULL, 0, 0))
    {
        /* Translate virtual-key messages into character messages */
        TranslateMessage(&messages);
        /* Send message to WindowProcedure */
        DispatchMessage(&messages);
    }

    /* The program return-value is 0 - The value that PostQuitMessage() gave */


    return messages.wParam;
}


/*  This function is called by the Windows function DispatchMessage()  */

class dPoint{ // Klasa pomocnicza do przechowywania informacji o punktach
public:
    double x;
    double y;

    dPoint();
    dPoint(double x,double y);

    operator POINT();
    dPoint operator -(dPoint dp2d);

    double Length();
};

dPoint::dPoint(){
    x = y = 0;
}

dPoint::dPoint(double x,double y){
    this->x = x;
    this->y = y;
}

dPoint::operator POINT(){
    POINT pt;
    pt.x = (long)x;
    pt.y = (long)y;

    return pt;
}

dPoint dPoint::operator -(dPoint dp2d){
    dPoint pt(x - dp2d.x,y - dp2d.y);
    return pt;
}

double dPoint::Length(){
    return pow(x*x+y*y,0.5);
}

dPoint p1(80,90); // Kolejne punkty okręgu
dPoint p2(40,50);
dPoint p3(10,10);
dPoint cp; // Zmienna przechowująca położenie środka okręgu

long ray = 0; // Zmienna przechowująca promień okręgu

dPoint CircleCenter(double x1,double y1,double x2,double y2,double x3,double y3){ // Funkcja licząca położenie środka okręgu
    dPoint dp;
    dp.x = 0.5 * ((x2 * x2 * y3 + y2 * y2 * y3 - x1 * x1 * y3 + x1 * x1 * y2 - y1 * y1 * y3 + y1 * y1 * y2 + y1 * x3 * x3 + y1 * y3 * y3 - y1 * x2 * x2 - y1 * y2 * y2 - y2 * x3 * x3 - y2 * y3 * y3) / (y1 * x3 - y1 * x2 - y2 * x3 - y3 * x1 + y3 * x2 + y2 * x1));
    dp.y = 0.5 * ((-x1 * x3 * x3 - x1 * y3 * y3 + x1 * x2 * x2 + x1 * y2 * y2 + x2 * x3 * x3 + x2 * y3 * y3 - x2 * x2 * x3 - y2 * y2 * x3 + x1 * x1 * x3 - x1 * x1 * x2 + y1 * y1 * x3 - y1 * y1 * x2) / (y1 * x3 - y1 * x2 - y2 * x3 - y3 * x1 + y3 * x2 + y2 * x1));
    return dp;
}

long Ray(dPoint pt,dPoint cp){ // funkcja licząca promień okręgu
    return (long)(pt - cp).Length();
}

LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                  /* handle the messages */
    {
        case WM_CREATE:
        {
            cp = CircleCenter(p1.x,p1.y,p2.x,p2.y,p3.x,p3.y); // Obliczenie początkowego położenia środka okręgu
            ray = Ray(p1,cp); // obliczenie promienia okręgu
        }
        break;
        case WM_LBUTTONDOWN:
        {
	 	    // Operacje związane z uzyskaniem położenia pierwszego punktu i obliczenia środka okręgu oraz jego nowego promienia
            POINT pt;
            GetCursorPos(&pt);
            ScreenToClient(hwnd,&pt);

            p1.x = pt.x;
            p1.y = pt.y;

            cp = CircleCenter(p1.x,p1.y,p2.x,p2.y,p3.x,p3.y);
            ray = Ray(p1,cp);

            InvalidateRect(hwnd,NULL,true);
        }
        break;
        case WM_RBUTTONDOWN:
        {
	 	    // Operacje związane z uzyskaniem położenia trzeciego punktu i obliczenia środka okręgu oraz jego nowego promienia
            POINT pt;
            GetCursorPos(&pt);
            ScreenToClient(hwnd,&pt);

            p3.x = pt.x;
            p3.y = pt.y;

            cp = CircleCenter(p1.x,p1.y,p2.x,p2.y,p3.x,p3.y);
            ray = Ray(p1,cp);

            InvalidateRect(hwnd,NULL,true);
        }
        break;
        case WM_MBUTTONDOWN:
        {
		 	// Operacje związane z uzyskaniem położenia drugiego punktu i obliczenia środka okręgu oraz jego nowego promienia
            POINT pt;
            GetCursorPos(&pt);
            ScreenToClient(hwnd,&pt);

            p2.x = pt.x;
            p2.y = pt.y;

            cp = CircleCenter(p1.x,p1.y,p2.x,p2.y,p3.x,p3.y);
            ray = Ray(p1,cp);

            InvalidateRect(hwnd,NULL,true);
        }
        break;
        case WM_PAINT:
        {
		// Rysowanie okręgu i punktów
 
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd,&ps);

            HBRUSH hb =  (HBRUSH)GetStockObject(NULL_BRUSH);
            HPEN hp = CreatePen(PS_SOLID,1,RGB(255,255,255));
            SelectObject(hdc,hp);
            SelectObject(hdc,hb);
            Ellipse(hdc,(long)(cp.x - ray),(long)(cp.y - ray),(long)(cp.x + ray),(long)(cp.y + ray));

            Ellipse(hdc,(long)(p1.x - 5),(long)(p1.y - 5),(long)(p1.x + 5),(long)(p1.y + 5));
            Ellipse(hdc,(long)(p2.x - 5),(long)(p2.y - 5),(long)(p2.x + 5),(long)(p2.y + 5));
            Ellipse(hdc,(long)(p3.x - 5),(long)(p3.y - 5),(long)(p3.x + 5),(long)(p3.y + 5));

            DeleteObject(hb);
            DeleteObject(hp);

            EndPaint(hwnd,&ps);
        }
        break;
        case WM_DESTROY:
            PostQuitMessage (0);       /* send a WM_QUIT to the message queue */
            break;
        default:                      /* for messages that we don't deal with */
            return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return 0;
}
Komentarze
photo
+1 # Michał12234 2011-12-15 16:39
nie chce sie skompilowac w microsoft visual studio 2010 ani w Dev-C++ 5.0.0.9
czym to otworzyć?
Odpowiedz | Odpowiedz z cytatem | Cytować
Dodaj komentarz