Новичок
Профиль
Группа: Участник
Сообщений: 16
Регистрация: 26.4.2015
Репутация: нет Всего: нет
|
Всем привет,нужна помощь. Прога рисует треугольник... накладывает на него текстуру...поворачивает его на заданное кол-во градусов...и создает освещенный треугольник- по тем же введенным координатам... проблема в том, что координаты считываются со второго раза через консоль..с первого ничего не происходит(((что посоветуете?? Код | #if defined(UNICODE) && !defined(_UNICODE) #define _UNICODE #elif defined(_UNICODE) && !defined(UNICODE) #define UNICODE #endif
#include <tchar.h> #include <windows.h> #include <iostream> #include <cmath>
using namespace std; /* Declare Windows procedure */ LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
HDC hdc; HDC hCmpDC; HBITMAP hBitmap; static HDC memBit; static BITMAP bm;
struct Tr { POINT points[3];//3 точки треугольника с координатами points[].x и points[].y int Ir[3];//красная составляющая трех точек треугольника int Ig[3];//зеленая составляющая трех точек треугольника int Ib[3];//голубая составляющая трех точек треугольника } tr;
inline void swap(float &a, float &b) { float t; t = a; a = b; b = t; }
void triangle(HDC hdc, int x1, int y1, int x2, int y2, int x3, int y3, int color) { // Упорядочиваем точки p1(x1, y1),p2(x2, y2), p3(x3, y3) if (y2 < y1) { swap(y1, y2); swap(x1, x2); } // точки p1, p2 упорядочены if (y3 < y1) { swap(y1, y3); swap(x1, x3); } // точки p1, p3 упорядочены теперь p1 самая верхняя осталось упорядочить p2 и p3 if (y2 > y3) { swap(y2, y3); swap(x2, x3); }
// приращения по оси x для трёх сторон треугольника float dx13 = 0, dx12 = 0, dx23 = 0;
// вычисляем приращения в случае, если ординаты двух точек совпадают, приращения полагаются равными нулю if (y3 != y1) { dx13 = float (x3 - x1); dx13 /= y3 - y1; } else { dx13 = 0; }
if (y2 != y1) { dx12 = float (x2 - x1); dx12 /= (y2 - y1); } else { dx12 = 0; }
if (y3 != y2) { dx23 = float (x3 - x2); dx23 /= (y3 - y2); } else { dx23 = 0; }
// "рабочие точки" изначально они находятся в верхней точке float wx1 = float (x1); float wx2 = wx1;
// сохраняем приращение dx13 в другой переменной float _dx13 = dx13;
// упорядочиваем приращения таким образом, чтобы в процессе работы алгоритмы точка wx1 была всегда левее wx2 if (dx13 > dx12) { swap(dx13, dx12); }
// растеризуем верхний полутреугольник for (int i = y1; i < y2; i++){ // рисуем горизонтальную линию между рабочими точками for (int j = int(wx1); j <= int(wx2); j++){ SetPixel(hdc, j, i, color); } wx1 += dx13; wx2 += dx12; }
// вырожденный случай, когда верхнего полутреугольника нет надо разнести рабочие точки по оси x, т.к. изначально они совпадают if (y1 == y2){ wx1 = float (x1); wx2 = float (x2); }
// упорядочиваем приращения (используем сохраненное приращение) if (_dx13 < dx23) { swap(_dx13, dx23); }
// растеризуем нижний полутреугольник for (int i = y2; i <= y3; i++){ // рисуем горизонтальную линию между рабочими точками for (int j = int(wx1); j <= int(wx2); j++){ SetPixel(hdc, j, i, color); } wx1 += _dx13; wx2 += dx23; } } void AreaGuro(Tr tr, float a1, float b1, float a2, float b2, float a3, float b3) { double Ir1, Ir2, Ig1, Ig2, Ib1, Ib2; double x, y; double x1, x2, t1, t2, t; int R, G, B;
tr.points[0].x = a1; tr.points[0].y = b1; tr.points[1].x = a2; tr.points[1].y = b2; tr.points[2].x = a3; tr.points[2].y = b3; tr.Ir[0] = 0; tr.Ir[1] = 255; tr.Ir[2] = 255; tr.Ig[0] = 0; tr.Ig[1] = 0; tr.Ig[2] = 0; tr.Ib[0] = 0; tr.Ib[1] = 0; tr.Ib[2] = 0; //упорядочить вершины по y { POINT temp; if(tr.points[0].y > tr.points[1].y) { temp = tr.points[0]; tr.points[0] = tr.points[1]; tr.points[1] = temp; } if(tr.points[1].y > tr.points[2].y) { temp = tr.points[1]; tr.points[1] = tr.points[2]; tr.points[2] = temp; } if(tr.points[0].y > tr.points[1].y) { temp = tr.points[0]; tr.points[0] = tr.points[1]; tr.points[1] = temp; } }
for (y = tr.points[0].y; y < tr.points[1].y; y++) //закрашиваем линии от верхней к нижней { //точки пересечения линии(y) с границами грани(ac,ab) x1 = ((y - tr.points[0].y)/(tr.points[1].y - tr.points[0].y))*(tr.points[1].x - tr.points[0].x) + tr.points[0].x; x2 = ((y - tr.points[0].y)/(tr.points[2].y - tr.points[0].y))*(tr.points[2].x - tr.points[0].x) + tr.points[0].x;
//интенсивности в точках пересечения линии(y) с границами грани if (tr.points[0].x == tr.points[1].x) continue; if (tr.points[0].x == tr.points[2].x) continue; t1 = (x1 - tr.points[1].x)/(tr.points[0].x - tr.points[1].x); t2 = (x2 - tr.points[2].x)/(tr.points[0].x - tr.points[2].x);
Ir1=t1*tr.Ir[0] + (1-t1)*tr.Ir[1]; Ir2=t2*tr.Ir[0] + (1-t2)*tr.Ir[2];
Ig1=t1*tr.Ig[0] + (1-t1)*tr.Ig[1]; Ig2=t2*tr.Ig[0] + (1-t2)*tr.Ig[2];
Ib1=t1*tr.Ib[0] + (1-t1)*tr.Ib[1]; Ib2=t2*tr.Ib[0] + (1-t2)*tr.Ib[2];
if (x2 == x1) continue; if (x2 > x1) { //рисовать линию for(x = (int) x1; x<=(int) x2; x++) { //интенсивность в точке x t = (x2-x)/(x2-x1); R = int(t*Ir1 + (1-t)*Ir2); G = int(t*Ig1 + (1-t)*Ig2); B = int(t*Ib1 + (1-t)*Ib2);
SetPixel(hdc, int(x),int(y),RGB(R, G, B)); } } else { //рисовать линию for(x = (int)x1; x>=(int)x2; x--) { //интенсивность в точке x t = (x2-x)/(x2-x1);
R = int(t*Ir1 + (1-t)*Ir2); G = int(t*Ig1 + (1-t)*Ig2); B = int(t*Ib1 + (1-t)*Ib2);
SetPixel(hdc, int(x),int(y),RGB(R,G,B)); } } } for(y=tr.points[1].y; y<=tr.points[2].y; y++) { //точки пересечения линии(y) с границами грани(ac,bc) x1 = ((y-tr.points[1].y)/(tr.points[2].y-tr.points[1].y))*(tr.points[2].x-tr.points[1].x) + tr.points[1].x; x2 = ((y-tr.points[0].y)/(tr.points[2].y-tr.points[0].y))*(tr.points[2].x-tr.points[0].x) + tr.points[0].x;
//интенсивности в точках пересечения линии(y) с границами грани if (tr.points[2].x == tr.points[1].x) continue; if (tr.points[0].x == tr.points[2].x) continue; t1 = (x1-tr.points[2].x)/(tr.points[1].x-tr.points[2].x); t2 = (x2-tr.points[2].x)/(tr.points[0].x-tr.points[2].x);
Ir1=t1*tr.Ir[0] + (1-t1)*tr.Ir[1]; Ir2=t2*tr.Ir[0] + (1-t2)*tr.Ir[2];
Ig1=t1*tr.Ig[1] + (1-t1)*tr.Ig[0]; Ig2=t2*tr.Ig[2] + (1-t2)*tr.Ig[0];
Ib1=t1*tr.Ib[0] + (1-t1)*tr.Ib[1]; Ib2=t2*tr.Ib[0] + (1-t2)*tr.Ib[2];
if (x2 == x1) continue; if (x2 > x1) { //рисовать линию for(x = (int) x1; x<=(int) x2; x++) { //интенсивность в точке x t = (x2-x) / (x2-x1);
R = int(t*Ir1 + (1-t)*Ir2); G = int(t*Ig1 + (1-t)*Ig2); B = int(t*Ib1 + (1-t)*Ib2);
SetPixel(hdc, int(x),int(y),RGB(R,G,B)); } } else { //рисовать линию for(x = (int) x1; x >= (int) x2; x--) { //интенсивность в точке x t = (x2-x)/(x2-x1);
R = int(t*Ir1 + (1-t)*Ir2); G = int(t*Ig1 + (1-t)*Ig2); B = int(t*Ib1 + (1-t)*Ib2);
SetPixel(hdc, int(x),int(y),RGB(R,G,B)); } } } } void rotateTexture90 (HDC hdc, float x1, float y1, float x2, float y2, float x3, float y3, float Xmax, float Xmin, float Kx, float Ky) { float xo; float yo; int gr; int t;
cout<<"Введите точку вращения 1? 2? 3?: "; cin>>t;
if(t=1) { xo=x1;yo=y1; } if(t=2) { xo=x2;yo=y2; } if(t=3) { xo=x3;yo=y3; }
cout<<"На сколько градусов повернуть треугольник?: "; cin>>gr; int color = RGB(0,255,0); int color2 = RGB(200,200,200);
if (gr > 360) gr = gr - 360; { triangle(hdc, x1, y1, x2, y2, x3, y3, color2); float sina = sin(gr * (M_PI / 180)); float cosa = cos(gr * (M_PI / 180)); //Sleep(0); float newx1=((x1 - xo) * cosa - (y1 - yo) * sina) + xo; float newy1=((x1 - xo) * sina + (y1 - yo) * cosa) + yo; float newx2=((x2 - xo) * cosa - (y2 - yo) * sina) + xo; float newy2=((x2 - xo) * sina + (y2 - yo) * cosa) + yo; float newx3=((x3 - xo) * cosa - (y3 - yo) * sina) + xo; float newy3=((x3 - xo) * sina + (y3 - yo) * cosa) + yo;
// Упорядочиваем точки p1(x1, y1),p2(x2, y2), p3(x3, y3) if ( newy2 < newy1) { swap( newy1, newy2); swap( newx1, newx2); } // точки p1, p2 упорядочены if ( newy3 < newy1) { swap( newy1, newy3); swap( newx1, newx3); } // точки p1, p3 упорядочены теперь p1 самая верхняя осталось упорядочить p2 и p3 if ( newy2 > newy3) { swap( newy2, newy3); swap( newx2, newx3); } // приращения по оси x для трёх сторон треугольника float dx13 = 0, dx12 = 0, dx23 = 0;
// вычисляем приращения в случае, если ординаты двух точек совпадают, приращения полагаются равными нулю if ( newy3 != newy1) { dx13 = float ( newx3 - newx1); dx13 /= newy3 - newy1; } else { dx13 = 0; }
if ( newy2 != newy1) { dx12 = float ( newx2 - newx1); dx12 /= ( newy2 - newy1); } else { dx12 = 0; }
if (y3 != y2) { dx23 = float ( newx3 - newx2); dx23 /= ( newy3 - newy2); } else { dx23 = 0; }
// "рабочие точки" изначально они находятся в верхней точке float wx1 = float ( newx1); float wx2 = wx1;
// сохраняем приращение dx13 в другой переменной float _dx13 = dx13;
// упорядочиваем приращения таким образом, чтобы в процессе работы алгоритмы точка wx1 была всегда левее wx2 if (dx13 > dx12) { swap(dx13, dx12); }
// растеризуем верхний полутреугольник for (int i =(int) newy1; i < (int) newy2; i++) { // рисуем горизонтальную линию между рабочими точками for (int j = int(wx1); j < int(wx2); j++) { float newx11 =((j - xo) * cosa + (i - yo) * sina) + xo; float newy11 =(-(j - xo) * sina + (i - yo) * cosa) + yo; SetPixel(hdc, j, i, GetPixel(memBit, (int) (((newx11-Xmin) * Kx)), (int) ((newy11-y1) * Ky))); } wx1 += dx13; wx2 += dx12; } // вырожденный случай, когда верхнего полутреугольника нет надо разнести рабочие точки по оси x, т.к. изначально они совпадают if ( newy1 == newy2 && newx1 < newx2) { wx1 = float ( newx1); wx2 = float ( newx2); }
if ( newy1 == newy2 && newx1 > newx2) { wx1 = float ( newx2); wx2 = float ( newx1); } // упорядочиваем приращения (используем сохраненное приращение) if (_dx13 < dx23) { swap(_dx13, dx23); }
// растеризуем нижний полутреугольник for (int i = (int) newy2; i < (int) newy3; i++) { // рисуем горизонтальную линию между рабочими точками for (int j = int(wx1); j < int(wx2); j++) { float newx11 =((j - xo) * cosa + (i - yo) * sina) + xo; float newy11 =(-(j - xo) * sina + (i - yo) * cosa) + yo; SetPixel(hdc, j, i, GetPixel(memBit, (int) (((newx11-Xmin) * Kx)), (int) ((newy11-y1) * Ky))); } wx1 += _dx13; wx2 += dx23; } }
} void texture(HDC hdc, float x1, float y1, float x2, float y2, float x3, float y3, float Xmax, float Xmin) { // Упорядочиваем точки p1(x1, y1),p2(x2, y2), p3(x3, y3) if (y2 < y1) { swap(y1, y2); swap(x1, x2); } // точки p1, p2 упорядочены if (y3 < y1) { swap(y1, y3); swap(x1, x3); } // точки p1, p3 упорядочены теперь p1 самая верхняя осталось упорядочить p2 и p3 if (y2 > y3) { swap(y2, y3); swap(x2, x3); }
// приращения по оси x для трёх сторон треугольника float dx13 = 0, dx12 = 0, dx23 = 0;
// вычисляем приращения в случае, если ординаты двух точек совпадают, приращения полагаются равными нулю if (y3 != y1) { dx13 = float (x3 - x1); dx13 /= y3 - y1; } else { dx13 = 0; }
if (y2 != y1) { dx12 = float (x2 - x1); dx12 /= (y2 - y1); } else { dx12 = 0; }
if (y3 != y2) { dx23 = float (x3 - x2); dx23 /= (y3 - y2); } else { dx23 = 0; }
// "рабочие точки" изначально они находятся в верхней точке float wx1 = float (x1); float wx2 = wx1;
// сохраняем приращение dx13 в другой переменной float _dx13 = dx13; // упорядочиваем приращения таким образом, чтобы в процессе работы алгоритмы точка wx1 была всегда левее wx2 if (dx13 > dx12) { swap(dx13, dx12); }
if (x1 > x2) { Xmax = x1; Xmin = x2; if (x1 < x3) Xmax = x3; if (x2 > x3) Xmin = x3; } else { Xmax = x2; Xmin = x1; if (x2 < x3) Xmax = x3; if (x1 > x3) Xmin = x3; } float Kx = bm.bmWidth/(Xmax - Xmin); float Ky = bm.bmHeight/(y3 - y1);
// растеризуем верхний полутреугольник for (int i = y1; i < y2; i++){ // рисуем горизонтальную линию между рабочими точками for (int j = int(wx1); j <= int(wx2); j++){ SetPixel(hdc, j, i, GetPixel(memBit, (int) (((j-Xmin) * Kx)), (int) ((i-y1) * Ky))); } wx1 += dx13; wx2 += dx12; }
// вырожденный случай, когда верхнего полутреугольника нет надо разнести рабочие точки по оси x, т.к. изначально они совпадают if (y1 == y2){ wx1 = float (x1); wx2 = float (x2); }
// упорядочиваем приращения (используем сохраненное приращение) if (_dx13 < dx23) { swap(_dx13, dx23); }
// растеризуем нижний полутреугольник for (int i = y2; i <= y3; i++){ // рисуем горизонтальную линию между рабочими точками for (int j = int(wx1); j <= int(wx2); j++){ SetPixel(hdc, j, i, GetPixel(memBit, (int) (((j-Xmin) * Kx)), (int) ((i-y1) * Ky))); } wx1 += _dx13; wx2 += dx23; } rotateTexture90 (hdc, x1, y1, x2, y2, x3, y3, Xmax, Xmin, Kx, Ky); }
//Ввод через консоль void TrangleAll() { SetConsoleOutputCP(1251); SetConsoleCP(1251);
float x1=0; float y1=0; float x2=0; float y2=0; float x3=0; float y3=0; float Xmax=0; float Xmin=0; float Kx=0; float Ky=0;
cout<<"Введите координаты первой точки: x = "; cin>>x1; cout<<"y = "; cin>>y1;
cout<<"Введите координаты второй точки: x = "; cin>>x2; cout<<"y = "; cin>>y2;
cout<<"Введите координаты третьей точки: x = "; cin>>x3; cout<<"y = "; cin>>y3;
texture(hdc, x1, y1, x2, y2, x3, y3, Xmax, Xmin); Sleep(1500); AreaGuro(tr, x1, y1, x2, y2, x3, y3);
}
TCHAR szClassName[ ] = _T("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 = (HBRUSH) COLOR_BACKGROUND;
/* 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 */ _T("Code::Blocks Template Windows App"), /* Title Text */ WS_OVERLAPPEDWINDOW, /* default window */ CW_USEDEFAULT, /* Windows decides the position */ CW_USEDEFAULT, /* where the window ends up on the screen */ 800, /* The programs width */ 500, /* 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); UpdateWindow(hwnd); PAINTSTRUCT ps; HBITMAP hBmp, hbmp; hBitmap = (HBITMAP)LoadImage(NULL, _T("2.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); GetObject(hBitmap, sizeof(bm), &bm);
memBit = CreateCompatibleDC(hdc); SelectObject(memBit, hBitmap); ReleaseDC(hwnd, hdc); /* Run the message loop. It will run until GetMessage() returns 0 */ while (GetMessage (&messages, NULL, 0, 0)) { PAINTSTRUCT ps; //HDC hCmpDC; HBITMAP hBmp, hbmp; /* Translate virtual-key messages into character messages */ TranslateMessage(&messages); /* Send message to WindowProcedure */ DispatchMessage(&messages); hdc = BeginPaint(hwnd, &ps); HDC hdc = GetDC(hwnd); loop: //***************Вывод************** TrangleAll();
DeleteDC(hCmpDC); DeleteObject(hBmp); DeleteObject(hbmp); hCmpDC = NULL;
EndPaint(hwnd, &ps);
} /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) /* handle the messages */ { 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; }
|
|