Documente Academic
Documente Profesional
Documente Cultură
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.
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:
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:
6
ARC DE CERC. ALGORITMUL DDA
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)
7
Arcul rosu: r = 2 si θ = 2π/3, deci s = 4π/3
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:
Exemplu: daca radianul uni cerc este 5cm si unghiul arcului este 110o , care este lungimea
arcului?
Solutie:
Circumferinta= 2πr
9
Aplicatie
//
#include "stdafx.h"
#include "spp.h"
#include<math.h>
#include "MainFrame.h"
#define PI 3.1415926
#ifdef _DEBUG
#undef THIS_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;
m_bFullScreen=TRUE;
// Windowed Mode
CMainFrame::~CMainFrame()
KillGLWindow(); // Shutdown
12
/////////////////////////////////////////////////////////////////////////////
// CMainFrame PreCreateWindow
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;
if
(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!
=DISP_CHANGE_SUCCESSFUL)
m_bFullScreen=FALSE;
// Windowed Mode Selected.
else
14
return FALSE;
// 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.lpszClass = AfxRegisterWndClass(CS_OWNDC|CS_HREDRAW|
CS_VREDRAW|CS_DBLCLKS,
return TRUE;
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
#ifdef _DEBUG
CFrameWnd::AssertValid();
16
void CMainFrame::Dump(CDumpContext& dc) const
CFrameWnd::Dump(dc);
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// CMainFrame OnCreateClient
// TODO: Add your specialized code here and/or call the base class
if (bRet)
GLuint PixelFormat;
// Holds The Results After Searching For A
Match
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
};
KillGLWindow ();
// Reset The Display
return FALSE;
19
KillGLWindow ();
// Reset The Display
return FALSE;
KillGLWindow ();
// Reset The Display
return FALSE;
KillGLWindow ();
// Reset The Display
return FALSE;
20
}
KillGLWindow ();
// Reset The Display
return FALSE;
if ( !InitGL () ) {
// Initialize Our Newly Created GL
Window
KillGLWindow ();
// Reset The Display
return FALSE;
m_bAppIsActive = TRUE;
21
return bRet;
/////////////////////////////////////////////////////////////////////////////
// CMainFrame OnPaint
void CMainFrame::OnPaint()
/////////////////////////////////////////////////////////////////////////////
// CMainFrame OnSize
22
m_cxClient = cx;
m_cyClient = cy;
ReSizeGLScene( cx, cy );
/////////////////////////////////////////////////////////////////////////////
// CMainFrame OnSetFocus
OnQueryNewPalette();
/////////////////////////////////////////////////////////////////////////////
// CMainFrame OnCreateClient
BOOL CMainFrame::OnQueryNewPalette()
Invalidate();
return TRUE;
23
/////////////////////////////////////////////////////////////////////////////
// CMainFrame OnPaletteChanged
OnQueryNewPalette();
/////////////////////////////////////////////////////////////////////////////
// CMainFrame OnActivateApp
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();
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();
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();
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(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();
//////////////////////////////////////////////////////////////////////////////
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
//////////////////////////////////////////////////////////////////////////////
SwapBuffers(m_hDC);
Invalidate(FALSE);
/////////////////////////////////////////////////////////////////////////////
// CMainFrame OnCreateClient
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
{
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
glShadeModel(GL_SMOOTH);
// Enable Smooth Shading
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 ( !wglDeleteContext ( m_hRC ) ) {
// Are We Able To Delete The RC?
m_hRC = NULL;
// Set RC To NULL
m_hDC = NULL;
// Set DC To NULL
34
MessageBox( "Could Not Release m_hWnd.", "SHUTDOWN
ERROR", MB_OK | MB_ICONINFORMATION );
m_hWnd = NULL;
// Set m_hWnd To NULL
/////////////////////////////////////////////////////////////////////////////
// CMainFrame OnKeyDown
// TODO: Add your message handler code here and/or call default
switch ( nChar ) {
case VK_ESCAPE:
PostMessage ( WM_CLOSE );
break;
} // end switch
35
}
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);
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);
AfxMessageBox("ÄúºÃ,´ËΪÀ×´ïÏÔʾÆ÷µÄ»æÖƶ¯»³ÌÐò\n\t\t\t¡ª¡ªxin");
CFrameWnd::OnLButtonDown(nFlags, point);
37
38
39