Identity Of Code

هیچی و همه چی

Identity Of Code

هیچی و همه چی

توابع easing

موتور های Tweening اصولا از روشی که Robert Penner در سال 2002 معرفی کرده استفاده می کنند. تو یکی از کتاباش این روش رو توضیح داده و به زبان اکشن اسکریپت 1 پیادش کرده.  دیروز سورس کد های TweenLite رو نگاه می کردم بیشتر توابع دقیقا مثل توابع پنر بود.

خوندن کد های پنر زیاد آسون نیست اون هم بخاطر موضوع performance ـه. این موضوع  آدم رو تو دوراهی قرار می ده، باید کدوم رو فدای اون یکی کرد ؟ سرعت اجرا یا سرعت توسعه ؟ خودم بارها با این مشکل برخوردم و دقیقا نمی دونم کی باید چیکار کرد.

این روش از یکسری معادلات ریاضی استفاده می کنه که به اونها توابع Easing میگن ، برای یک سری توابع مثل مجزور و مکعب و کلا توابع ایکس به توان n روش ثابته. اما یکسری توابع مثل Back، Bounce,Elastic که خاص تر هستند و روش های مختلفی دارن ،و کارو یکم پیچیده تر می کنن. 

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


که n تعداد نواسانات رو تعیین می کنه،این تابع به تنهایی نتیجه مطلوبی نمیده ، و کلا بیخیالش شدم تا این ک تو سورس کد توین لایت دیدم چیزی شبیه همین معادله بکار رفته منتهی با یک سری شرط و شروط که برای بازه های مختلف اعداد مختلف رو بده و این تابع فقط ناحیه ای خاصی رو ساپورت کنه، یک تفاوت جزیی دیگه ای هم داشت این بود که به جای عدد نپر 2 گذاشته بود.

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


اما روش سومی هم که من اینجا ارائه اش کردم تابعی به این شکله :


این تابع از لحاظ کارایی نسبتا خوبه و حجم پردازش مثل تابع بالا رو در گیر نمی کنه و از طرفی کنترل روش هست و میشه تعداد نوسانات رو هم تعیین کرد. این تابع در حالت عادیش همون تابع sinx/x ـه که حدش تو نقطه صفر یکه منتهی با روش عادی جایگذاری نمیشه حلش کرد و به 0/0 مبهم بر می خوریم. تو ریاضیات می تونیم از قضیه  فشردگی یا قاعده هوپیتال حلش منیم. اما تو زبان های برنامه نویسی قضیه فرق می کنه.تو اکشن اسکریپت 0/0 بی نهایت میده در نتیجه کافیه وقتی عدد infinity شد مقدارش رو به 1 تغییر بدیم.


هر چند این توابع هیچکدوم کاملا مثل هم کار نمی کنن و اما شباهت کلی بین همشون هست.




پ.ن: این تابع در حالت عادی برای easeInOut برای n های کوچکتر از 3 در وسط حرکت کاهش و افزایش سرعت داره. اما برای easeIn و easeOut به صورت جداگانه بخوبی کار می کنه


آپدیت: برای حل مشکل بالا میشه در بازه x بزرگتر از  (1+1/2n-) و کوچکتر از 1 تابع خطی 2nx-2n+1 رو  بدیم.

البته دقیق تر هم میشه کار کرد، طبق قضیه مقدار میانگین (Mean Value Theorem) در بازه ی نام برده روی منحنی موجود نقطه ای وجود داره که مشتق اون برابره با شیب خط راستی که از اون دو نقطه می گذره، اگر اون نقطه رو شناسای کنیم میتونیم تابع رو برای x های بزرگتر از اون نقطه اعمال کنیم، اینجوری منحنی شیب خودش رو در بازه بیشتری حفظ می کنه و حرکت طبیعی تر به نظر می رسه.