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?

Wyznaczenie punktów przecięcia okręgu z prostą - Implementacja w C/C++
Ocena użytkownikóww: *****  / 10
SłabyŚwietny
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;
}
Dodaj komentarz