Sunteți pe pagina 1din 39

Cuprins:

1. Introducere
2. Arc de cerc . Algoritmul DDA
3. Aplicatie

1
Algoritmul de linie de Bresenham este un algoritm care determină
care puncte dimensionale ar trebui să fie reprezentate grafic cu scopul de a
forma o apropiere de o linie dreaptă între două puncte date. Acesta este de
obicei folosite pentru a trage linii pe ecranul unui computer, în care se
foloseşte numai numere întregi, scăderea şi trecerea de biţi, care sunt toate
operaţiuni foarte ieftine în arhitecturi standard. Aceasta este unul dintre cele
mai timpurii algoritmi de dezvoltare în domeniul de grafica pe calculator. O
extensie minora la algoritmul de origine, de asemenea, se ocupa cu
desenarea de cercuri. . În timp ce algoritmi, cum ar fi algoritmul lui Wu,
sunt, de asemenea, utilizate frecvent in grafica pe calculator deoarece
acestea pot sprijini viteza şi simplitatea algoritmului linie Bresenham
înseamnă că acesta este încă important. Algoritmul este folosit în hardware,
cum ar fi plotere în cipuri grafice moderne de plăci grafice.. Acesta poate fi,
de asemenea, gasit in bibliotecile multor software-ul. Deoarece acest
algoritm este foarte simplu, nu este adesea pus în aplicare în nici un
firmware-ul sau hardware-ul modern de plăci grafice.

Eticheta "Bresenham" este utilizata astăzi pentru o familie întreagă de


algoritmi de prelungire sau modificarea algoritmului Bresenham original al
lui. A se vedea referinţele în continuare mai jos.

Algoritmul va fi iniţial prezentat numai pentru octant în care segmentul se


duce în jos şi la dreapta (x 0 ≤ x 1 şi y 0 ≤ y 1), precum şi proiecţia sa orizontală
x 1 - x 0 este mai lung decât Y proiecţie verticală 1 - Y 0 (linie are o pantă mai
mică de 1 şi mai mare decât 0.) În această octant, pentru fiecare coloană x
între x 0 şi x 1, există exact un rând Y (calculat prin algoritmul) care conţine
un pixel de linie, în timp ce fiecare rând între y 0 şi y 1 poate conţine mai
multe pixeli raster.

Algoritmul lui Bresenham alege Y intreg care corespunde cel mai apropiat
centru de pixeli care este idealul (fracţionată) y pentru acelaşi X; pe coloane
succesive Y poate rămâne acelaşi sau să crească până la 1. Ecuaţia generală
a liniei prin obiective este dat de:

2
Din moment ce ştim coloană, x, rândul pixelilor lui, y, este dat de rotunjirea
acestuia functie de cel mai apropiat număr întreg:

Panta (y 1 - y 0) / (x 1 - x 0) depinde de obiectivul coordonatelor, dar poate fi


calculat, iar Y ideal pentru valori succesive ale lui x număr întreg, poate fi
calculat pornind de la Y 0 şi în mod repetat, adăugând pantă .

În practică, algoritmul poate urmări, în loc de o valoare mare a lui Y, o


valoare mică a erorii între -0,5 şi 0,5: distanţa verticală între valorile
rotunjite si exacte ale lui Y, pentru X curent. De fiecare dată când x este
crescut, eroarea este sporită datorita pantei lor; în cazul în care depăşeşte 0.5,
y este crescut cu 1 iar eroarea este decrementata de 1.0

următoarelea secventa de cod returneaza valoare absolută:

linie de funcţie (x0, x1, y0, y1)


