/********************************************************** * Geometrical Transformations in 2D plane * * ------------------------------------------------------- * * Reference: * * After Robert DONY - MASSON 1990 "Graphisme dans le * * plan et dans l'espace en Turbo Pascal 4.0". * * * * Visual C++ in API style Release By J-P Moreau, Paris. * * ------------------------------------------------------- * * Available transformations are: * * Kind=1: Rotation (choose angle in degrees) * * Kind=2: Homothecy (choose ratio) * * Kind=3: Symmetry (choose with respect to OX, OY or O) * * Kind=4: Shearing (choose parameters B, C). * **********************************************************/ #include #include #include #include HDC hdc; RECT rect; HPEN redpen, hpen; //Functions of module Gr2D.cpp void Fenetre(double,double,double,double); void Cloture(int,int,int,int); void Bordure(); void Axes(); void Gradue(double,double); void Grille(double,double); void MoveXY(double,double); void LineXY(double,double); //"home made" graphic commands for hdc environment used by above functions void DrawPixel(int ix,int iy) { //sorry, no other available command found Rectangle(hdc,rect.left+ix,rect.top+iy, rect.left+ix+2,rect.top+iy+1); } void Swap(int *i1,int *i2) { int it; it=*i1; *i1=*i2; *i2=it; } void DrawLine(int ix1,int iy1,int ix2,int iy2) { int i,il,ix,iy; float dx,dy; if (ix2 *f2) *f2=x; if (y < *f3) *f3=y; if (y > *f4) *f4=y; } void SeekWindow() { double aux1,aux2,f1,f2,f3,f4; short i; f1=1e20; f2=-f1; f3=f1; f4=f2; for (i=1; i<=lim; i++) Limits(X[i],Y[i],&f1,&f2,&f3,&f4); aux1=-m*a+n*c+m; aux2=-m*b-n*d+n; for (i=1; i<=lim; i++) { Xtr[i]=a*X[i]-c*Y[i]+aux1; Ytr[i]=b*X[i]+d*Y[i]+aux2; Limits(Xtr[i],Ytr[i],&f1,&f2,&f3,&f4); } max=fabs(f1); if (max < fabs(f2)) max=fabs(f2); if (max < fabs(f3)) max=fabs(f3); if (max < fabs(f4)) max=fabs(f4); max=int(max); } void Init() { char ch; // transformation data // origin coordinates, m & n m = 1; n = 1; // Kind of transformation: // choice=1: Rotation // choice=2: Homothecy // choice=3; Symmetry // choice=4: Shearing choice=4; switch(choice) { case 1: { //rotation rotdeg=130.0; rotrad=coef*rotdeg; a=cos(rotrad); b=sin(rotrad); c=b; d=a; break; } case 2: { //homothecy rh=-2.5; a=rh; b=0; c=0; d=rh; break; } case 3: { //symmetry b=0; c=0; if (m==0 && n==0) { ch='X'; switch(ch) { case 'X': {a=1; d=-1; break;} case 'Y': {a=-1; d=1; break;} case 'O': {a=-1; d=-1;} } } else { a=-1; d=-1; } break; } case 4: { //shearing a=1; d=1; b=2.0; c=3.0; } } SeekWindow(); Fenetre(-20,20,-20,20); } void Polygon(double *X, double *Y, int n, int mode) { // draw a polygon defined byr X(i), Y(i) int i; // in physical coordinates, closed or open MoveXY(X[1],Y[1]); for (i=2; i<=n; i++) LineXY(X[i],Y[i]); if (mode) LineXY(X[1],Y[1]); } void FigureInit() { // draw figure to transform double xmax; redpen = CreatePen(PS_SOLID, 3, RGB(255, 0, 0)); extern MaxX, MaxY; Cloture(80,MaxX-40,60,MaxY-10); xmax=int(max/5.0); Grille(2,2); Bordure(); Axes(); Gradue(4, 4); SelectObject(hdc,redpen); Polygon(X,Y,10,1); SelectObject(hdc,hpen); } void FigureTrans() { // draw figure after transformation SelectObject(hdc,redpen); Polygon(Xtr,Ytr,lim,1); SelectObject(hdc,hpen); if (m!=0 && n!=0) { MoveXY(m+0.5,n); LineXY(m-0.5,n); MoveXY(m,n-0.5); LineXY(m,n+0.5); } switch(choice) { case 1: {OutText(100,50,"Rotation"); break;} case 2: {OutText(100,50,"Homothecy"); break;} case 3: {OutText(100,50,"Symmetry"); break;} case 4: OutText(100,50,"Shearing"); } } // main function void Exec_Trans2D() { extern MaxX, MaxY; MaxX=(rect.right-rect.left); MaxY=(rect.bottom-rect.top); InitObject(); Init(); FigureInit(); FigureTrans(); } //end specific section //Handle window Paint and Destroy messages long FAR PASCAL /*_export*/ WndProc(HWND hwnd, UINT message, UINT wParam, LONG lParam) { HPEN hpenOld; PAINTSTRUCT ps; switch (message) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); GetClientRect(hwnd, &rect); hpen = CreatePen(PS_SOLID, 1, RGB(0, 0, 255)); hpenOld = SelectObject(hdc,hpen); Exec_Trans2D(); SelectObject(hdc,hpenOld); DeleteObject(hpen); DeleteObject(redpen); EndPaint(hwnd, &ps); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } // main program int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow) { static char szAppName[] = "Trans2D"; HWND hwnd; MSG msg; WNDCLASS wndclass; if (!hPrevInstance) { 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 = GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; RegisterClass(&wndclass); } hwnd = CreateWindow(szAppName, // window class name " 2D TRANSFORMS", // window caption WS_OVERLAPPEDWINDOW, // window style CW_USEDEFAULT, // initial x position CW_USEDEFAULT, // initial y position CW_USEDEFAULT, // initial x size CW_USEDEFAULT, // initial y size NULL, // parent window handle NULL, // window menu handle hInstance, // program instance handle NULL); // creation parameters ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } //end of file trans2d.cpp