ورود

View Full Version : سوال: حرکت توپ



mrbm_2007
سه شنبه 20 بهمن 1388, 02:50 صبح
سلام
من می خوام حرکت توپ روی یک صفحه رو بصورت سه بعدی شبیه سازی کنم
بدیهی که مسئله اصلی چرخوندن سطح توپ(texture) متناظر با جابجایی توپه.
برای این کار من به یک ماتریس دوران حول یک محور گذرنده از مبدا با زاویه ی مشخص نیاز دارم.
من دارم از opengl استفاده می کنم و اساتید می دونن که glrotate تابع مخصوص همین جور کاری هست.(دوران)
فرض کنید توپ از مبدا به نقطه (x,y) رفت، برای این حالت محور و زاویه بدست میاد و با همون تابع راحت میشه چرخوندش!
ولی حالا اگه در ادامه اون حرکت به نقطه (x2,y2) بره دوبار چرخوندن لازم داره.
یک راه ساده استفاده از آرایه و ذخیره کردن این چرخش هاس، ولی اصلاً خوب نیست!!
و راه بهتر اینکه جمع آثار قبلی ها رو نگه داریم ،ولی چجوری؟:عصبانی++:(چون تو opengl هر بار باید از اول صحنه ایجاد بشه و حالت قبلی در کار نیست)
اگه ماتریس های دوران رو داشته باشیم ،حاصلضرب اونها میشه همون چیزی که میخوایم.(البته نه به این راحتی ولی دیگه مشکل حل میشه)
:متفکر:

نمی دونم شاید روش های بهتری هم باشه
در هر صورت اگه کسی تجربه یا اطلاعی داره ممنون می شم اگه راهنمایی کنه
:تشویق:

اگه خواستید یه نگاهی به فایل ضمیمه هم بندازید.(البته خیلی روبراه نیست ولی شما خرده نگیرید)
{کلید های برنامه:
حرکت موس
درگ موس
چرخ موس}

باتشکر

kochol
سه شنبه 20 بهمن 1388, 14:55 عصر
سلام
اول از همه بهت تبریک می گم دمو جالبی نوشتی.

راحی که به فکر من می رسه.
1- جهت حرکت توپ رو که داری ضرب خارجی شو با بردار 0 1 0 حساب کن.
2- این بردار جدید می شه همون محوری که باید توپت رو دورش بچرخونی.
3- بر اساس سرعت حرکت توپ مقدار چرخش دور اون محور رو زیاد کن.

این کار جهت چرخشت رو درست می کنه اما دقیقا نمی دونم که این کافیه یا نه.

kochol
سه شنبه 20 بهمن 1388, 14:57 عصر
دوست کارت خیلی خوب بود و من مطما هستم که 100% تو این زمینه پیشرفت میکنی.:تشویق:
ولی به نظر من ( نمیخوام به OpenGL توهین کنم :افسرده:) ولی اگر با Direct3D ادامه بدی ، خیلی بهتره.:متفکر:
اگر برنامت با OpenGL نبود ، میتونستم بهت کمک کنم .:ناراحت:

به این حرف ها زیاد گوش نده هیچ فرقی نمی کنه d3d با ogl

خوب شما فرض کن که برنامش با d3d است شما روش d3d رو بگو تبدیل اون به ogl با من

mrbm_2007
سه شنبه 20 بهمن 1388, 16:51 عصر
خیلی ممنون که جواب دادید
البته بگم من خودم کم کم دارم به سمت Directx هم میرم
نه لزوما بخاطر برتری بلکه بخاطر همه گیر بودنش
در هر حال زیاد مهم نیست

درباره تابع glrotate ؛ یه زاویه و یه بردار (جهت) می گیره و محور ها رو می چرخونه


راهی که به فکر من می رسه.
1- جهت حرکت توپ رو که داری ضرب خارجی شو با بردار 0 1 0 حساب کن.
2- این بردار جدید می شه همون محوری که باید توپت رو دورش بچرخونی.
3- بر اساس سرعت حرکت توپ مقدار چرخش دور اون محور رو زیاد کن.
مشکل اینجاست که وضعیت texture تابع مسیر حرکت توپه
اگه ابتدا در یک راستا و سپس در یک راستای دیگه حرکت کنه باید اثر این دوتا با هم در نظر گرفته بشه.
مثلاً اگه لازم باشه با اندازه theta1 حول I1 بچرخه و به اندازه theta2 حول I2 حال ما اون رو حول I3 به اندازه theta3 می چرخونیم ولی مشکل پیدا کردن این محور و زاویه ست.