int deltax := x1 - x0 deltax int: = x1 - x0
int deltay := y1 - y0 deltay int: = y1 - y0
real error := 0 Eroare reală: = 0
real deltaerr := deltay / deltax // Assume deltax != 0 (line is
not vertical), deltaerr reală: = deltay / deltax / / presupunem deltax!
= 0 (linie nu este verticală),
// note that this division needs to be done in a way that
preserves the fractional part / / Act de faptul că această diviziune
trebuie să se facă într-un mod care păstrează o parte fracţionată
int y := y0 int y: = y0
for x from x0 to x1 pentru x de la x0 la x1
plot(x,y) plot (x, y)
error := error + deltaerr error: = eroare de + deltaerr
if abs(error) ≥ 0.5 then în cazul în care abs (eroare) ≥ 0,5,
atunci
y := y + 1 Y: = y + 1
error := error - 1.0 error: = eroare - 1.0

3
Versiunea de mai sus afiseaza linii care coboara spre dreapta. Ne-am
dori, desigur, să fie în măsură să tragă toate liniile.. Primul caz este ceea ce
ne permite să elaboreze linii care încă mai au panta in jos dar din capatul
opus . Aceasta este o simplă cale de reprezentare de puncte iniţial în cazul în
care x0>x1. Mai complicat este de a determina cum să elaboreze linii care
merg in sus. . Pentru a face acest lucru, vom verifica dacă y ≥ 0 Y 1; dacă este
aşa, modificam pasul y cu -1 în loc de 1. În sfârşit, avem în continuare
nevoie pentru a generaliza un algoritm de la desena linii în toate direcţiile.
Până acum am fost doar în măsură să elaboreze linii cu o panta. Pentru a fi
capabili să elaboreze linii, cu o pantă mai mare, vom profita de faptul că o
linie abruptă se poate reflecta în întreaga linie Y = x pentru a obţine o linie
cu o pantă mică. Efectul este pentru a comuta x şi variabilele Y ,Codul arata
astfel:

function line(x0, x1, y0, y1) linie de funcţie (x0, x1, y0, y1)
boolean steep := abs(y1 - y0) > abs(x1 - x0) boolean abrupt: = abs
(y1 - y0)> abs (x1 - x0)
if steep then în cazul în care abrupte, atunci
swap(x0, y0) swap (x0, y0)
swap(x1, y1) swap (x1, y1)
if x0 > x1 then în cazul în care x0> x1, apoi
swap(x0, x1) swap (x0, x1)
swap(y0, y1) swap (y0, y1)
int deltax := x1 - x0 deltax int: = x1 - x0
int deltay := abs(y1 - y0) deltay int: = abs (y1 - y0)
real error := 0 Eroare reală: = 0
real deltaerr := deltay / deltax deltaerr reală: = deltay / deltax
int ystep ystep int
int y := y0 int y: = y0
if y0 < y1 then ystep := 1 else ystep := -1 în cazul în care Y0
<Y1, atunci ystep: = 1 else ystep: = -1
for x from x0 to x1 pentru x de la x0 la x1
if steep then plot(y,x) else plot(x,y) în cazul în care
abrupte apoi teren (y, x) else parcelă (x, y)
error := error + deltaerr error: = eroare de + deltaerr
if error ≥ 0.5 then în cazul în eroare ≥ 0,5, atunci
y := y + ystep Y: = y + ystep
error := error - 1.0 error: = eroare - 1.0

4
Problema cu această abordare este că aceste calculatoare funcţionează
relativ lent pe numerele fractionare cum ar fi error şi deltaerr în plus,
erori pot acumula peste multe completări în virgulă mobilă. Lucrul cu
numere întregi, va fi mai rapidă şi mai precisă. Trucul pe care le folosim este
de a multiplica toate numerele de fracţionare de mai sus prin deltax care
ne permite să le exprimam ca numere întregi. Singura problemă rămasă este
constanta 0,5 de a face cu acest lucru, vom schimba initializarea de error
variabile, si inversand-o pentru o optimizare suplimentară de mici
dimensiuni. Nou program arata astfel:

