تیر
۴
۱۳۹۱

رسم انواع دایره در OpenGL

همونطور که میدونید برای رسم دایره دلخواهمون در OpenGL باید مقداری برنامه نویسی کنیم.

در این نوشته ابتدا قصد دارم دو روش جالب و مناسب برای رسم دایره های توخالی رو شرح بدم و سپس روش رسم دایره توپر رو براتون بگم.

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

برای رسم دایره به فرمول ریاضی دایره و یک حلقه نیاز داریم تا بتونیم به تعداد دلخواه نقاط سازنده دایره رو بدست بیاریم و سپس با متصل کردن این نقاط شکل دایره ایه خودمون رو به وجود بیاریم. هرقدر تعداد نقاط بیشتری رو به دست بیاریم و به OpenGL اعلام کنیم دایره رسم شده توسط OpenGL دقیقتر و دایره تر خواهد بود.

حالا سوال اینجاست که چگونه نقاط تشکیل دهنده دایره رو به دست بیاریم؟

حتما از دوره دبیرستان به یاد دارید که فرمول دایره به صورت زیر بود:

x2 + y2 = r2

برای رسم دایره توخالی، x و y هیچکدام برای استفاده در شمارنده حلقه فور مناسب نیستند چون در صورت استفاده از اونها نمیتوان به شکل ساده و تمیز از امکانات OpenGL برای رسم دایره استفاده کرد.

برای حل زیباتر این مسئله بهتره از جاگذاری های زیر در فرمول بالا استفاده کنیم:

X = r cos(θ)   =>   x2= r2 – (r2cos2(θ))   =>   x = ± r sin(θ)

Y = r sin(θ)   =>   y2= r2 – (r2sin2(θ))   =>   y = ± r cos(θ)

با استفاده از این جاگذاری ها میتونیم در هر مرحله x و y رو به صورت مستقل از هم به دست بیاریم. همچنین از زاویه میتونیم به عنوان شمارنده حلقه استفاده کنیم. به طوری که با افزایش زاویه به مقدار دلخواه در هر مرحله از حلقه مختصات نقطه جدیدی از دایره به دست خواهد آمد.

به کد زیر توجه کنید:

در حلقه مثال فوق زاویه از صفر تا ۲π تغییر میکنه و در هر مرحله از اجرا یک مختصات جدید از نقاط روی دایره به دست میاد و رسم میشه. اگر مقدار stage به قدر کافی کم باشه تعداد نقاط به قدری زیاد خواهد شد که شکل ترسیم شده توسط نقاط به صورت یک دایره دیده خواهد شد.

اما کار بهتر اینه که به جای استفاده از GL_POINTS در مثال بالا از GL_LINE_LOOP یا GL_LINE_STRIP استفاده کنیم. در این صورت تمام نقاط به دست آمده بر روی دایره به یکدیگر متصل خواهند شد و احیانا نقاط خالی در رسم دایره نخواهیم داشت. به مثال زیر توجه کنید:

در قطعه کد بالا baseX و baseY که به عنوان پارامتر های تابع drawCircle تعریف شدند، مختصات نقطه مرکز دایره رو دریافت میکنند. با مقداردهی دلخواه به این نقاط میتونیم دایره رو در هرجای دلخواه از صفحه ترسیم کنیم. همچنین بهتره که مقدار انتخابی برای stage مضربی از PI باشه تا دایره بدون اضافه کاری و به صورت کامل رسم بشه. تصویری از اجرای کد بالا را در زیر مشاهده میکنید.

روش بعدی برای رسم دایره توخالی مقداری پیچیده تر اما جالبتره. این شیوه دایره رو به عنوان یک چند ضلعی با اضلاع بسیار زیاد میبینه و رسم میکنه.

الگوریتم این روش به جای استفاده از زاویه به عنوان شمارنده حلقه، از عددی صحیح و مثبت که نشان دهنده تعداد اضلاع سازنده دایره است استفاده میکنه. به تکه کد زیر دقت کنید:

 به تفاوتهای کد مذکور با کدهای قبلی در خط هایلایت شده دقت کنید.

هرچقدر به edges مقداری بالاتری رو اختصاص بدیم دایره ترسیم شده دایره تر از آب در خواهد آمد. هرچند بهتره برای حفظ سرعت برنامه مقدار مناسبی رو برای این منظور در نظر بگیریم چون عملا از یک مقداری به بعد تفاوتی از نظر بیننده در مشاهده دایره های رسم شده توسط ما دیده نخواهد شد. یکی از نکات جالب این تکه کد اینه که میشه به استفاده از اون به راحتی هر چند ضلعی منتظمی رو ترسیم کرد.

