Написах основен вариант с фиксирана запетая на синусоидалната функция, която използва справочна таблица (насочена към AVR микроконтролер без FPU). Моята реализация също така приема отрицателни стойности и стойности, които надвишават 2π, както прави висулката с плаваща запетая в math.h.
Така че трябва да картографирам дадената стойност в диапазон между 0 и 2π (т.е. техните аналогове с фиксирана точка). За положителни аргументи е лесно да ги отрежете с вградения в C оператор за остатък %. Тъй като това не е опция за отрицателни стойности, използвам следния (очевиден) подход:
unsigned int modulus = (a - (INT_FLOOR(a / b) * b) + b) % b;
a и b са стойности с целочислен тип и INT_FLOOR() се има предвид само като намек, че дробната част на (a/b) е съкратена. Тази формула гарантира, че изчисленият модул (който се използва като индекс за масива от таблици) е винаги положителен и че също така отрицателните аргументи се картографират с положителните им двойници (поддържайки фазови измествания в двете посоки).
Проблемът ми с този подход е, че изглежда прекалено сложен, тъй като включва не по-малко от пет аритметични операции. Има ли по-ефективен подход, който пропускам?
Този въпрос е изключително стар във времето на интернет, но най-простият начин... е просто да си бъркате в Objective-C... Съжалявам.
Моят общ начин за подход към това е следният:
NSOpenGLView
обект в браузъра на обекти и го чукнете върху прозореца си.MyRenderer
или нещо подобно.MyRendere
r.NSOpenGLView
.- (void) awakeFromNib
: Do your class initialization here. Do not initialize OpenGL here, or your program will crash.- (void) drawRect:(NSRect)dirtRect
: Рисувайте тук.- (void) prepareOpenGL
: Инициализирайте OpenGL тук.- (void) reshape:(NSRect)bounds
: Когато изгледът се преоразмерява.Добрата новина е, че можете свободно да смесвате C++ функции и класове в MyRenderer.mm. Можете също да използвате директиви C++
#include
заедно с директиви Objective-C#import
. Можете да правите C++ вътре вdrawRect
без проблеми.Лошата новина е, че
NSOpenGLView
не преначертава сцената на всеки x милисекунди. Той ще преначертае сцената само след като сметне за необходимо. За това ще трябва да използвате класаNSTimer
на Cocoa.Редактиране: Допълнителна забележка: В метода
- person Daniel Fischer   schedule 04.05.2012drawRect
не забравяйте да извикатеglFlush()
, както и[[self openGLContext] flushBuffer]
. По някаква причина само извикването на[[self openGLContext] flushBuffer]
не рисува нищо в изгледа за мен.fmod
, за да правите остатък от плаващи елементи? Работи правилно за отрицателни числа, както и за положителни. - person Sergey Kalinichenko   schedule 04.05.2012unsigned in modulus = abs(a) % abs(b);
Като алтернатива, нещо като:modulus = a % b; if (modulus < 0) modulus += b;
- person Jerry Coffin   schedule 04.05.2012