function line(x0, x1, y0, y1) linie de funcţie (x0, x1, y0, y1)
boolean steep := abs(y1 - y0) > abs(x1 - x0) boolean abrupt: = abs
(y1 - y0)> abs (x1 - x0)
if steep then în cazul în care abrupte, atunci
swap(x0, y0) swap (x0, y0)
swap(x1, y1) swap (x1, y1)
if x0 > x1 then în cazul în care x0> x1, apoi
swap(x0, x1) swap (x0, x1)
swap(y0, y1) swap (y0, y1)
int deltax := x1 - x0 deltax int: = x1 - x0
int deltay := abs(y1 - y0) deltay int: = abs (y1 - y0)
int error := deltax / 2 eroare int: = deltax / 2
int ystep ystep int
int y := y0 int y: = y0
if y0 < y1 then ystep := 1 else ystep := -1 în cazul în care Y0
<Y1, atunci ystep: = 1 else ystep: = -1
for x from x0 to x1 pentru x de la x0 la x1
if steep then plot(y,x) else plot(x,y) în cazul în care
abrupte apoi teren (y, x) else parcelă (x, y)
error := error - deltay error: = eroare - deltay
if error < 0 then în cazul în care eroarea <0, atunci
y := y + ystep Y: = y + ystep
error := error + deltax error: = eroare de + deltax

5
Algoritmul a fost dezvoltat de Jack E. Bresenham în 1962, la IBM. În anul
2001 Bresenham a scris:

"Am fost de lucru în laboratorul de calcul de la IBM, San Jose


laborator de dezvoltare. Un plotter CalComp a fost ataşat la un IBM
1401, prin intermediul maşinii de scris, 1407 consolă. Algoritmul a
fost în utilizarea în producţie până în vara anului 1962, eventual, o
lună sau cam asa ceva mai devreme. Programele în acele zile au fost
în mod liber schimbate între corporaţii atât de CalComp (Jim
Newland şi Calvin Hefte). Când m-am întors la Stanford, în toamna
1962, am pus o copie în biblioteca comp Stanford Center.
O descriere a liniei de tragere de rutină a fost acceptat pentru
prezentare la 1963 ACM Convenţiei Naţionale în Denver, Colorado. .
Acesta a fost un an în care procedurile nu au fost publicate, numai
ordinea de zi şi subiecte într-o problemă de Comunicaţii a ACM.. O
persoană din sistemele IBM Oficial ma întrebat după ce am făcut
prezentarea mea,daca doresc sa imi fie publicat proiectul.. " Am fost
fericit si de acord, şi au imprimat-o în 1965. "

Algoritmul Bresenham mai târziu a fost modificat pentru a produce


cercuri, algoritmul rezultat fiind uneori cunoscut fie ca algoritmul "cerc"
Bresenham sau algoritm de punctul de mijloc cerc.Algoritmul Bresenham
poate fi interpretat ca o uşore modificare ADD (folosind 0.5 ca pragul de
eroare în loc de 0,). Principiul de a folosi o eroare de incrementare, în loc de
operaţiuni de divizare care are alte aplicaţii in grafica.. Este posibil să se
utilizeze această tehnică pentru a calcula U, V, coordonatele în timpul raster
scanda de textura poligoane cartografiate. Bresenham, de asemenea, a
publicat un Run-Slice (spre deosebire de Run-Length), algoritmul de calcul.

O extindere a algoritmului care se ocupă de linii groase, a fost creat de Alan


Murphy la IBM.

6
ARC DE CERC. ALGORITMUL DDA
ARC DE CERC.

Arcul de cerc este o parte a circumferintei cercului. Atunci lungimea arcului


este o fractiune a circumferintei pe care o acopera. Lungimea este
proportional cu dimensiunea unui unghi la central opus arcului. Din
convenient vom numi acest unghi unghiul unui arc de cerc.

Arcurile de cerc sunt masurate prin doua cai:ca masurare a unhiului central
sau ca lungimea arcului insusi.
Masurarea unghiului central(in grade)

Arcul rosu masoara 120o

Arcul albastru masoara