تصویری از اجرای تکه کد بالا رو با مقداری ناکافی برای edges ملاحظه میکنید. همونطور که میبینید چون مقدار edges به حد کافی بالا نیست تصویر زیر کاملا به صورت دایره دیده نمیشه.

 

بعد از مبحث رسم دایره توخالی میرسیم به نحوه رسم دایره های توپر.

برای دایره توپر روش های متعددی میشه استفاده کرد. یکی از این روشها استفاده از GL_TRIANGLE_FAN میباشد. با این شیوه دایره ی توپر به شکل مجموعه ای از مثلث های به هم پیوسته ترسیم خواهد شد.

کد مربوط به این روش رو در زیر مشاهده میکنید.

دقت کنید که در این کد قبل از ورود به حلقه فور راس مثلث ها که همان راس دایره میباشد مقداردهی میشود. سپس نقاط بعدی که همان نقاط روی دایره هستند درون حلقه پیدا شده و مثلث های تشکیل دهنده دایره توپر رسم میشوند.

در شکل های زیر مراحل رسم با استفاده از این روش رو مشاهده میکنید.

و همینطور ادامه تا:

امیدوارم این مطلب براتون مفید بوده باشه. در پایان یک نمونه کد کامل برای رسم این نوع دایره ها در لینک زیر قرار دادم.

دانلود سورس کد رسم انواع دایره با OpenGL

مرور کد برنامه رسم انواع دایره با OpenGL:

 تصویری از اجرای کد برنامه بالا:

اشتراک گذاری این مطلب:

نوشته‌های مرتبط

درباره نویسنده

برنامه‌نویس ++‏C/C‏ - برنامه‌نویس سیستم‌های گرافیکی با استفاده از کتابخانه ‏OpenGL - برنامه‌نویس #‏C و ..‏



