MSFD Скрипт по тригонометрии – быстрый синус и косинус
Я попросил JDGBOLT поделиться своим последним, наилучшим тригонометрическим скриптом с читателями MSFD, и я рад представить его здесь.
Хотя он очень длинный, я думаю, этот скрипт будет просто незаменим для любого, кто делает моды включающие тригонометрию, например моды с направленным движением.
Я подправил и прокомментировал скрипт, чтобы каждый смог в нем разобраться.
Благодарите JDGBOLT, если используете этот скрипт!
Скрипт рассчитывает синус и косинус трех углов.
Это обычно углы трех осей объекта, полученные с помощью GetAngle.
Храните эти углы в глобальных переменных
float Z_input_variable
float X_input_variable
float _input_variable
Можно это сделать с другого скрипта на объекте, который вы двигаете.
Затем запускайте скрипт: Startscript jdtrigscript.
Скрипт в этой версии завершит себя сам и поместит результат в следующие глобальные переменные:
Float Z_sin
Float Z_cos
Float X_sin
Float X_cos
Float Y_sin
Float Y_cos
Нужно создать все эти глобальные переменные до того, как вы скомпилируете скрипт.
Скрипт очень быстрый, а результат точный. Результаты будут доступны через один фрейм.
begin jdtrigscript
; от JDGBOLT
; исправлял и от комментировал для MSFD GhanBuriGhan
; одновременный расчет синуса и косинуса для трех углов (например для трех разных осей)
; для промежуточных результатов синуса и косинуса
float ax1
float ax2
float ay1
float ay2
; главная переменная угла
float angle
;временные хранилища угла:
float angle_source ;содержит угол (из глобальной переменной)
float angle_temp
float angle_temp2
short angleshort ; переменная для угла без дроби
float angledec ; для десятичной части угла
short anglequad ;квадрант
float axfinal ; для конечного результата синуса
float ayfinal ; для конечного результата косинуса
float angconvx1 ; для расчета десятичной части синуса и косинуса
float angconvy1
float angconvx2
float angconvy2
short objnum ;счетчик для трех углов
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
while ( objnum <= 3 ) ; этот скрипт рассчитывает синус и косинус для трех углов за один фрейм
;exporting results:
if ( objnum == 1 )
set Z_sin to axfinal ; Z_sin = axfinal для следующей оси
set Z_cos to ayfinal ; ditto
endif
if ( objnum == 2 )
set X_sin to axfinal ;ditto
set X_cos to ayfinal ;ditto
endif
if ( objnum == 3 )
set Y_sin to axfinal ;ditto
set Y_cos to ayfinal ;ditto
;MessageBox "sine of Z: %.3f cosine of Z: %.3f", Z_sin, Z_cos
;MessageBox "sine of X: %.3f cosine of X: %.3f", X_sin, X_cos
;MessageBox "sine of Y: %.3f cosine of Y: %.3f", Y_sin, Y_cos
Set objnum to 0
StopScript jdtrigscript
Return
endif
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
set objnum to ( objnum + 1 ) ;чтобы рассчитать все три угла один за одним
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
; получить углы из глобальных переменных.
if ( objnum == 1 )
set angle_source to Z_input_angle
endif
if ( objnum == 2 )
set angle_source to X_input_angle
endif
if ( objnum == 3 )
set angle_source to Y_input_angle
endif
;GetAngle возвращает значения от -180 до +180, а нужны
;от 0 до 360°C:
if ( angle_source < 0 )
set angle_source to ( 360 + angle_source )
endif
set angle to angle_source
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
;определяем квадрант. Так как нужно узнать синус и косинус для угла 0-90°
if ( angle <= 90 )
set angle_temp2 to angle
set anglequad to 1
elseif ( angle <= 180 )
set angle_temp2 to ( 180 - angle )
set anglequad to 2
elseif ( angle <= 270 )
set angle_temp2 to ( angle - 180 )
set anglequad to 3
elseif ( angle <= 360 )
set angle_temp2 to ( 360 - angle )
set anglequad to 4
endif
; получаем десятичную часть угла
set angleshort to angle_temp2
set angledec to ( angle_temp2 - angleshort ) ; разница между типом float и short
set angle_temp to angleshort
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
; вот значения синуса и косинуса до вычислений:
if ( angle_temp <= 10 ) ; углы организованы с шагом 10 градусов для скорости (и из-за лимита if-блоков?)
if ( angle_temp == 0 )
set ax1 to 0.000000 ; синус
set ay1 to 1.000000 ;косинус
set ax2 to 0.017452 ; синус angletemp+1
set ay2 to 0.999847 ;косинус angletemp+1
elseif ( angle_temp == 1 )
set ax1 to 0.017452
set ay1 to 0.999847
set ax2 to 0.034899
set ay2 to 0.999390
elseif ( angle_temp == 2 )
set ax1 to 0.034899
set ay1 to 0.999390
set ax2 to 0.052333
set ay2 to 0.998629
elseif ( angle_temp == 3 )
set ax1 to 0.052333
set ay1 to 0.998629
set ax2 to 0.069756
set ay2 to 0.997564
elseif ( angle_temp == 4 )
set ax1 to 0.069756
set ay1 to 0.997564
set ax2 to 0.087155
set ay2 to 0.996194
elseif ( angle_temp == 5 )
set ax1 to 0.087155
set ay1 to 0.996194
set ax2 to 0.104528
set ay2 to 0.994521
elseif ( angle_temp == 6 )
set ax1 to 0.104528
set ay1 to 0.994521
set ax2 to 0.121869
set ay2 to 0.992546
elseif ( angle_temp == 7 )
set ax1 to 0.121869
set ay1 to 0.992546
set ax2 to 0.139173
set ay2 to 0.990268
elseif ( angle_temp == 8 )
set ax1 to 0.139173
set ay1 to 0.990268
set ax2 to 0.156434
set ay2 to 0.987688
elseif ( angle_temp == 9 )
set ax1 to 0.156434
set ay1 to 0.987688
set ax2 to 0.173648
set ay2 to 0.984807
elseif ( angle_temp == 10 )
set ax1 to 0.173648
set ay1 to 0.984807
set ax2 to 0.190808
set ay2 to 0.981627
endif
elseif ( angle_temp <= 20 ) ; и так далее…
if ( angle == 11 )
set ax1 to 0.190808
set ay1 to 0.981627
set ax2 to 0.207911
set ay2 to 0.978147
elseif ( angle_temp == 12 )
set ax1 to 0.207911
set ay1 to 0.978147
set ax2 to 0.224951
set ay2 to 0.974370
elseif ( angle_temp == 13 )
set ax1 to 0.224951
set ay1 to 0.974370
set ax2 to 0.241921
set ay2 to 0.970295
elseif ( angle_temp == 14 )
set ax1 to 0.241921
set ay1 to 0.970295
set ax2 to 0.258819
set ay2 to 0.965925
elseif ( angle_temp == 15 )
set ax1 to 0.258819
set ay1 to 0.965925
set ax2 to 0.275637
set ay2 to 0.961261
elseif ( angle_temp == 16 )
set ax1 to 0.275637
set ay1 to 0.961261
set ax2 to 0.292371
set ay2 to 0.956304
elseif ( angle_temp == 17 )
set ax1 to 0.292371
set ay1 to 0.956304
set ax2 to 0.309016
set ay2 to 0.951056
elseif ( angle_temp == 18 )
set ax1 to 0.309016
set ay1 to 0.951056
set ax2 to 0.325568
set ay2 to 0.945518
elseif ( angle_temp == 19 )
set ax1 to 0.325568
set ay1 to 0.945518
set ax2 to 0.342020
set ay2 to 0.939692
elseif ( angle_temp == 20 )
set ax1 to 0.342020
set ay1 to 0.939692
set ax2 to 0.358367
set ay2 to 0.933580
endif
elseif ( angle_temp <= 30 )
if ( angle_temp == 21 )
set ax1 to 0.358367
set ay1 to 0.933580
set ax2 to 0.374606
set ay2 to 0.927183
elseif ( angle_temp == 22 )
set ax1 to 0.374606
set ay1 to 0.927183
set ax2 to 0.390731
set ay2 to 0.920504
elseif ( angle_temp == 23 )
set ax1 to 0.390731
set ay1 to 0.920504
set ax2 to 0.406736
set ay2 to 0.913545
elseif ( angle_temp == 24 )
set ax1 to 0.406736
set ay1 to 0.913545
set ax2 to 0.422618
set ay2 to 0.906307
elseif ( angle_temp == 25 )
set ax1 to 0.422618
set ay1 to 0.906307
set ax2 to 0.438371
set ay2 to 0.898794
elseif ( angle_temp == 26 )
set ax1 to 0.438371
set ay1 to 0.898794
set ax2 to 0.453990
set ay2 to 0.891006
elseif ( angle_temp == 27 )
set ax1 to 0.453990
set ay1 to 0.891006
set ax2 to 0.469471
set ay2 to 0.882947
elseif ( angle_temp == 28 )
set ax1 to 0.469471
set ay1 to 0.882947
set ax2 to 0.484809
set ay2 to 0.874619
elseif ( angle_temp == 29 )
set ax1 to 0.484809
set ay1 to 0.874619
set ax2 to 0.500000
set ay2 to 0.866025
elseif ( angle_temp == 30 )
set ax1 to 0.500000
set ay1 to 0.866025
set ax2 to 0.515038
set ay2 to 0.857167
endif
elseif ( angle_temp <= 40 )
if ( angle_temp == 31 )
set ax1 to 0.515038
set ay1 to 0.857167
set ax2 to 0.529919
set ay2 to 0.848048
elseif ( angle_temp == 32 )
set ax1 to 0.529919
set ay1 to 0.848048
set ax2 to 0.544639
set ay2 to 0.838670
elseif ( angle_temp == 33 )
set ax1 to 0.544639
set ay1 to 0.838670
set ax2 to 0.559192
set ay2 to 0.829037
elseif ( angle_temp == 34 )
set ax1 to 0.559192
set ay1 to 0.829037
set ax2 to 0.573576
set ay2 to 0.819152
elseif ( angle_temp == 35 )
set ax1 to 0.573576
set ay1 to 0.819152
set ax2 to 0.587785
set ay2 to 0.809016
elseif ( angle_temp == 36 )
set ax1 to 0.587785
set ay1 to 0.809016
set ax2 to 0.601815
set ay2 to 0.798635
elseif ( angle_temp == 37 )
set ax1 to 0.601815
set ay1 to 0.798635
set ax2 to 0.615661
set ay2 to 0.788010
elseif ( angle_temp == 38 )
set ax1 to 0.615661
set ay1 to 0.788010
set ax2 to 0.629320
set ay2 to 0.777145
elseif ( angle_temp == 39 )
set ax1 to 0.629320
set ay1 to 0.777145
set ax2 to 0.642787
set ay2 to 0.766044
elseif ( angle_temp == 40 )
set ax1 to 0.642787
set ay1 to 0.766044
set ax2 to 0.656059
set ay2 to 0.754709
endif
elseif ( angle_temp <= 50 )
if ( angle_temp == 41 )
set ax1 to 0.656059
set ay1 to 0.754709
set ax2 to 0.669130
set ay2 to 0.743144
elseif ( angle_temp == 42 )
set ax1 to 0.669130
set ay1 to 0.743144
set ax2 to 0.681998
set ay2 to 0.731353
elseif ( angle_temp == 43 )
set ax1 to 0.681998
set ay1 to 0.731353
set ax2 to 0.694658
set ay2 to 0.719339
elseif ( angle_temp == 44 )
set ax1 to 0.694658
set ay1 to 0.719339
set ax2 to 0.707106
set ay2 to 0.707106
elseif ( angle_temp == 45 )
set ax1 to 0.707106
set ay1 to 0.707106
set ax2 to 0.719339
set ay2 to 0.694658
elseif ( angle_temp == 46 )
set ax1 to 0.719339
set ay1 to 0.694658
set ax2 to 0.731353
set ay2 to 0.681998
elseif ( angle_temp == 47 )
set ax1 to 0.731353
set ay1 to 0.681998
set ax2 to 0.743144
set ay2 to 0.669130
elseif ( angle_temp == 48 )
set ax1 to 0.743144
set ay1 to 0.669130
set ax2 to 0.754709
set ay2 to 0.656059
elseif ( angle_temp == 49 )
set ax1 to 0.754709
set ay1 to 0.656059
set ax2 to 0.766044
set ay2 to 0.642787
elseif ( angle_temp == 50 )
set ax1 to 0.766044
set ay1 to 0.642787
set ax2 to 0.777145
set ay2 to 0.629320
endif
elseif ( angle_temp <= 60 )
if ( angle == 51 )
set ax1 to 0.777145
set ay1 to 0.629320
set ax2 to 0.788010
set ay2 to 0.615661
elseif ( angle_temp == 52 )
set ax1 to 0.788010
set ay1 to 0.615661
set ax2 to 0.798635
set ay2 to 0.601815
elseif ( angle_temp == 53 )
set ax1 to 0.798635
set ay1 to 0.601815
set ax2 to 0.809016
set ay2 to 0.587785
elseif ( angle_temp == 54 )
set ax1 to 0.809016
set ay1 to 0.587785
set ax2 to 0.819152
set ay2 to 0.573576
elseif ( angle_temp == 55 )
set ax1 to 0.819152
set ay1 to 0.573576
set ax2 to 0.829037
set ay2 to 0.559192
elseif ( angle_temp == 56 )
set ax1 to 0.829037
set ay1 to 0.559192
set ax2 to 0.838670
set ay2 to 0.544639
elseif ( angle_temp == 57 )
set ax1 to 0.838670
set ay1 to 0.544639
set ax2 to 0.848048
set ay2 to 0.529919
elseif ( angle_temp == 58 )
set ax1 to 0.848048
set ay1 to 0.529919
set ax2 to 0.857167
set ay2 to 0.515038
elseif ( angle_temp == 59 )
set ax1 to 0.857167
set ay1 to 0.515038
set ax2 to 0.866025
set ay2 to 0.500000
elseif ( angle_temp == 60 )
set ax1 to 0.866025
set ay1 to 0.500000
set ax2 to 0.874619
set ay2 to 0.484809
endif
elseif ( angle_temp <= 70 )
if ( angle_temp == 61 )
set ax1 to 0.874619
set ay1 to 0.484809
set ax2 to 0.882947
set ay2 to 0.469471
elseif ( angle_temp == 62 )
set ax1 to 0.882947
set ay1 to 0.469471
set ax2 to 0.891006
set ay2 to 0.453990
elseif ( angle_temp == 63 )
set ax1 to 0.891006
set ay1 to 0.453990
set ax2 to 0.898794
set ay2 to 0.438371
elseif ( angle_temp == 64 )
set ax1 to 0.898794
set ay1 to 0.438371
set ax2 to 0.906307
set ay2 to 0.422618
elseif ( angle_temp == 65 )
set ax1 to 0.906307
set ay1 to 0.422618
set ax2 to 0.913545
set ay2 to 0.406736
elseif ( angle_temp == 66 )
set ax1 to 0.913545
set ay1 to 0.406736
set ax2 to 0.920504
set ay2 to 0.390731
elseif ( angle_temp == 67 )
set ax1 to 0.920504
set ay1 to 0.390731
set ax2 to 0.927183
set ay2 to 0.374606
elseif ( angle_temp == 68 )
set ax1 to 0.927183
set ay1 to 0.374606
set ax2 to 0.933580
set ay2 to 0.358367
elseif ( angle_temp == 69 )
set ax1 to 0.933580
set ay1 to 0.358367
set ax2 to 0.939692
set ay2 to 0.342020
elseif ( angle_temp == 70 )
set ax1 to 0.939692
set ay1 to 0.342020
set ax2 to 0.945518
set ay2 to 0.325568
endif
elseif ( angle_temp <= 80 )
if ( angle_temp == 71 )
set ax1 to 0.945518
set ay1 to 0.325568
set ax2 to 0.951056
set ay2 to 0.309016
elseif ( angle_temp == 72 )
set ax1 to 0.951056
set ay1 to 0.309016
set ax2 to 0.956304
set ay2 to 0.292371
elseif ( angle_temp == 73 )
set ax1 to 0.956304
set ay1 to 0.292371
set ax2 to 0.961261
set ay2 to 0.275637
elseif ( angle_temp == 74 )
set ax1 to 0.961261
set ay1 to 0.275637
set ax2 to 0.965925
set ay2 to 0.258819
elseif ( angle_temp == 75 )
set ax1 to 0.965925
set ay1 to 0.258819
set ax2 to 0.970295
set ay2 to 0.241921
elseif ( angle_temp == 76 )
set ax1 to 0.970295
set ay1 to 0.241921
set ax2 to 0.974370
set ay2 to 0.224951
elseif ( angle_temp == 77 )
set ax1 to 0.974370
set ay1 to 0.224951
set ax2 to 0.978147
set ay2 to 0.207911
elseif ( angle_temp == 78 )
set ax1 to 0.978147
set ay1 to 0.207911
set ax2 to 0.981627
set ay2 to 0.190808
elseif ( angle_temp == 79 )
set ax1 to 0.981627
set ay1 to 0.190808
set ax2 to 0.984807
set ay2 to 0.173648
elseif ( angle_temp == 80 )
set ax1 to 0.984807
set ay1 to 0.173648
set ax2 to 0.987688
set ay2 to 0.156434
endif
elseif ( angle_temp <= 90 )
if ( angle_temp == 81 )
set ax1 to 0.987688
set ay1 to 0.156434
set ax2 to 0.990268
set ay2 to 0.139173
elseif ( angle_temp == 82 )
set ax1 to 0.990268
set ay1 to 0.139173
set ax2 to 0.992546
set ay2 to 0.121869
elseif ( angle_temp == 83 )
set ax1 to 0.992546
set ay1 to 0.121869
set ax2 to 0.994521
set ay2 to 0.104528
elseif ( angle_temp == 84 )
set ax1 to 0.994521
set ay1 to 0.104528
set ax2 to 0.996194
set ay2 to 0.087155
elseif ( angle_temp == 85 )
set ax1 to 0.996194
set ay1 to 0.087155
set ax2 to 0.997564
set ay2 to 0.069756
elseif ( angle_temp == 86 )
set ax1 to 0.997564
set ay1 to 0.069756
set ax2 to 0.998629
set ay2 to 0.052335
elseif ( angle_temp == 87 )
set ax1 to 0.998629
set ay1 to 0.052335
set ax2 to 0.999390
set ay2 to 0.034899
elseif ( angle_temp == 88 )
set ax1 to 0.999390
set ay1 to 0.034899
set ax2 to 0.999847
set ay2 to 0.017452
elseif ( angle_temp == 89 )
set ax1 to 0.999847
set ay1 to 0.017452
set ax2 to 1.000000
set ay2 to 0.000000
elseif ( angle_temp == 90 )
set ax1 to 1.000000
set ay1 to 0.000000
set ax2 to 0.999847
set ay2 to 0.017452
endif
endif
;используем простую линейную экстраполяцию для приближенного десятичного значения синуса и косинуса:
set angconvx1 to ( ax2 - ax1 ) ; разница между sin(angle) и sin(angle+1)
set angconvy1 to ( ay2 - ay1 ) ; то же для cos
set angconvx2 to ( angconvx1 * angledec ) ;calculate a fraction by the decimal residue
set angconvy2 to ( angconvy1 * angledec ) ; то же для cos
set axfinal to ( ax1 + angconvx2 ) ; окончательный результат result + fraction
set ayfinal to ( ay1 + angconvy2 ) ; окончательный результат result + fraction
;correct for quadrant:
if ( anglequad == 1 )
set axfinal to ( axfinal * 1 ) ; окончательный синус
set ayfinal to ( ayfinal * 1 ) ; окончательный косинус
elseif ( anglequad == 2 )
set axfinal to ( axfinal * 1 ) ; окончательный синус
set ayfinal to ( ayfinal * -1 ) ; окончательный косинус
elseif ( anglequad == 3 )
set axfinal to ( axfinal * -1 ) ; окончательный синус
set ayfinal to ( ayfinal * -1 ) ; окончательный косинус
elseif ( anglequad == 4 )
set axfinal to ( axfinal * -1 ) ; окончательный синус
set ayfinal to ( ayfinal * 1 ) ; окончательный косинус
endif
endwhile ; цикл для трех углов
;-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
end jdtrigscript