240o

Masurare in functie de lungimea arcului(in radiani)


Formula: s = rθ
s = lungime arcului
r = radianii cercului
θ = masurarea unghiului central in radiani

7
Arcul rosu: r = 2 si θ = 2π/3, deci s = 4π/3

Arcul albastru: r = 2 si θ = 4π/3, deci s = 8π/3

Lungimea arcului de cerc

Unghiul centrului are 360o si este proportional cu circumferinta. Folosind


proportionaliatea avem:

Formula de mai sus ne permite sa calculam orice valoare daca se dau celelalte doua
valori.
Calculul lungimii unui arc
Din formula putem calcula lungimea unui arc de cerc.
Exemplu:

Daca circumferinta cercului este de 54 cm, care este lungimea unghiului ABC?

8
Solutie:

Lungimea arcului = x 54= 18 cm

Exemplu: daca radianul uni cerc este 5cm si unghiul arcului este 110o , care este lungimea
arcului?

Solutie:

Circumferinta= 2πr

lungimea arcului = x 2π x 5 = 9,6cm

9
Aplicatie

// MainFrame.cpp : implementation of the CMainFrame class

//

#include "stdafx.h"

#include "spp.h"

#include<math.h>

#include "MainFrame.h"

#define PI 3.1415926

#ifdef _DEBUG

#define new DEBUG_NEW

#undef THIS_FILE

static char THIS_FILE[] = __FILE__;

#endif

float k=0;

float r1=6.0,r2=4.0,r3=2.0;

/////////////////////////////////////////////////////////////////////////////

// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)

//{{AFX_MSG_MAP(CMainFrame)

10
ON_WM_PAINT()

ON_WM_SIZE()

ON_WM_SETFOCUS()

ON_WM_QUERYNEWPALETTE()

ON_WM_PALETTECHANGED()

ON_WM_ACTIVATEAPP()

ON_WM_KEYDOWN()

ON_WM_TIMER()

ON_WM_CREATE()

ON_WM_LBUTTONDOWN()

ON_WM_DESTROY()

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////

// CMainFrame construction/destruction

CMainFrame::CMainFrame()

VB_WIDTH = 1024;

VB_HEIGHT = 768;

VB_DEPTH = 32;

m_bFullScreen = FALSE;

11
m_hDC = NULL;

m_hRC = NULL;

m_cxClient = 0;

m_cyClient = 0;

m_hPal = NULL;

m_bAppIsActive = FALSE;

// Ask The User Which Screen Mode They Prefer

if (MessageBox("Would You Like To Run In Fullscreen Mode?", "Start


FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDYES)

m_bFullScreen=TRUE;
// Windowed Mode

// TODO: add member initialization code here

CMainFrame::~CMainFrame()

KillGLWindow(); // Shutdown

12
/////////////////////////////////////////////////////////////////////////////

// CMainFrame PreCreateWindow

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)

if (!CFrameWnd::PreCreateWindow(cs))

return FALSE;

EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS,
&m_DMsaved); // save the current display state

if (m_bFullScreen)
// Attempt Fullscreen Mode?

DEVMODE dmScreenSettings;
// Device Mode

memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
// Makes Sure Memory's Cleared

dmScreenSettings.dmSize=sizeof(dmScreenSettings);
// Size Of The Devmode Structure

dmScreenSettings.dmPelsWidth = VB_WIDTH;
// Selected Screen Width

dmScreenSettings.dmPelsHeight = VB_HEIGHT;
// Selected Screen Height

13
dmScreenSettings.dmBitsPerPel = VB_DEPTH;
// Selected Bits Per Pixel

dmScreenSettings.dmFields=DM_BITSPERPEL|
DM_PELSWIDTH|DM_PELSHEIGHT;

// Try To Set Selected Mode And Get Results. NOTE:


CDS_FULLSCREEN Gets Rid Of Start Bar.

if
(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!
=DISP_CHANGE_SUCCESSFUL)