۵۵ دیدگاه افزودن دیدگاه +

  • mr30.kheyli behem komak kard mamnunam

    • خواهش میکنم. خوشحالم که بهتون کمک کرده

  • سلام
    خوبی یک دایره متحرک چه طور میشه رسم کرد که در طول و عرض توسط کلید کی بورد حرکت کنه؟

    • سلام
      اگر از glut استفاده میکنید میتونید با استفاده از glutSpecialFunc و یا glutKeyboardFunc توابعی رو برای اداره کننده های رخداد های صفحه کلید معرفی کنید و سپس برای هر کلید دلخواه با استفاده از تابع glTranslatef دایره رو حرکت بدید

      • سلام
        من یه دایره در opengl دارم میخوام این دایره در خط افقی جا به جا شه بدون هیچ دکمه یا عمل خاصی فقط این دایره تو خط افق جابه جا شه
        اگه ممکنه دراینباره راهنماییم کنید
        ممنون از شما و سایت خوبتون

  • سلام ندا خانم
    اگر میخواهید دایره به صورت اتوماتیک و مثلا در فواصل زمانی معینی به اندازه های دلخواهی روی خط افقی حرکت کنه میتونید از تابع glutTimerFunc برای زمانبندی این کار و از تابع glTranslatef برای حرکت دادن شکلتون استفاده کنید. نحوه تعریف و استفاده این توابع در کتابها و اینترنت کاملا اومده اول خودتون ببینید بعد اگر سوالی داشتید در خدمتم

  • سلام خسته نباشید
    خیلی لطف کردید،انشالله موفق باشید

    • سلام احسان جان
      وظیفه بود
      شما هم موفق باشی

  • سلام میشه بگیید اگه بخوام در داخل یک دایره یک مستطیل قرار بدهم به چه صورت هست؟اگر میدونید لطفا کدش رو برام بزارید؟

    • سلام. اگر براتون فرقی نداره مستطیل به چه شکل درون دایره قرار بگیره میتونید به راحتی با استفاده از تابع glRectf مستطیل رو رسم کنید.

  • خیلی متشکر خدا بهتون خیر بده موفق باشید

  • سلام .میشه بیضی هم بذارید.البته کد کاملشو

    • برای کشیدن بیضی فقط کافیه مقدار radius رو در کد بالا برای x , y متفاوت در نظر بگیرید

  • slm man bayad chand ta dayere kenar ham 4 ta bala 3 ta payinesh va.. anja bedam chejori mishe komakam konid mer30

    • فکر میکنم همین مطلب به طور کامل میتونه کمکتون کنه. فقط کافیه چند تکه کد رسم دایره رو با نقاط مرکزی که میخواهید کپی و پیست کنید.

  • سلام خوبین تشکر میکنم از اینکه اطلاعاتتون رو در اختیار ما میگذارید . من مراحل تکامل ماه را با open gl برنامه نوشتم اما نمیدونم چه جوری با استفاده از دستورات list در open gl ماه اول به ماه دوم همینطور تا ماه ۱۴ تبدیلبشه خوشحال میشم اطلاعاتتون رو در اختیار من بذارید

    • سلام
      عذرخواهی میکنم که جوابتون رو دیر میدم.
      اگر درست متوجه شده باشم شما با دستور glGenLists چند تا لیست ساختید و میخواهید از یک شکل آرام آرام به سمت شکل دیگه برید. اگر اینطوره فقط کافیه یک وقفه با استفاده از متد glutTimerFunc مابین تغییر شکل هاتون بدید. اگر منظور دیگه ای داشتید کاملتر بگید تا توضیح بیشتری بدم.

  • سلام.مرسی خوب بود. من میخوام تو این دایره اسممو بنویسم.میشه کمکم کنید؟؟؟؟

    • سلام
      اگر میخواهید اسمتون رو با حروف لاتین بنویسید میتونید از این مطلب استفاده کنید

  • با تشکر از مطالبتون
    میخواستم ببرسم اگه بخوام یه جدول ۳۲در۳۲ ای که در word ساختم و حاوی یه سری خونه های سیاه و سفیده بیاد داخل این دایرهه باید چی کار کنم؟ ممنون میشم راهنماییم کنین

    • شما برای کشیدن شکلی که گفتید باید از دستورات خود OpenGL استفاده کنید. مثلا میتونید از تابع glRectf برای کشیدن مستطیل هایی که تشکیل یک جدول رو میدن استفاده کنید.

  • سلام دوست عزیز
    من ۴ تا مربع کنار هم قرار دادم الان میخوام ۱ دایره بیاد رو این ۴ تا مربع قرار بگیره
    هر کاری میکنم درست نمیشه….. میشه کمک کنی؟؟؟؟

    • سلام جواد جان
      کدی که نوشتی رو برام بفرست تا راهنماییت کنم

  • salam.man do ta darkhast dashtam.mishe lotf konin code rasme mokaab simi ro ham bezarin.va inke agar bekham hamin dayere ba mouse rasm beshe bayad chi kar konam?
    mamnoon misham komak konin

    • میبخشید که دیر پاسخ دادم
      کدی که گفتین رو متاسفانه فعلا فرصت نمیکنم ارسال کنم
      اما درباره رسم دایره با موس میتونید از برنامه ای که برای بازی دوز در سایت گذاشتم
      استفاده کنید. در اون برنامه کدهای مربوط به کار با ماوس رو خواهید دید.

  • من می خوام چند تا کره با جنس های مختلف بسازم … یکی آینه ، فلز ، چوب و…
    چجوری میشه جنس کره ها رو مشخص کرد؟؟؟

  • سلام
    من برنامه های بالارو درdevc++ کپی کردم امااجرانشد.هیچی ازبرنامه نویسی وopengl نمیدونم بایدهفته بعدهم پروژه تحویل بدم.توروخدااگه میشه کمکم کنید.اگه امکانش هست برنامه کامل آماده اجراشوبرام بذارید. باتشکر

  • run روکه میزنم مینویسه warning: project is not compiled

  • سلام باتشکرزحمات شما. من کدهای بالارودرمحیطdev قرارمیدم امااجرانمیشه اخطارمیده

  • سلام اگه میشه به سوالات پاسخ بدین باتشکر

    • سلام یاسر جان
      متاسفانه دیر پیامتو دیدم با اینحال قبلا هم اعلام کرده بودم که کدهای اینجا برای ارائه پروژه درسی نیست.
      در مورد محیط dev هم باید بگم که متاسفانه هیچ کدام از کدها رو در اون محیط تست نکردم ولی حدس میزنم در صورتی که پیش نیازها رو به درستی نصب کرده باشید با تغییرات کمی بشه در اون محیط هم کدها رو کامپایل کرد.

  • سلام
    ممنون از کدهاتون خیلی خوب بود
    اگه ممکن هست کد یک شکل یخورده پیچیده تر بزارید
    خیلی ساده هست این شکل
    با تشکر

  • حواااااسم نبود
    کدهای دیگرو دیدم
    واااای عالللللی بود
    خخخییییییلللللللللللللللی ممنونم
    خدا قوت

  • salam
    merci az site khoobetoon
    kheyli be dardam khord

  • سلااام ممنون میشم در مورد این سوال راهنماییم کنید.برنامه ای که ۲۰۰ دایره را با مختصات تصادفی و شعاع بین ۱۰تا۳۰ با رنگهاای تصادفی بکشد.ممنووون

  • خیلی خیلی مرسی واقعا کمکم کردین.
    بازم مرسی

  • سلام
    ممنون از وبلاگ خوبتون
    اگه امکانش هس کد ی شکل دلخواه از دایره بیضی میخاستم
    ممنون

  • با سلام
    چگونه میتوان با در دست داشتن مشخصات ,مختصات و سرعت دو دایره متحرک در یک صفحه دو بعدی درصورت برخورد شکل برخورد را رسم کرد
    اگه امکان داره لطف کنید هر چه سریعتر ممنون میشم
    با تشکر

  • خوب و کامل بود ممنونم

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

  • سلام
    ابتدا از پست مفیدتون تشکر میکنم.
    من نیاز دارم دایره ای رسم کنم به روش در نظر گرفتن اضلاع چند ضلعی ولی با یک تفاوت
    در کد شما نقاطی که بدست میاد که اضلاع را تشکیل بدهند دارای فاصله یکسانی از یکدیگر هستند یعنی طول اضلاع بدست آمده با هم برابر است .
    اممممااا من باید از همین روش چندضلعی استفاده کنم ولی فاصله نقاطی که بدست میاد یکسان نباشه یعنی طول اضلاعی که بدست میاد یکسان نباشه

    اگه در نوشتن کدش .اینکه چه جور باید مختصات این نقاط را بدست بیارم کمک کنید یک دنیا ممنون میشوم

  • سلام ….خسته نباشید
    من توی پروژه ام میخوام از توابع آماده رسم دایره و رسم خط به زبان c ++ استفاده کنم میشه یکم راهنماییم کنید
    ممنون
    من خیلی برنامه بالارو درک نمی کنم

  • از شما بخاطر توضیحات خوبی که در مورد دایره دادید ممنونم در کار و زندگی موفق باشید

    • خوشحالم که مورد توجه شما قرار گرفته. انشاا.. که شما هم موفق باشید.

  • سلام باعرض خسته نباشید ممنون ا ز اطلاعات مفیدتون لذت بردم یه درخواستی داشتم میشه لوگوی یکی از بانک هاروطراحی کنید ممنون من خودم دانشجوی ایتی هستم وبه این رشته خیلی علاقه دارم ممنون میشم کمک کنید

    • سلام
      متاسفم امکان این کار رو ندارم

  • سلام باتشکر از اطلاعاتتون..میشه لطفا بگید برای ترسیم یک منحنی یا همون سطح توپر مرز بسته و نامنظم چیکار باید بکنم؟..سپاس

  • درود برشما آقا محسن. خیلی ممنون بابت آموزشتون. یه سوال داشتم اینکه آیا تابعی تو کتابخونه openGL هست که مثلآ یه شکلی رو بکشیم و در مرحله بعد با اون تابع و با استفاده از مرکز دوران دلخواه، شکلمون رو بچرخونیم. مثلآ مرکز دوران خارج از شکل ما باشه

  • سلام خسته نباشید.رسم سهمی و هذلولی هم میشه بزارید؟

    • سلام متاسفانه فرصت اینکار رو ندارم اما اگر قواعد اولیه رو بدونید هر شکل هندسی رو به نظرم میتونید خودتون رسم کنید
      موفق باشید

  • kheyli khub bud mamnoon az lotfetoon

  • سلام
    opengl c++ vs
    من یه منو نوشتم که کاربر هر کدومو انتخاب کرد شکل مربوطش چاپ شه درست شکلام چاپ میشه ولی وقتی هر شکلی چاپ شد دیگه ادامه برنامه اجرا نمیشه ینی باید کامل خارج بشه بعد دوباره از اول اجرا کنه
    تو glutMainLoop گیر میکنه
    ممنون میشم راه حلی بگید

    • سلام مرتضی جان راستشو بخوای چون مدت زیادیه از فضای اوپن جی ال خارج شدم چیزی درمورد مشکلی که دچار شدی به ذهنم نرسید
      امیدوارم با ممارست به راه حلش برسی که حتما میتونی

  • عالییییییییییییییییییییییییی بود الهی خدا خیرت بده

  • سلام
    خسته نباشید
    میشه کد رسم دایره و قلب رو برام بفرستین

فرستادن دیدگاه