Nadesłany przez Krzysztof Zajączkowski, 17 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.
PuntyPrzecieciaZOkregiem/PunktyPrzeciecia.cpp:
#include <windows.h> #include <math.h> // Punkty przecięcia prostej z okręgiem // www.algorytm.org // Autor: Krzysztof Zajączkowski class dPoint2D{ // Klasa pomocnicza opisująca punkt (wektor) 2D double x; double y; public: dPoint2D(double x,double y); dPoint2D operator -(dPoint2D p); dPoint2D operator +(dPoint2D p); dPoint2D operator *(double k); double operator *(dPoint2D p); double SickDistance2D(dPoint2D p); dPoint2D GetPointOnLine(dPoint2D &fP,dPoint2D &lP); double X(); double Y(); void X(double x); void Y(double y); double Length(); }; dPoint2D::dPoint2D(double x,double y){ this->x = x; this->y = y; } double dPoint2D::X(){ return x; } double dPoint2D::Y(){ return y; } void dPoint2D::Y(double y){ this->y = y; } void dPoint2D::X(double x){ this->x = x; } dPoint2D dPoint2D::operator *(double k){ dPoint2D temp(x * k,y * k); return temp; } double dPoint2D::operator *(dPoint2D p){ return p.X() * x + p.Y() * y; } double dPoint2D::SickDistance2D(dPoint2D p){ return pow(x - p.X(),2.0) + pow(y - p.Y(),2.0); } dPoint2D dPoint2D::operator -(dPoint2D p){ dPoint2D temp(this->x - p.X(),this->y - p.Y()); return temp; } dPoint2D dPoint2D::operator +(dPoint2D p){ dPoint2D temp(this->x + p.X(),this->y + p.Y()); return temp; } double dPoint2D::Length(){ return sqrt(x*x+y*y); } dPoint2D dPoint2D::GetPointOnLine(dPoint2D &fP,dPoint2D &lP){ // Obliczenia związane z rzutowaniem punktu na prostą //double u = ((x - fP.X()) * (lP.X() - fP.X()) + (y - fP.Y()) * (lP.Y() - fP.Y())) / (lP.SickDistance2D(fP)); double u = (((*this) - fP) * (lP - fP))/ ((fP - lP) * (fP - lP)); return fP + (lP - fP) * u; } LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam){ static dPoint2D V1(20,300); static dPoint2D V2(300,20); static dPoint2D VC(150,50); // punkt rzutowany static dPoint2D V3(0,0); // punkt zrzutowany static dPoint2D V4(0,0); // Pierwszy punkt przecięcia static dPoint2D V5(0,0); // Drugi punkt przecięcia static double ray = 100; static POINT MousePos; switch(msg) { case WM_CREATE: { V3 = VC.GetPointOnLine(V1,V2); double L1 = (VC - V3).Length(); double L2 = sqrt(ray * ray - L1 * L1); dPoint2D VP = (V2 - V1) * (L2 / (V2 - V1).Length()); V4 = VP + V3; V5 = V3 - VP; } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd,&ps); HPEN hPen = CreatePen(PS_SOLID,2,RGB(0,0,255)); HBRUSH hBr = (HBRUSH)GetStockObject(NULL_BRUSH); SelectObject(hdc,hPen); SelectObject(hdc,hBr); Ellipse(hdc,(int)(VC.X()-ray),(int)(VC.Y()-ray),(int)(VC.X()+ray),(int)(VC.Y()+ray)); Ellipse(hdc,(int)(VC.X()-5),(int)(VC.Y()-5),(int)(VC.X()+5),(int)(VC.Y()+5)); MoveToEx(hdc,(int)V1.X(),(int)V1.Y(),NULL); LineTo(hdc,(int)V2.X(),(int)V2.Y()); Ellipse(hdc,(int)(V1.X()-5),(int)(V1.Y()-5),(int)(V1.X()+5),(int)(V1.Y()+5)); Ellipse(hdc,(int)(V2.X()-5),(int)(V2.Y()-5),(int)(V2.X()+5),(int)(V2.Y()+5)); Ellipse(hdc,(int)(V4.X()-5),(int)(V4.Y()-5),(int)(V4.X()+5),(int)(V4.Y()+5)); Ellipse(hdc,(int)(V5.X()-5),(int)(V5.Y()-5),(int)(V5.X()+5),(int)(V5.Y()+5)); DeleteObject(hPen); DeleteObject(hBr); EndPaint(hWnd,&ps); } break; case WM_LBUTTONDOWN: { V1.X(MousePos.x); V1.Y(MousePos.y); V3 = VC.GetPointOnLine(V1,V2); double L1 = (VC - V3).Length(); double L2 = sqrt(ray * ray - L1 * L1); dPoint2D VP = (V2 - V1) * (L2 / (V2 - V1).Length()); V4 = VP + V3; V5 = V3 - VP; InvalidateRect(hWnd,NULL,true); } break; case WM_RBUTTONDOWN: { V2.X(MousePos.x); V2.Y(MousePos.y); V3 = VC.GetPointOnLine(V1,V2); double L1 = (VC - V3).Length(); double L2 = sqrt(ray * ray - L1 * L1); dPoint2D VP = (V2 - V1) * (L2 / (V2 - V1).Length()); V4 = VP + V3; V5 = V3 - VP; InvalidateRect(hWnd,NULL,true); } break; case WM_MOUSEMOVE: { POINT pt; MousePos.x = LOWORD(lParam); MousePos.y = HIWORD(lParam); VC.X(MousePos.x); VC.Y(MousePos.y); V3 = VC.GetPointOnLine(V1,V2); double L1 = (VC - V3).Length(); double L2 = sqrt(ray * ray - L1 * L1); dPoint2D VP = (V2 - V1) * (L2 / (V2 - V1).Length()); V4 = VP + V3; V5 = V3 - VP; InvalidateRect(hWnd,NULL,true); } break; case WM_DESTROY: { PostQuitMessage(0); } break; } return DefWindowProc(hWnd,msg,wParam,lParam); } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE ,LPSTR ,int ){ WNDCLASS wnd; wnd.cbClsExtra = NULL; wnd.cbWndExtra = NULL; wnd.hbrBackground = CreateSolidBrush(RGB(0,0,0)); wnd.hCursor = LoadCursor(NULL,IDC_ARROW); wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION); wnd.hInstance = hInstance; wnd.lpfnWndProc = WndProc; wnd.lpszClassName = "WndPunktyPrzecięciaOkręguZProstą"; wnd.lpszMenuName = NULL; wnd.style = CS_VREDRAW|CS_HREDRAW; if(!RegisterClass(&wnd)){ MessageBox(NULL,"Coś nie tak","Informacja",MB_OK); return 0; } HWND hwnd = CreateWindow("WndPunktyPrzecięciaOkręguZProstą","Punkty przecięcia prostej z okręgiem, autor: Krzysztof Zajączkowski, kontakt: malyszkz@wp.pl",WS_OVERLAPPEDWINDOW,0,0,800,600,NULL,NULL,hInstance,NULL); ShowWindow(hwnd, SW_SHOWNORMAL); UpdateWindow(hwnd); MSG msg; while(GetMessage(&msg,NULL,0,0)){ DispatchMessage(&msg); TranslateMessage(&msg); } return 0; }