// If The Mode Fails, Offer Two Options. Quit Or Use


Windowed Mode.

if (MessageBox("The Requested Fullscreen Mode Is Not


Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe
GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)

m_bFullScreen=FALSE;
// Windowed Mode Selected.

else

// Pop Up A Message Box Letting User Know The


Program Is Closing.

MessageBox("Program Will Now


Close.","ERROR",MB_OK|MB_ICONSTOP);

14
return FALSE;

// TODO: Modify the Window class or styles here by modifying

// the CREATESTRUCT cs

cs.cx = VB_WIDTH;

cs.cy = VB_HEIGHT;

if (m_bFullScreen)
// Are We Still In Fullscreen Mode?

cs.dwExStyle=WS_EX_APPWINDOW;
// Window Extended Style

cs.style=WS_POPUP;
// Windows Style

ShowCursor(FALSE);
// Hide Mouse Pointer

else

15
{

cs.dwExStyle=WS_EX_APPWINDOW |
WS_EX_WINDOWEDGE; // Window Extended Style

cs.style=WS_OVERLAPPEDWINDOW;
// Windows Style

cs.y = (int) GetSystemMetrics(SM_CYSCREEN) / 2 - cs.cy / 2;

cs.x = (int) GetSystemMetrics(SM_CXSCREEN) / 2 - cs.cx / 2;

cs.lpszClass = AfxRegisterWndClass(CS_OWNDC|CS_HREDRAW|
CS_VREDRAW|CS_DBLCLKS,

LoadCursor(NULL,IDC_ARROW), NULL, NULL);

return TRUE;

/////////////////////////////////////////////////////////////////////////////

// CMainFrame diagnostics

#ifdef _DEBUG

void CMainFrame::AssertValid() const

CFrameWnd::AssertValid();

16
void CMainFrame::Dump(CDumpContext& dc) const

CFrameWnd::Dump(dc);

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////

// CMainFrame message handlers

/////////////////////////////////////////////////////////////////////////////

// CMainFrame OnCreateClient

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs,


CCreateContext* pContext)

// TODO: Add your specialized code here and/or call the base class

BOOL bRet = CFrameWnd::OnCreateClient(lpcs, pContext);

if (bRet)

GLuint PixelFormat;
// Holds The Results After Searching For A
Match

static PIXELFORMATDESCRIPTOR pfd=


// pfd Tells Windows How We Want
Things To Be

17
{

sizeof(PIXELFORMATDESCRIPTOR),
// Size Of This Pixel Format
Descriptor

1,
// Version Number

PFD_DRAW_TO_WINDOW |
// Format Must Support
Window

PFD_SUPPORT_OPENGL |
// Format Must Support OpenGL

PFD_DOUBLEBUFFER,
// Must Support Double
Buffering

PFD_TYPE_RGBA,
// Request An RGBA Format

VB_DEPTH,
// Select Our Color Depth

0, 0, 0, 0, 0, 0,
// Color Bits Ignored

0,
// No Alpha Buffer

0,
// Shift Bit Ignored

0,
// No Accumulation
Buffer

0, 0, 0, 0,
// Accumulation Bits Ignored

16,
// 16Bit Z-Buffer
(Depth Buffer)

18
0,
// No Stencil Buffer

0,
// No Auxiliary Buffer

PFD_MAIN_PLANE,
// Main Drawing Layer

0,
// Reserved

0, 0, 0
// Layer Masks Ignored

};

if ( !( m_hDC = ::GetDC ( m_hWnd ) ) ) {


// Did We Get A Device Context?

KillGLWindow ();
// Reset The Display

MessageBox ( "Can't Create A GL Device Context.",


"ERROR", MB_OK | MB_ICONEXCLAMATION );

return FALSE;

if ( !( PixelFormat = ChoosePixelFormat ( m_hDC, &pfd ) ) )


{ // Did Windows Find A Matching Pixel Format?

19
KillGLWindow ();
// Reset The Display

MessageBox ( "Can't Find A Suitable PixelFormat.",


"ERROR", MB_OK | MB_ICONEXCLAMATION );

return FALSE;

if ( !SetPixelFormat ( m_hDC, PixelFormat, &pfd ) ){


// Are We Able To Set The Pixel Format?

KillGLWindow ();
// Reset The Display

MessageBox ( "Can't Set The PixelFormat.", "ERROR",


MB_OK | MB_ICONEXCLAMATION );

return FALSE;

if ( !( m_hRC = wglCreateContext ( m_hDC ) ) ) {


// Are We Able To Get A Rendering Context?

KillGLWindow ();
// Reset The Display

MessageBox( " Can't Create A GL Rendering Context.",


"ERROR", MB_OK | MB_ICONEXCLAMATION );

return FALSE;

20
}

if ( !wglMakeCurrent ( m_hDC, m_hRC ) ) {


// Try To Activate The Rendering Context

KillGLWindow ();
// Reset The Display

MessageBox ( "Can't Activate The GL Rendering


Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION );

return FALSE;

if ( !InitGL () ) {
// Initialize Our Newly Created GL
Window

KillGLWindow ();
// Reset The Display

MessageBox ( "Initialization Failed.", "ERROR", MB_OK


| MB_ICONEXCLAMATION );

return FALSE;

m_bAppIsActive = TRUE;

21
return bRet;

/////////////////////////////////////////////////////////////////////////////

// CMainFrame OnPaint

void CMainFrame::OnPaint()

CPaintDC dc(this); // device context for painting

// TODO: Add your message handler code here

// Do not call CMainFrame::OnPaint() for painting messages

::ValidateRect ( m_hWnd, NULL );

/////////////////////////////////////////////////////////////////////////////

// CMainFrame OnSize

void CMainFrame::OnSize(UINT, int cx, int cy)

22
m_cxClient = cx;

m_cyClient = cy;

ReSizeGLScene( cx, cy );

/////////////////////////////////////////////////////////////////////////////

// CMainFrame OnSetFocus

void CMainFrame::OnSetFocus(CWnd* pOldWnd)

OnQueryNewPalette();

/////////////////////////////////////////////////////////////////////////////

// CMainFrame OnCreateClient

BOOL CMainFrame::OnQueryNewPalette()

Invalidate();

return TRUE;

23
/////////////////////////////////////////////////////////////////////////////

// CMainFrame OnPaletteChanged

void CMainFrame::OnPaletteChanged(CWnd* pFocusWnd)

if ((pFocusWnd != this) && (!IsChild(pFocusWnd)))

OnQueryNewPalette();

/////////////////////////////////////////////////////////////////////////////

// CMainFrame OnActivateApp

void CMainFrame::OnActivateApp(BOOL bActive, HTASK hTask)

CFrameWnd::OnActivateApp(bActive, hTask);

m_bAppIsActive = bActive;

/////////////////////////////////////////////////////////////////////////////

// CMainFrame RenderGLScene

24
void draw_circle(float r, float z)

float angle=0.0,n=365,i=0,x=0,y=0;

glBegin(GL_LINE_STRIP);

glVertex3f(r,0,0);

for(i=0;i<=n;i++)

angle=2*i*PI/n;

x=r*cos(angle);

y=r*sin(angle);

glVertex3f(x,y,z);

glEnd();

void drawx(float r_1,float r_2,float r_3)

float R,h;

for(h=0.0;h>=-1.5;h=h-0.03)

for(R=10.0;R>=8;R=R-0.05)

glColor3f(0.6/(0.13*R),0.4/(0.13*R),0.8/(0.13*R));

draw_circle(R,h);

25
glColor3f(0.4,1.0,0.0);

draw_circle(r_1,r_1*(-0.2));

draw_circle(r_2,r_2*(-0.2));

draw_circle(r_3,r_3*(-0.2));

glBegin(GL_LINES);

glVertex3f(8,0,-0.5);

glVertex3f(-8,0,-0.5);

glVertex3f(0,8,-0.5);

glVertex3f(0,-8,-0.5);

glEnd();

void drawfan(float k1)

float angle2,x,y,j;

glBegin(GL_TRIANGLE_FAN);

glColor3f(1,0,0);

glVertex3f(0,0,-0.5);

glColor3f(0,1,0);

for(j=k1;j<=k1+10;j++)

angle2=2*j*PI/60;

26
glVertex3f(8*cos(angle2),8*sin(angle2),-0.5);

glEnd();

void DrawCoordination(float length)

glBegin(GL_LINES);

glColor3f(0.7,0,0);

glVertex3f(0,0,-0.5);

glVertex3f(length,0,-0.5);

glEnd();

glBegin(GL_TRIANGLES);

glColor3f(0.7,0,0);

glVertex3f(length, 0, -0.5);

glVertex3f((1-0.2)*length, 0.05*length, -0.5);

glVertex3f((1-0.2)*length, -0.05*length, -0.5);

glVertex3f(length, 0, -0.5);

glVertex3f((1-0.2)*length, 0, 0.05*length-0.5);

glVertex3f((1-0.2)*length, 0, -0.05*length-0.5);

glEnd();

27
void CMainFrame::RenderGLScene()

if (!m_bAppIsActive)

return;

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Clear Screen And Depth Buffer

glLoadIdentity();

// EXAMPLE OPENGL CODE


START ////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

static GLfloat xrot;


// X Rotation

static GLfloat yrot;


// Y Rotation

static GLfloat zrot;


// Z Rotation

glPushMatrix();
// Push Matrix Onto Stack (Copy The
Current Matrix)

glLoadIdentity();
// Reset The Current Modelview
Matrix

glTranslatef(0.0f,0.0f,-40.0f);
// Move Into The Screen 40.0

28
glRotatef(-60, 1, 0, 0);

// glRotatef(xrot,1.0f,0.0f,0.0f);

// glRotatef(yrot,0.0f,1.0f,0.0f);

// glRotatef(zrot,0.0f,0.0f,1.0f);

DrawCoordination(15);

glPushMatrix();

glRotatef(90, 0, 0, 1);

DrawCoordination(15);

glPopMatrix();

drawx(r1,r2,r3);

// glPushMatrix();

// glRotatef(zrot, 0, 0, 1);

drawfan(k);

// glPopMatrix();

glPopMatrix();
// Pop Matrix Off The Stack

xrot+=1.5f;

yrot+=1.5f;

29
zrot+=1.5f;
// Scaderea variabila de
rotatie pentru Quad

//////////////////////////////////////////////////////////////////////////////

// EXAMPLE OPENGL CODE


END //////////////////////////////////////////////////////////

// Swap our scene to the front

SwapBuffers(m_hDC);

Invalidate(FALSE);

/////////////////////////////////////////////////////////////////////////////

// CMainFrame OnCreateClient

GLvoid CMainFrame::ReSizeGLScene(GLsizei width, GLsizei height)


// Resize And Initialize The GL Window

if ( height==0) {
// Prevent A Divide By Zero By

height=1;
// Making Height Equal One

30
}

glViewport(0,0,width,height);
// Reset The Current Viewport

glMatrixMode(GL_PROJECTION);
// Select The Projection Matrix

glLoadIdentity();
// Reset The Projection Matrix

gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
// Calculate The Aspect Ratio Of The Window

glMatrixMode(GL_MODELVIEW);
// Select The Modelview Matrix

glLoadIdentity();
// Reset The Modelview Matrix

//////////////////////////////////////////////////////////////////////////////

// CMainFrame InitGL

int CMainFrame::InitGL(GLvoid)
// All Setup For OpenGL Goes Here

31
{

// EXAMPLE DIRECT SOUND CODE


START ////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

// EXAMPLE DIRECT SOUND CODE


END ////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////

glShadeModel(GL_SMOOTH);
// Enable Smooth Shading

glClearColor(0.0f, 0.0f, 0.0f, 0.5f);


// Black Background

glClearDepth(1.0f);
// Depth Buffer Setup

glEnable(GL_DEPTH_TEST);
// Enables Depth Testing

glDepthFunc(GL_LEQUAL);
// The Type Of Depth Testing
To Do

glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// Really Nice Perspective Calculations

glEnable(GL_TEXTURE_2D);
// Enable Texture Mapping

return TRUE;
// Initialization Went OK

32
//////////////////////////////////////////////////////////////////////////////

// CMainFrame KillGLWindow

GLvoid CMainFrame::KillGLWindow(GLvoid)
// Properly Kill The Window

if (m_bFullScreen)
// Are We In Fullscreen
Mode?

if (!ChangeDisplaySettings(NULL,CDS_TEST)) {
// if the shortcut doesn't work

ChangeDisplaySettings(NULL,CDS_RESET);
// Do it anyway (to get the values out of the
registry)

ChangeDisplaySettings(&m_DMsaved,CDS_RESET);
// change it to the saved settings

} else {

ChangeDisplaySettings(NULL,CDS_RESET);

ShowCursor(TRUE);
// Show Mouse Pointer

33
if ( m_hRC ) {
// Do We Have A Rendering
Context?

if ( !wglMakeCurrent ( NULL, NULL ) ) {


// Are We Able To Release The DC And RC
Contexts?

MessageBox ( "Release Of DC And RC Failed.",


"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION );

if ( !wglDeleteContext ( m_hRC ) ) {
// Are We Able To Delete The RC?

MessageBox ( "Release Rendering Context Failed.",


"SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION );

m_hRC = NULL;
// Set RC To NULL

if ( m_hDC && !::ReleaseDC ( m_hWnd, m_hDC ) ) {


// Are We Able To Release The DC

MessageBox ( "Release Device Context Failed.", "SHUTDOWN


ERROR", MB_OK | MB_ICONINFORMATION );

m_hDC = NULL;
// Set DC To NULL

if ( m_hWnd && !::DestroyWindow ( m_hWnd ) ) {


// Are We Able To Destroy The Window?

34
MessageBox( "Could Not Release m_hWnd.", "SHUTDOWN
ERROR", MB_OK | MB_ICONINFORMATION );

m_hWnd = NULL;
// Set m_hWnd To NULL

/////////////////////////////////////////////////////////////////////////////

// CMainFrame OnKeyDown

void CMainFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)

CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags);

// TODO: Add your message handler code here and/or call default

switch ( nChar ) {

case VK_ESCAPE:

PostMessage ( WM_CLOSE );

break;

} // end switch

35
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)

if (CFrameWnd::OnCreate(lpCreateStruct) == -1)

return -1;

SetTimer(1,100,NULL);

SetTimer(2,5,NULL);

return 0;

void CMainFrame::OnDestroy()

CFrameWnd::OnDestroy();

KillTimer(1);

KillTimer(2);

void CMainFrame::OnTimer(UINT nIDEvent)

switch(nIDEvent)

case 1:

r1=r1+0.5;r2=r2+0.5;r3=r3+0.5;

if(r1>=8) r1=0;

36
if(r2>=8) r2=0;

if(r3>=8) r3=0;

case 2:

k=k+0.5;

Invalidate();

CFrameWnd::OnTimer(nIDEvent);

void CMainFrame::OnLButtonDown(UINT nFlags, CPoint point)

AfxMessageBox("ÄúºÃ,´ËΪÀ×´ïÏÔʾÆ÷µÄ»æÖƶ¯»³ÌÐò\n\t\t\t¡ª¡ªxin");

CFrameWnd::OnLButtonDown(nFlags, point);

37
38
39