1 / 36

OpenGL برنامه نویسی گرافیکی با

به نام خداوند هستی بخش یگانه. جلسه هشتم. OpenGL برنامه نویسی گرافیکی با . A.M. Safaei. جلسه هشتم . گرافیک کامپیوتری. تشخیص چند ضلعی های مقعر و محدب. هر چند ضلعی مقعر دست کم یک زاویه داخلی بیشتر از 180 درجه دارد ، همچنین امتداد بعضی از اضلاع چند ضلعی مقعر اضلاع دیگر را قطع می کند.

thi
Download Presentation

OpenGL برنامه نویسی گرافیکی با

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. به نام خداوند هستی بخش یگانه جلسه هشتم OpenGLبرنامه نویسی گرافیکی با A.M. Safaei

  2. جلسه هشتم گرافیک کامپیوتری • تشخیص چند ضلعی های مقعر و محدب • هر چند ضلعی مقعر دست کم یک زاویه داخلی بیشتر از 180 درجه دارد ، همچنین امتداد بعضی از اضلاع چند ضلعی مقعر اضلاع دیگر را قطع می کند. راس محسوب نمی شود : چند ضلعی مقعر>180 : چند ضلعی محدب<180 چند ضلعی های خود متقاطع

  3. جلسه هشتم گرافیک کامپیوتری • دستور gluOrtho2D (-100.0,100.0,-100.0,100.0); • دستور فوق براي تنظيم مختصات در ترسيم دو بعدي بكار مي رود. • به صورت پيش فرض مختصات دوبعدي به صورت 2 * 2 در نظر گرفته می شود. • فرمت کلی دستور در حالت دو بعدی: • فرمت کلی دستور در حالت سه بعدی(مختصات سه بعدی بصورت 2 * 2 * 2 ): • Void gluOrtho2D(GL double left, GL double right, GL double bottom, GL double top) • Void gluOrtho (GL double left, GL double right, GL double bottom, GL double top, GL double zNear, GL double zFar)

  4. جلسه هشتم گرافیک کامپیوتری • تابع Round ( ) • این تابع جهت گرد کردن متغیر های عددی مختلف استفاده می شود. • جهت استفاده از این تابع نیاز هست که از دو تابع Floor و Ceil مشخص گردد که از فایل سرآیند math.h استفاده می شود. • تابع Floor جز صحيح عدد را محاسبه مي كند. • تابع Ceil بزرگترين عدد صحيح نزديك به عدد اعشاري را برمي گرداند. int Round (GLdouble in) { GLint out; if ((in-floor(in))<0.5) out=floor(in); else out=ceil(in); return out; } • Floor(2.8)=2 • Floor(2.3)=2 • Ceil(2.8)=3 • Ceil(2.3)=3

  5. جلسه هشتم گرافیک کامپیوتری • تمرین: رسم دایره از طریق خطوط به هم پیوسته #include <GL/glut.h> #include<math.h> #define GL_PI 3.141592653 void mydisplay() { gluOrtho2D (-100.0,100.0,-100.0,100.0); glClear(GL_COLOR_BUFFER_BIT); float x,y,z,angle; glBegin(GL_LINES); z=0.0;

  6. جلسه هشتم گرافیک کامپیوتری • تمرین: رسم دایره از طریق خطوط به هم پیوسته for(angle = 0.0f; angle <= GL_PI; angle += (GL_PI / 20.0f)) { glColor3f(0.0,1.0,0.0); // Top half of the circle x = 50.0* sin(angle); y = 50.0*cos(angle); glVertex3f(x, y,z); glColor3f(1.0,0.0,0.0); // Bottom half of the circle y = 50.0*cos(angle+GL_PI); x = 50.0*sin(angle+GL_PI); glVertex3f(x, y,z); } glEnd(); glFlush(); } int main(intargc, char** argv) { glutInitWindowSize(500,500); glutCreateWindow("simple"); glutDisplayFunc(mydisplay); glutMainLoop(); }

  7. جلسه هشتم گرافیک کامپیوتری c • مثال های بیشتر در ترسیمات دو بعدی • ترسیم مثلث های تو در تو v1 v2 • با رسم یک مثلث شروع می کنیم. • میانه های اضلاع مثلث را به هم وصل کرده و مثلث داخل را حذف می کنیم. • تکرار مراحل فوق a b v3

  8. جلسه هشتم گرافیک کامپیوتری • تمرین: کد برنامه آنالیز نمایید. #include <GL/glut.h> /* initial triangle */ GLfloat v[3][2]={{-1.0, -0.58}, {1.0, -0.58}, {0.0, 1.15}}; int n; /* number of recursive steps */ void triangle( GLfloat *a, GLfloat *b, GLfloat *c) /* display one triangle */ { glVertex2fv(a); glVertex2fv(b); glVertex2fv(c); }

  9. جلسه هشتم گرافیک کامپیوتری • تقسیمات فرعی مثلث ها void divide_triangle(GLfloat *a, GLfloat *b, GLfloat *c,int m) {/* triangle subdivision using vertex numbers */ point2 v0, v1, v2; int j; if(m>0) { for(j=0; j<2; j++) v0[j]=(a[j]+b[j])/2; for(j=0; j<2; j++) v1[j]=(a[j]+c[j])/2; for(j=0; j<2; j++) v2[j]=(b[j]+c[j])/2; divide_triangle(a, v0, v1, m-1); divide_triangle(c, v1, v2, m-1); divide_triangle(b, v2, v0, m-1); } else(triangle(a,b,c)); /* draw triangle at end of recursion */ }

  10. جلسه هشتم گرافیک کامپیوتری • تابع نمایش و مقدار دهی اولیه void display() { glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_TRIANGLES); divide_triangle(v[0], v[1], v[2], n); glEnd(); glFlush(); } void myinit() { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(-2.0, 2.0, -2.0, 2.0); glMatrixMode(GL_MODELVIEW); glClearColor (1.0, 1.0, 1.0,1.0) glColor3f(0.0,0.0,0.0); } int main(intargc, char **argv) { n=4; glutInit(&argc, argv); glutInitWindowSize(500, 500); glutCreateWindow(“2D shap"); glutDisplayFunc(display); myinit(); glutMainLoop(); }

  11. جلسه هشتم گرافیک کامپیوتری • تمرین : رسم نقاط تصادفي با رنگهاي تصادفي void myDisplay() { gluOrtho2D(0,300,0,300); GLint Count; GLfloatr,g,b; glClear(GL_COLOR_BUFFER_BIT) ; glPointSize(1); for( Count = 0; Count < 32000; Count ++) { r= rand() % 100/100.0f; g= rand() % 100/100.0f; b= rand() % 100/100.0f; glColor3f(r, g, b); // set foreground color mySetPixel( (GLint) rand()%300,(Glint)rand()%300); } glutSwapBuffers() ; }

  12. جلسه هشتم گرافیک کامپیوتری • توابع سفارش رسم نقاط • تابع سفارشی رسم نقطه mySetPixel voidmySetPixel( GLint x , GLint y) { glBegin(GL_POINTS); glVertex2i(x,y); glEnd(); } ------------------- void mySetPixel( GLdouble x , GLdouble y) { glBegin(GL_POINTS); glVertex2d(x,y); glEnd(); }

  13. جلسه هشتم گرافیک کامپیوتری • رسم خط افقی و عمودی • ساده ترین خطها در رسم کامپیوتری خطوطی هستند که در امتداد محورها باشند به عبارت دیگر خطوطی که موازی یکی از محورهای X یا Y هستند. • برای رسم یک خط افقی یا عمودی کافیست به موزات محوری که خط موازی با آن است حرکت کرده و در هرگام یک پیکسل را رسم کنیم.

  14. جلسه هشتم گرافیک کامپیوتری • رسم خط افقی voidHLine(GLint X1, GLint Y, GLint X2) { GLintX,Temp; if( X1 > X2){ Temp=X1; X1=X2; X2=Temp;} for( X = X1; X <= X2; X ++) mySetPixel(X, Y); } • رسم خط عمودی voidVLine(GLint X, GLint Y1, GLint Y2) { GLintY,Temp; if( Y1 > Y2){ Temp=Y1; Y1=Y2; Y2=Temp;} for( Y = Y1; Y <= Y2; Y ++) mySetPixel(X, Y); }

  15. جلسه هشتم گرافیک کامپیوتری • رسم خط با شیب دلخواه • اینگونه خطوط انعطاف پذیری بسیار زیادی دارند و امکان اعمال کنترل بیشتری به کاربر می دهند. • همانطور که قبلا معادله خطی یک خط شیب دار از طریقY=mX + b محاسبه می شدکه در آن m شیب خط و مقدار b را بعنوان عرض از مبدا محاسبه می کردیم. • در صورتی که تغییرات x بیشتر از تغییرات y باشد در اینصورت : |m|<=1 و در صورتی که تغییرات y بیشتر از تغییرات X باشد در اینصورت : |m|>=1 خواهد بود. y – y1 = m ( x – x1) y=mx + b

  16. جلسه هشتم گرافیک کامپیوتری • رسم خط با شیب دلخواه void floatLine( GLint X1, GLint Y1, GLint X2, GLint Y2) { GLintiX, iY, Temp; float m, X, Y; if( (X2-X1) > (Y2-Y1)) { if( X1 > X2) { Temp=X1;X1=X2; X2=Temp; Temp=Y1; Y1=Y2; Y2=Temp; } m = (float) (Y2-Y1)/(X2-X1); for( iX = X1; iX <= X2; iX ++) { Y = m * ( iX - X1) + Y1; mySetPixel( iX, Round(Y)); } }

  17. جلسه هشتم گرافیک کامپیوتری • رسم خط با شیب دلخواه else { if( Y1 > Y2) { Temp=X1; X1=X2; X2=Temp; Temp=Y1; Y1=Y2; Y2=Temp; } m = (float) (X2-X1)/(Y2-Y1); for( iY = Y1; iY <= Y2; iY ++) { X = m * ( iY - Y1) + X1; mySetPixel( Round(X), iY); } } }

  18. جلسه هشتم گرافیک کامپیوتری • رسم دایره از طریق فرمول معادله دایره • فرمول ریاضی در رسم دایره به مرکز مبدا مختصات عبارت است از : • R شعاع و واحد آن بر حسب پیکسل می باشد. اگر مقدار y از از معادله زیر محاسبه کنیم. • به ازای هر مقدار x دو مقدار برای y بدست می آید، که ابتدا مقدار مثبت و سپس مقدار منفی را برای Y بدست می آوریم که با نیم دایریه بالایی و و پائینی متناظرند، بنابراین برای رسم دایره مقدار x را هر بار به اندازه یک واحد افزایش داد و سپس مقدار y را روی فرمول فوق محاسبه کرد.

  19. جلسه هشتم گرافیک کامپیوتری • رسم دایره (به روشی معادله ریاضی) void floatCircle(GLintXCenter, GLintYCenter, GLint r) { GLint x, y; GLfloat yr; GLdouble s; for( x = -r; x <= r ; x ++) { s=r*r -x*x; yr = sqrt(s); y = Round(yr); mySetPixel(x+XCenter, y+YCenter); mySetPixel(x+XCenter, -y+YCenter); } }

  20. جلسه هشتم گرافیک کامپیوتری • رسم بیضی با استفاده از معادله ریاضی • معادله بیضی بصورت زیر می باشد، پارامترهای a و b به ترتیب شعاعهای بیضی در راستای محور های x و y می باشند. void floatEllipse(GLintXCenter, GLintYCenter,GLint a, GLint b) } GLint x, y; GLfloat yr; for( x = -a; x <= a ; x ++) } yr = b*sqrt(1.0 -(GLfloat)(x*x)/(a*a)); y = Round(yr); mySetPixel(x+XCenter, y+YCenter); mySetPixel(x+XCenter, -y+YCenter); } }

  21. جلسه هشتم گرافیک کامپیوتری • مختصات سه بعدی :: 3 Dimensions • نحوه بیان مختصات در سه بعدی • در مختصات دو بعدی نیاز نداشتیم که دوربین ( چشم ما) به چه نقطه ای از مختصات نگاه می کند ولی در سه بعدی بصورت پیش فرض به سمت منفی محور Z ها نگاه می کند.

  22. جلسه هشتم گرافیک کامپیوتری • مختصات سه بعدی :: 3D • رسم کره • با استفاده از دو تابع زیر می توان کره ای تو پر و یا تو خالی در OpenGL رسم کرد. • Radius: شعاع کرده • slices: تعداد تقسیمات حول محور Z • Stacks تعداد تقسیمات در طول محور Z void glutSolidSphere(GLdouble radius, GLint slices, GLint stacks); void glutWireSphere(GLdouble radius, GLint slices, GLint stacks);

  23. جلسه هشتم گرافیک کامپیوتری • مختصات سه بعدی :: 3D • رسم مکعب • با استفاده از دو تابع زیر می توان مکعبی تو پر و یا تو خالی در OpenGL رسم کرد. • Size: اندازه هر کدام از اضلاع void glutSolidCube(GLdouble size); void glutWireCube(GLdouble size);

  24. جلسه هشتم گرافیک کامپیوتری • مختصات سه بعدی :: 3D • رسم مخروط • امکان ایجاد دو نوع مخروط توپر و توخالی با استفاده از توابع زیر در OpenGL وجود دارد. • base: شعاع قاعده هرم • height: ارتفاع هرم • Slices : تعداد تقسیمات حول محور z • Stacks :تعداد تقسیمات در طول محور void glutSolidCone(GLdouble base, GLdouble height, GLint slices, GLint stacks); void glutWireCone(GLdouble base, GLdouble height, GLint slices, GLint stacks);

  25. جلسه هشتم گرافیک کامپیوتری • مختصات سه بعدی :: 3D • رسم حلقه های بسته (Torus)) • با استفاده از دو تابع زیر می توان حلقه های تو پر و یا تو خالی در OpenGL رسم کرد. • innerRadius: شعاع داخلی • outerRadius: شعاع بیرونی • nsides: تعداد اضلع برای هر بخش دایره ای • rings:تعداد تقسیمات محسوری void glutSolidTorus(GLdoubleinnerRadius, GLdoubleouterRadius, GLintnsides, GLint rings); void glutWireTorus(GLdoubleinnerRadius, GLdoubleouterRadius, GLintnsides, Glint rings);

  26. جلسه هشتم گرافیک کامپیوتری • مختصات سه بعدی :: 3D • رسم قوری • کتابخانه GLUT امکان رسم یک قوری ( به صورت توپر و توخالی ) را در اختیار می گذارد : • Size: سایز شکل void glutSolidTeapot(GLdouble size); void glutWireTeapot(GLdouble size);

  27. جلسه هشتم گرافیک کامپیوتری • مختصات سه بعدی :: 3D • اشکال بدون آرگومان • کتابخانه GLUT اشکال دیگری را در اختیارتان می گذارد که کنترلی بر آن ها ( از لحاظ ارسال آرگومان به توابع آن ها ) ندارید و فقط می توانید آن ها رسم می کند. void glutSolidOctahedron(void); void glutWireOctahedron(void); void glutSolidIcosahedron(void); void glutWireIcosahedron(void); void glutSolidTetrahedron(void); void glutWireTetrahedron(void);

  28. جلسه هشتم گرافیک کامپیوتری • مختصات سه بعدی :: 3D • رسم یک مکعب بصورت دستی • مکعب را دقیقا همان طوری رسم می کنیم که بر روی کاغذ انجام می دهیم. ابتدا دو مربع با فاصله از هم می کشیم و سپس با استفاده از خطوط محل تلقی رئوس را به هم وصل می کنیم. #include <GL/glut.h> int Height=400, Width=400; float Size=0.5; void display(void) { glClear(GL_COLOR_BUFFER_BIT); glRotatef(50,1,0,1); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_QUADS); glVertex3f(0.0, 0.0, 0.0); glVertex3f(Size, 0.0, 0.0); glVertex3f(Size, Size, 0.0); glVertex3f(0.0, Size, 0.0); چرخش 50 درجه در راستای محور x و z//

  29. جلسه هشتم گرافیک کامپیوتری • مختصات سه بعدی :: رسم مکعب glVertex3f(0.0, 0.0, -Size); glVertex3f(Size, 0.0, -Size); glVertex3f(Size, Size, -Size); glVertex3f(0.0, Size, -Size); glEnd(); glBegin(GL_LINES); glVertex3f(0.0, Size, 0.0); glVertex3f(0.0, Size, -Size); glVertex3f(0.0, 0.0, 0.0); glVertex3f(0.0, 0.0, -Size); glVertex3f(Size, 0.0, 0.0); glVertex3f(Size, 0.0, -Size); glVertex3f(Size, Size, 0.0); glVertex3f(Size, Size, -Size); glEnd(); glutSwapBuffers(); } int main(intargc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE); glutInitWindowSize(Width, Height); glutCreateWindow("Manual Cube"); glutDisplayFunc(display); glutMainLoop(); }

  30. جلسه هشتم گرافیک کامپیوتری • ماتریس تبدیلات در OpenGL • ماتریس نما مدل (Modelview Matrix) • برای تبدیل اشیاء روی صحنه ( انتقال ، دوران و تغییر ابعاد و تغییر مختصات استفاده می شوند. • تشکیل شده از دو ماتریس: 1- نما ( جهت مشخص کردن مکان بیننده در سه بعدی)، 2- مدل ( جهت دریافت نقاط اصلی یک شی و نمایش آن در سه بعدی) . • ماتریس تصویر (Projection Matrix) • برای کار با تصاویر موازی و پرسپکتیو بکار می رود و چگونگی گرفتن یک نقطه از دنیای سه بعدی و قرار دادن آن بر روی صفحه دوبعدی را بیان می کند. • ماتریس بافت (Texture matrix) • برای تعیین بافتی که باید بر روی شی نگاشته شود بکار می رود.

  31. جلسه هشتم گرافیک کامپیوتری • ماتریس تبدیلات • جهت تعیین نوع ماتریس تبدیل در OpenGL از دستور زیر استفاده می شود. • پارامترهای Mode : • GL_MODELVIEW • GL_PROJECTION • GL_TEXTURE glMatrixMode(mode);

  32. جلسه هشتم گرافیک کامپیوتری • دریچه دید :: View Port • فرض OpenGL این نیست که شکل را بر روی تمام پنجره رسم کند. • پنجره گرافیکی را می توان به چند دریچه کوچک تقسیم کرد. • هر تصویر مجزا بر روی یک دریچه قابل رسم است. • دریچه ای که رسم اشکال در آن انجام می شود را دریچه دید می نامند. • دریچه دید می تواند کل پنجره باشد و یا هر ناحیه مستطیلی شکل از کل آن باشد. • ابعاد دریچه دید به اندازه به ابعاد پنجره نمایش وابسته است، به همین جهت هنگامی که ابعاد پنجره تغییر می کند باید دریچه دید را تنظیم کرد تا تبدیلات گرافیکی به درستی انجام شود.

  33. جلسه هشتم گرافیک کامپیوتری • دریچه دید :: View Port • تنظیم دریچه دید از طریق تابع : • X و Y مختصات پیکسلی گوشه سمت چپ پائین دریچه دید می باشد. • Height و Width ارتفاع و عرض دریچه دید بر حسب پیکسل می باشد. glViewport (Glint x, Glint y, Glsizei width, Glsizei height)

  34. جلسه هشتم گرافیک کامپیوتری • دریچه دید :: View Port • به هنگام تغییر سایز پنجره تابع reshape فراخوانی خواهد شد. glutReshapeFunc(reshape); void reshape (int width, int height) { glViewport (0, 0, width, height); }

  35. جلسه هشتم گرافیک کامپیوتری • دریچه دید :: View Port • با تعریف دریچه دید، مبدا مختصات در گوشه سمت چپ پائین در نظر گرفته می شود، تبدیلی که این مربع واحد را در حالت های دو یا سه بعدی به پنجره نمایش می نگارد ، تصویر یا Projection نامیده می شود. • برای تعیین ناحیه رسم باید به OpenGL اطلاع دهیم که ناحیه رسم ما از کجا شروع می شود تا بتواند آن را به روی دریچه دید ما بنگارد، اینکار توسط ماتریس تصویر (Projection Matrix) انجام می شود.

  36. جلسه هشتم گرافیک کامپیوتری • دریچه دید :: View Port • جهت سادگی تعیین مختصات و سختی کار با ماتریس تصویر می توان از تابع gluOrtho2D در حالت دوبعدی و gluOrtho در حالت سه بعدی استفاده کرد که پارامترهای محدوده عمق تصویر (محور Z ) نیز تعریف می شود. • رسم هایی که خارج از محدوده تعریف شده توسط پارامتر ها انجام شوند، کوتاه سازی و حذف خواهند شد. glOrtho(left, right, bottom, top, near, far)

More Related