You are not logged in.
Pages: 1
У меня возникла небольшая проблема при написании скрипта...надо направить объект из 1 точки в другую....обе точки движутся.
Я пришёл к тому, что известен синус угла для объекта. А как узнать сам угол???
Ведь в СБ нету арксинуса...
Подскажите плз, в геометрии я не оч силён)
Last edited by 3Doomer (05-06-2009 19:55)
GIMS developer
Offline
Не так давно я писал код, чтобы объект появлялся всегда перед лицом игрока. Если тебе нужно это, то держи:
{$CLEO} WAIT 10000 0172: 0@ = actor $PLAYER_ACTOR Z_angle 0@ += 90.0 02F7: 1@ = sine 0@ // (float) 1@ *= 2.0 // 2 - расстояние от игрока до объекта 02F6: 2@ = cosine 0@ // (float) 2@ *= 2.0 // 2 - расстояние от игрока до объекта 0@ += -90.0 ACTOR.StorePos($PLAYER_ACTOR,3@,4@,5@) 005B: 3@ += 1@ // (float) 005B: 4@ += 2@ // (float) 5@ += -1.0 // уменьшаем высоту, чтобы объект был создан на земле, а не на уровне пояса игрока OBJECT.Create(6@,2779,3@,4@,5@) { создаем например игровой автомат (для другой модели может потребоваться предварительная загрузка} Object.Angle(6@) = 0@ { присваиваем объекту такой же угол поворота, как у игрока, в результате игрок и объект будут находиться "лицом к лицу"} 0A93: end_custom_thread
Offline
Мой код поворачивает объект только вокруг вертикальной оси (Z). Чтобы написать код для всёх трех осей, надо знать в каком порядке отмеряются два других угла.
Условие твоей задачи я так и не понял, объясни подробнее.
Насчет арксинусов - в них нет необходимости, т.к. углы игрока и объекта можно узнать непосредственно, а синусы берутся от этих углов.
Last edited by Den_spb (05-06-2009 20:08)
Offline
арксинус как раз то и нужен! у меня получается прямоугольный треугольник у которого известны все стороны....надо найти 1 из углов который не 90 градусов.
делю прилежащую сторону на противолежащую - получаю синус угла....сам угол узнаётся по арксинусу:crazy: которого нету в СБ
перечитай первый пост...я поправил чтобы было понятнее
по оси Z твой скрипт чёт тож не туды вродь поворачивает:rolleyes:
чертёж вложен....из точки А объект тянется в точку В
Last edited by 3Doomer (05-06-2009 20:27)
GIMS developer
Offline
Во-первых, ты неверно определяешь тригонометрические функции.
На твоем рисунке:
AB*cosCAB=AC
AB*sinCAB=BC
AC*tgCAB=BC
Чтобы получить отношение нужных отрезков треугольника, надо воспользоваться соответствующей функцией (есть и другие функции) для соответствующего угла.
Во-вторых, если нет другого способа, и необходим арксинус, то его можно найти разложением в ряд:
arcsinX = X + (X^3)/6 + (X^5)*3/40 + (X^7)*15/336 + ...
Чем больше слагаемых, тем больше точность, но 4-5 слагаемых думаю будет достаточно.
Значение угла получится в радианах.
Ну а насчет моего кода - всё работает, скрин в доказательство
Last edited by Den_spb (05-06-2009 21:19)
Offline
хм.....разложение в ряд может помочь=)
не всякий ряд будет сходится. Например, стандартное разложение арксинуса сходится только при величине параметра меньше 1 (чуть меньше 60 градусов).
Проще всего написать библиотеку функций на любом высокоуровневом языке, подключить ее и просто вызывать функции.
1) грузим библиотеку в адресное пространство игры
0AA2: 0@ = load_library "CLEO\Math.dll" // IF and SET
2) получаем адрес нужной функции
0AA4: 1@ = get_proc_address "GetASin" library 0@ // IF and SET
3) вызываем функцию по полученному адресу
0AA5: call 1@ num_params 1 pop 0 2@
При компиляции dll надо будет указать stdcall calling convention функции (тогда в опкоде будет pop 0).
4) выгружаем библиотеку
0AA3: free_library 0@
А еще можно воспользоваться Alexander's Quick Opcode.
Offline
не всякий ряд будет сходится. Например, стандартное разложение арксинуса сходится только при величине параметра меньше 1 (чуть меньше 60 градусов).
Радиус сходимости у ряда арксинуса действительно равен 1, но параметр этой функции - не угол, а синус угла. Синус же угла может принимать значения от 0 до 1 по модулю (1 - это уже прямой угол). Так что данное разложение можно использовать без ограничений.
Last edited by Den_spb (06-06-2009 00:28)
Offline
Радиус сходимости у ряда арксинуса действительно равен 1, но параметр этой функции - не угол, а синус угла.
Точно, стормозил.:crazy:
А может (и не может, а точно) в exe есть эта тригонометрия? Как-то не хочется алгоритмы приближенного вычисления писать на скриптовом языке...
Кстати, есть ряд готовых функций на асме. Можно преобразовать их в hex и вынести в отдельный label. Вот что получится:
:ASin hex blah-blah C3 end
Тогда вызов будет производится следующим образом:
0A9F: 0@ = current_thread_pointer 0@ += 0x10 0A8D: 0@ = read_memory 1@ size 4 virtual_protect 0 // baseIP 0@ -= @ASin // абсолютный адрес метки, он же адрес нашей функции в памяти игры 0AA7: call_function 0@ num_params 1 pop 1 param 1@ result 0@ //вызываем функцию, в 0@ оказывается арксинус 1@...
В теории как всегда все просто, на практике 100 раз вылетит прежде чем поймешь что не так.
Last edited by Alien (06-06-2009 09:14)
Offline
Ребята чего вы опять выдумываете велосипед старайтесь тщательнее изучать опкоды
вот вам работающий код
Object.StorePos(0@, 2@, 3@, 4@) // здесь координаты первой точки Object.StorePos(1@, 5@, 6@, 7@) // здесь второй 0087: 8@ = 5@ // (float) здесь исп. доп. пременную 0063: 8@ -= 2@ // (float) здесь находим расстояние x, обязательно в таком порядке (из второй вычитаем первую)! 0087: 9@ = 6@ // (float) здесь исп. доп. пременную 0063: 9@ -= 3@ // (float) здесь находим расстояние y, обязательно в таком порядке (из второй вычитаем первую)! 0604: get_Z_angle_for_point 8@ 9@ store_to 10@ // здесь находим угол для первой! точки Object.Angle(0@) = 10@ // применяем
Last edited by mfisto (06-06-2009 15:14)
I know everything and nothing...
Offline
Вот еще справочка по "аркам":
arccos = cos^(-1)
arcsin = sin^(-1)
arctan = tan^(-1)
Специально для тех, кто не умеет читать по английски. Мой ник читается как "ГИР"!!!
Народная мудрость:
Прежде чем задавать вопросы,ПОЧИТАЙ СПРАВКУ!!!!
Offline
аналогично по трем остальным осям составляешь треугольники и также считаешь
как уже было замечено опкод 0604: это не только z_angle но может быть x и y т.к. это вообще просто arctan но с определенными условиями которые я написал в примере
главное это найти расстояния-катеты треугольников, для оси x это будет расстояние по y и по z
а для y соответственно - x и z
в моем же примере было для z по x и y
помоему аналогия вполне очевидно выполняется без особых проблем
I know everything and nothing...
Offline
Все равно хотелось бы наконец сделать нормальные тригинометрические функции в hex. Может, если мозгов хватит, сделаю, насколько я понимаю, надо пользоваться фиговиной, прикрученной к процессору и называемой математическим сопроцессором FPU. Там есть инструкция fpatan для нахождения арктангенса, а через арктангенс можно выразить и остальные арки. Только есть свои сложности, а мои знания ассемблера на уровне "я знаю что такое mov".
Кстати, хотел узнать, откуда принимается результат функцией, вызванной опкодом 0AA7? Из стека или из регистров? Почему-то на большинстве функций, где возвращается через регистр eax, игра вылетает...
И еще вопрос по опкоду 0AA8, кажется он вызывает метод thiscall, то есть передает одним из параметров объект в ecx? В справке как-то туманно написано, без конкретики.
Offline
Pages: 1