البته من امروز یه چیزی دیدم مثل اینکه وضعیت چرخیده شده رو توی یه ماتریس نگه می داشت بعد در ابتدای ایجاد صحنه از اون استفاده می کرد و چرخش های بعدی رو در ادامه اون اعمال می کرد
ولی راستش یکم کلاسش از من بالاتر بود
چیز خاصی دست گیرم نشد
اینم آدرسش:
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=48

mrbm_2007
چهارشنبه 21 بهمن 1388, 05:35 صبح
Negative_Se7en (http://www.barnamenevis.org/forum/member.php?u=134418) جان ممنون از پیگیری تون
* همون تور که kochol (http://www.barnamenevis.org/forum/member.php?u=6875) هم اشاره کرد از ضرب خارجی بردار حرکت توپ در بردار یکه K(در جهت محور z عمود بر صفحه) محور دوران بدست میاد(چون حاصل ضرب خارجی بر هردوی این بردار ها عموده)
* برای بدست آوردن زاویه هم طول مسیر حرکت رو بر شعاع توپ تقسیم کنیم زاویه به رادیان بدست میاد(رابطه طول کمان با شعاع دایره)
البته این ها برای حالتی صادقه که فقط در یک مسیر حرکت کرده باشه و تغییر جهت نداده باشه
راستی جهت محور دوران هم از روی ضرب خارجی بدست میاد. البته به ترتیب ضرب کردن بستگی داره که فکر می کنم چیزی که بالا نوشتم ترتیب درست باشه!

mrbm_2007
چهارشنبه 21 بهمن 1388, 12:57 عصر
من هنوز به نتیجه نرسیدم
یه با مرام پیدا نمیشه کمک کنه؟

mrbm_2007
جمعه 23 بهمن 1388, 12:28 عصر
خب بالاخره مشکل حل شد
بعدا وقت کنم حتما راه حل رو توضیح می دم:چشمک:

mrbm_2007
دوشنبه 26 بهمن 1388, 11:52 صبح
این تابع یه آرایه چهار تایی میگیره (بردار جهت دوران و زاویه) و یک ماتریس 3*3 که ماتریس دوران هست رو برمی گردونه



type
matrix33 = array [1 .. 3] of array [1 .. 3] of Double;
matrix4 = array [1 .. 4] of Double;
...

function CalcRot(rot4: matrix4):matrix33;
var
n, s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz: Double;
nR: matrix33;
begin
n := (rot4[1] * rot4[1]) + (rot4[2] * rot4[2]) + (rot4[3] * rot4[3]) +
(rot4[4] * rot4[4]);
if n > 0 then
s := 2 / n
else
s := 0;

xs := rot4[1] * s;
ys := rot4[2] * s;
zs := rot4[3] * s;
wx := rot4[4] * xs;
wy := rot4[4] * ys;
wz := rot4[4] * zs;
xx := rot4[1] * xs;
xy := rot4[1] * ys;
xz := rot4[1] * zs;
yy := rot4[2] * ys;
yz := rot4[2] * zs;
zz := rot4[3] * zs;

nR[1][1] := 1 - (yy + zz);
nR[2][1] := xy - wz;
nR[3][1] := xz + wy;
nR[1][2] := xy + wz;
nR[2][2] := 1 - (xx + zz);
nR[3][2] := yz - wx;
nR[1][3] := xz - wy;
nR[2][3] := yz + wx;
nR[3][3] := 1 - (xx + yy);

result := nR;
end;
بعد باید اون رو به یک ماتریس 16 تایی تبدیل کنید مثلا rot و برای اعمال دوران از

glMultMatrixf(@rot);استفاده کنید
البته باید ماتریس دورن در ماتریس دوران قبلی ضرب بشه تا اثرات قبلی هم اعمال بشه
اون ماتریس rot رو هم این جوری تشکیل داده می شه(nr ماتریس دوران 3*3 هست)


rot[1] := nR[1][1];
rot[2] := nR[1][2];
rot[3] := nR[1][3];
rot[4] := 0;
rot[5] := nR[2][1];
rot[6] := nR[2][2];
rot[7] := nR[2][3];
rot[8] := 0;
rot[9] := nR[3][1];
rot[10] := nR[3][2];
rot[11] := nR[3][3];
rot[12] := 0;
rot[13] := 0;
rot[14] := 0;
rot[15] := 0;
rot[16] := 1;