[Из песочницы] Как я отказался от вычисления квадратного корня

?v=1

Очень часто, при цифровой обработке сигналов необходимо вычислить длинну вектора, обычно это делается по формуле A=SQR (X^2+Y^2). Здесь возвести в квадрат значение не сложно, но операция вычисления квадратного корня не является простой операцией, особенно для микроконтроллеров. Кроме того, алгоритмы вычисления корня выполняются не стабильное время, и для алгоритмов, которых таких вычислений много, становится сложно прогнозировать время, необходимое для вычислений.

С такой задачей столкнулся и я. О том как я отказался от процедуры вычисления корня, читайте ниже.
Для начала, рассмотрим четыре вектора, они лежат в разных четвертях.

Сведем все в одну четверть — в первую. Для этого возьмем координату Y и если она отрицательная, то превратим ее в положительную. В случае если она и так положительная, то оставим все без изменений.

На самом деле, поскольку у меня абсолютные координаты и значения указаны в целых числах без знака, то вычислим модуль.

Здесь 2047 это виртуальный нуль, поскольку в проекте с которым я работал, когда изобретал этот велосипед, были АЦП 12 бит.

Посмотрим, что произошло.

И сделаем то-же самое для координаты X.

Кстати стоит заметить, что от двух 12ти битных значений, осталось два 11ти битных.

Теперь, все векторы находятся в первой четверти, но ведь их длинна, которую мы ищем, не изменилась.

Следующий этап преобразований: «вывернем вокруг оси 45 градусов».

Векторы могут иметь угол от нуля и до 90 градусов, при этом если в координатах вектора Y>X, то угол вектора лежит в области 45–90 градусов, а если Y

Сведем векторы к 45 градусам.

Если Y>X, то TEMP=Y, Y=X, X=TEMP (меняем X и Y местами).
Если Y<=X, то ничего не делаем.

Смотрим, что произошло. Все векторы лежат в диапозоне углов от 0 и до 45 градусов.

Хочу заметить, что на этом этапе, у меня была идея проверить угол на 22,5 градуса и опять развернуть. А потом сделать проверку и выворачивание на 12,25 градуса. И так, далее, пока вектор не «ляжет» на ось X, а тогда его длинна и будет определяться координатой X, а Y станет равен нулю.

Но, я не пошел этим путем, я сделал ставку на другой метод, и как оказалось в последствии, не прогадал.

Если разделить Y на X, а потом взять арккосинус из этого частного, то получим угол. А если разделить X на косинус этого угла, то получим длину вектора.

Казалось сложно, когда я думал, что надо получать угол по таблице арктангенсов, а потом получать коэффициент по таблице косинусов.

Но все обошлось. Я решил, что можно сразу сделать таблицу, где отношение Y/X адресует ячейку, а в ней «лежит» коэффициент, на который надо разделить X, чтобы получить длинну вектора.

Понятно, что все K, для всех (Y/X), должны быть посчитаны заранее.

Просчитанная таблица содержит 2048 значений, каждое из которых 16 бит. То есть 4кБ данных.

Таблица

Magnitude_Table
DCW 0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800
DCW 0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800
DCW 0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800
DCW 0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800
DCW 0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800
DCW 0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800
DCW 0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800
DCW 0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800,0×0800
DCW 0×0801,0×0801,0×0801,0×0801,0×0801,0×0801,0×0801,0×0801
DCW 0×0801,0×0801,0×0801,0×0801,0×0801,0×0801,0×0801,0×0801
DCW 0×0801,0×0801,0×0801,0×0801,0×0801,0×0801,0×0801,0×0801
DCW 0×0801,0×0801,0×0802,0×0802,0×0802,0×0802,0×0802,0×0802
DCW 0×0802,0×0802,0×0802,0×0802,0×0802,0×0802,0×0802,0×0802
DCW 0×0802,0×0802,0×0802,0×0802,0×0802,0×0802,0×0803,0×0803
DCW 0×0803,0×0803,0×0803,0×0803,0×0803,0×0803,0×0803,0×0803
DCW 0×0803,0×0803,0×0803,0×0803,0×0803,0×0803,0×0803,0×0803
DCW 0×0804,0×0804,0×0804,0×0804,0×0804,0×0804,0×0804,0×0804
DCW 0×0804,0×0804,0×0804,0×0804,0×0804,0×0804,0×0804,0×0805
DCW 0×0805,0×0805,0×0805,0×0805,0×0805,0×0805,0×0805,0×0805
DCW 0×0805,0×0805,0×0805,0×0805,0×0806,0×0806,0×0806,0×0806
DCW 0×0806,0×0806,0×0806,0×0806,0×0806,0×0806,0×0806,0×0806
DCW 0×0806,0×0807,0×0807,0×0807,0×0807,0×0807,0×0807,0×0807
DCW 0×0807,0×0807,0×0807,0×0807,0×0807,0×0808,0×0808,0×0808
DCW 0×0808,0×0808,0×0808,0×0808,0×0808,0×0808,0×0808,0×0808
DCW 0×0809,0×0809,0×0809,0×0809,0×0809,0×0809,0×0809,0×0809
DCW 0×0809,0×0809,0×080A,0×080A,0×080A,0×080A,0×080A,0×080A
DCW 0×080A,0×080A,0×080A,0×080A,0×080B,0×080B,0×080B,0×080B
DCW 0×080B,0×080B,0×080B,0×080B,0×080B,0×080B,0×080C,0×080C
DCW 0×080C,0×080C,0×080C,0×080C,0×080C,0×080C,0×080C,0×080D
DCW 0×080D,0×080D,0×080D,0×080D,0×080D,0×080D,0×080D,0×080E
DCW 0×080E,0×080E,0×080E,0×080E,0×080E,0×080E,0×080E,0×080E
DCW 0×080F,0×080F,0×080F,0×080F,0×080F,0×080F,0×080F,0×080F
DCW 0×0810,0×0810,0×0810,0×0810,0×0810,0×0810,0×0810,0×0810
DCW 0×0811,0×0811,0×0811,0×0811,0×0811,0×0811,0×0811,0×0811
DCW 0×0812,0×0812,0×0812,0×0812,0×0812,0×0812,0×0812,0×0813
DCW 0×0813,0×0813,0×0813,0×0813,0×0813,0×0813,0×0814,0×0814
DCW 0×0814,0×0814,0×0814,0×0814,0×0814,0×0814,0×0815,0×0815
DCW 0×0815,0×0815,0×0815,0×0815,0×0816,0×0816,0×0816,0×0816
DCW 0×0816,0×0816,0×0816,0×0817,0×0817,0×0817,0×0817,0×0817
DCW 0×0817,0×0817,0×0818,0×0818,0×0818,0×0818,0×0818,0×0818
DCW 0×0819,0×0819,0×0819,0×0819,0×0819,0×0819,0×0819,0×081A
DCW 0×081A,0×081A,0×081A,0×081A,0×081A,0×081B,0×081B,0×081B
DCW 0×081B,0×081B,0×081B,0×081C,0×081C,0×081C,0×081C,0×081C
DCW 0×081C,0×081D,0×081D,0×081D,0×081D,0×081D,0×081D,0×081E
DCW 0×081E,0×081E,0×081E,0×081E,0×081E,0×081F,0×081F,0×081F
DCW 0×081F,0×081F,0×081F,0×0820,0×0820,0×0820,0×0820,0×0820
DCW 0×0820,0×0821,0×0821,0×0821,0×0821,0×0821,0×0822,0×0822
DCW 0×0822,0×0822,0×0822,0×0822,0×0823,0×0823,0×0823,0×0823
DCW 0×0823,0×0824,0×0824,0×0824,0×0824,0×0824,0×0824,0×0825
DCW 0×0825,0×0825,0×0825,0×0825,0×0826,0×0826,0×0826,0×0826
DCW 0×0826,0×0827,0×0827,0×0827,0×0827,0×0827,0×0828,0×0828
DCW 0×0828,0×0828,0×0828,0×0829,0×0829,0×0829,0×0829,0×0829
DCW 0×082A,0×082A,0×082A,0×082A,0×082A,0×082B,0×082B,0×082B
DCW 0×082B,0×082B,0×082C,0×082C,0×082C,0×082C,0×082C,0×082D
DCW 0×082D,0×082D,0×082D,0×082D,0×082E,0×082E,0×082E,0×082E
DCW 0×082E,0×082F,0×082F,0×082F,0×082F,0×0830,0×0830,0×0830
DCW 0×0830,0×0830,0×0831,0×0831,0×0831,0×0831,0×0831,0×0832
DCW 0×0832,0×0832,0×0832,0×0833,0×0833,0×0833,0×0833,0×0833
DCW 0×0834,0×0834,0×0834,0×0834,0×0835,0×0835,0×0835,0×0835
DCW 0×0835,0×0836,0×0836,0×0836,0×0836,0×0837,0×0837,0×0837
DCW 0×0837,0×0837,0×0838,0×0838,0×0838,0×0838,0×0839,0×0839
DCW 0×0839,0×0839,0×083A,0×083A,0×083A,0×083A,0×083A,0×083B
DCW 0×083B,0×083B,0×083B,0×083C,0×083C,0×083C,0×083C,0×083D
DCW 0×083D,0×083D,0×083D,0×083E,0×083E,0×083E,0×083E,0×083F
DCW 0×083F,0×083F,0×083F,0×0840,0×0840,0×0840,0×0840,0×0840
DCW 0×0841,0×0841,0×0841,0×0841,0×0842,0×0842,0×0842,0×0842
DCW 0×0843,0×0843,0×0843,0×0843,0×0844,0×0844,0×0844,0×0844
DCW 0×0845,0×0845,0×0845,0×0845,0×0846,0×0846,0×0846,0×0847
DCW 0×0847,0×0847,0×0847,0×0848,0×0848,0×0848,0×0848,0×0849
DCW 0×0849,0×0849,0×0849,0×084A,0×084A,0×084A,0×084A,0×084B
DCW 0×084B,0×084B,0×084B,0×084C,0×084C,0×084C,0×084D,0×084D
DCW 0×084D,0×084D,0×084E,0×084E,0×084E,0×084E,0×084F,0×084F
DCW 0×084F,0×0850,0×0850,0×0850,0×0850,0×0851,0×0851,0×0851
DCW 0×0851,0×0852,0×0852,0×0852,0×0853,0×0853,0×0853,0×0853
DCW 0×0854,0×0854,0×0854,0×0854,0×0855,0×0855,0×0855,0×0856
DCW 0×0856,0×0856,0×0856,0×0857,0×0857,0×0857,0×0858,0×0858
DCW 0×0858,0×0858,0×0859,0×0859,0×0859,0×085A,0×085A,0×085A
DCW 0×085A,0×085B,0×085B,0×085B,0×085C,0×085C,0×085C,0×085C
DCW 0×085D,0×085D,0×085D,0×085E,0×085E,0×085E,0×085F,0×085F
DCW 0×085F,0×085F,0×0860,0×0860,0×0860,0×0861,0×0861,0×0861
DCW 0×0861,0×0862,0×0862,0×0862,0×0863,0×0863,0×0863,0×0864
DCW 0×0864,0×0864,0×0864,0×0865,0×0865,0×0865,0×0866,0×0866
DCW 0×0866,0×0867,0×0867,0×0867,0×0868,0×0868,0×0868,0×0868
DCW 0×0869,0×0869,0×0869,0×086A,0×086A,0×086A,0×086B,0×086B
DCW 0×086B,0×086C,0×086C,0×086C,0×086C,0×086D,0×086D,0×086D
DCW 0×086E,0×086E,0×086E,0×086F,0×086F,0×086F,0×0870,0×0870
DCW 0×0870,0×0871,0×0871,0×0871,0×0872,0×0872,0×0872,0×0873
DCW 0×0873,0×0873,0×0874,0×0874,0×0874,0×0874,0×0875,0×0875
DCW 0×0875,0×0876,0×0876,0×0876,0×0877,0×0877,0×0877,0×0878
DCW 0×0878,0×0878,0×0879,0×0879,0×0879,0×087A,0×087A,0×087A
DCW 0×087B,0×087B,0×087B,0×087C,0×087C,0×087C,0×087D,0×087D
DCW 0×087D,0×087E,0×087E,0×087E,0×087F,0×087F,0×087F,0×0880
DCW 0×0880,0×0880,0×0881,0×0881,0×0881,0×0882,0×0882,0×0882
DCW 0×0883,0×0883,0×0883,0×0884,0×0884,0×0885,0×0885,0×0885
DCW 0×0886,0×0886,0×0886,0×0887,0×0887,0×0887,0×0888,0×0888
DCW 0×0888,0×0889,0×0889,0×0889,0×088A,0×088A,0×088A,0×088B
DCW 0×088B,0×088B,0×088C,0×088C,0×088D,0×088D,0×088D,0×088E
DCW 0×088E,0×088E,0×088F,0×088F,0×088F,0×0890,0×0890,0×0890
DCW 0×0891,0×0891,0×0892,0×0892,0×0892,0×0893,0×0893,0×0893
DCW 0×0894,0×0894,0×0894,0×0895,0×0895,0×0895,0×0896,0×0896
DCW 0×0897,0×0897,0×0897,0×0898,0×0898,0×0898,0×0899,0×0899
DCW 0×0899,0×089A,0×089A,0×089B,0×089B,0×089B,0×089C,0×089C
DCW 0×089C,0×089D,0×089D,0×089E,0×089E,0×089E,0×089F,0×089F
DCW 0×089F,0×08A0,0×08A0,0×08A1,0×08A1,0×08A1,0×08A2,0×08A2
DCW 0×08A2,0×08A3,0×08A3,0×08A4,0×08A4,0×08A4,0×08A5,0×08A5
DCW 0×08A5,0×08A6,0×08A6,0×08A7,0×08A7,0×08A7,0×08A8,0×08A8
DCW 0×08A9,0×08A9,0×08A9,0×08AA,0×08AA,0×08AA,0×08AB,0×08AB
DCW 0×08AC,0×08AC,0×08AC,0×08AD,0×08AD,0×08AE,0×08AE,0×08AE
DCW 0×08AF,0×08AF,0×08AF,0×08B0,0×08B0,0×08B1,0×08B1,0×08B1
DCW 0×08B2,0×08B2,0×08B3,0×08B3,0×08B3,0×08B4,0×08B4,0×08B5
DCW 0×08B5,0×08B5,0×08B6,0×08B6,0×08B7,0×08B7,0×08B7,0×08B8
DCW 0×08B8,0×08B9,0×08B9,0×08B9,0×08BA,0×08BA,0×08BB,0×08BB
DCW 0×08BB,0×08BC,0×08BC,0×08BD,0×08BD,0×08BD,0×08BE,0×08BE
DCW 0×08BF,0×08BF,0×08BF,0×08C0,0×08C0,0×08C1,0×08C1,0×08C1
DCW 0×08C2,0×08C2,0×08C3,0×08C3,0×08C3,0×08C4,0×08C4,0×08C5
DCW 0×08C5,0×08C5,0×08C6,0×08C6,0×08C7,0×08C7,0×08C8,0×08C8
DCW 0×08C8,0×08C9,0×08C9,0×08CA,0×08CA,0×08CA,0×08CB,0×08CB
DCW 0×08CC,0×08CC,0×08CD,0×08CD,0×08CD,0×08CE,0×08CE,0×08CF
DCW 0×08CF,0×08CF,0×08D0,0×08D0,0×08D1,0×08D1,0×08D2,0×08D2
DCW 0×08D2,0×08D3,0×08D3,0×08D4,0×08D4,0×08D4,0×08D5,0×08D5
DCW 0×08D6,0×08D6,0×08D7,0×08D7,0×08D7,0×08D8,0×08D8,0×08D9
DCW 0×08D9,0×08DA,0×08DA,0×08DA,0×08DB,0×08DB,0×08DC,0×08DC
DCW 0×08DD,0×08DD,0×08DD,0×08DE,0×08DE,0×08DF,0×08DF,0×08E0
DCW 0×08E0,0×08E0,0×08E1,0×08E1,0×08E2,0×08E2,0×08E3,0×08E3
DCW 0×08E4,0×08E4,0×08E4,0×08E5,0×08E5,0×08E6,0×08E6,0×08E7
DCW 0×08E7,0×08E7,0×08E8,0×08E8,0×08E9,0×08E9,0×08EA,0×08EA
DCW 0×08EB,0×08EB,0×08EB,0×08EC,0×08EC,0×08ED,0×08ED,0×08EE
DCW 0×08EE,0×08EF,0×08EF,0×08EF,0×08F0,0×08F0,0×08F1,0×08F1
DCW 0×08F2,0×08F2,0×08F3,0×08F3,0×08F3,0×08F4,0×08F4,0×08F5
DCW 0×08F5,0×08F6,0×08F6,0×08F7,0×08F7,0×08F8,0×08F8,0×08F8
DCW 0×08F9,0×08F9,0×08FA,0×08FA,0×08FB,0×08FB,0×08FC,0×08FC
DCW 0×08FD,0×08FD,0×08FD,0×08FE,0×08FE,0×08FF,0×08FF,0×0900
DCW 0×0900,0×0901,0×0901,0×0902,0×0902,0×0902,0×0903,0×0903
DCW 0×0904,0×0904,0×0905,0×0905,0×0906,0×0906,0×0907,0×0907
DCW 0×0908,0×0908,0×0908,0×0909,0×0909,0×090A,0×090A,0×090B
DCW 0×090B,0×090C,0×090C,0×090D,0×090D,0×090E,0×090E,0×090F
DCW 0×090F,0×0910,0×0910,0×0910,0×0911,0×0911,0×0912,0×0912
DCW 0×0913,0×0913,0×0914,0×0914,0×0915,0×0915,0×0916,0×0916
DCW 0×0917,0×0917,0×0918,0×0918,0×0918,0×0919,0×0919,0×091A
DCW 0×091A,0×091B,0×091B,0×091C,0×091C,0×091D,0×091D,0×091E
DCW 0×091E,0×091F,0×091F,0×0920,0×0920,0×0921,0×0921,0×0922
DCW 0×0922,0×0923,0×0923,0×0924,0×0924,0×0924,0×0925,0×0925
DCW 0×0926,0×0926,0×0927,0×0927,0×0928,0×0928,0×0929,0×0929
DCW 0×092A,0×092A,0×092B,0×092B,0×092C,0×092C,0×092D,0×092D
DCW 0×092E,0×092E,0×092F,0×092F,0×0930,0×0930,0×0931,0×0931
DCW 0×0932,0×0932,0×0933,0×0933,0×0934,0×0934,0×0935,0×0935
DCW 0×0936,0×0936,0×0937,0×0937,0×0938,0×0938,0×0939,0×0939
DCW 0×093A,0×093A,0×093B,0×093B,0×093C,0×093C,0×093D,0×093D
DCW 0×093E,0×093E,0×093F,0×093F,0×0940,0×0940,0×0941,0×0941
DCW 0×0942,0×0942,0×0943,0×0943,0×0944,0×0944,0×0945,0×0945
DCW 0×0946,0×0946,0×0947,0×0947,0×0948,0×0948,0×0949,0×0949
DCW 0×094A,0×094A,0×094B,0×094B,0×094C,0×094C,0×094D,0×094D
DCW 0×094E,0×094E,0×094F,0×094F,0×0950,0×0950,0×0951,0×0951
DCW 0×0952,0×0952,0×0953,0×0953,0×0954,0×0954,0×0955,0×0956
DCW 0×0956,0×0957,0×0957,0×0958,0×0958,0×0959,0×0959,0×095A
DCW 0×095A,0×095B,0×095B,0×095C,0×095C,0×095D,0×095D,0×095E
DCW 0×095E,0×095F,0×095F,0×0960,0×0960,0×0961,0×0961,0×0962
DCW 0×0962,0×0963,0×0964,0×0964,0×0965,0×0965,0×0966,0×0966
DCW 0×0967,0×0967,0×0968,0×0968,0×0969,0×0969,0×096A,0×096A
DCW 0×096B,0×096B,0×096C,0×096C,0×096D,0×096E,0×096E,0×096F
DCW 0×096F,0×0970,0×0970,0×0971,0×0971,0×0972,0×0972,0×0973
DCW 0×0973,0×0974,0×0974,0×0975,0×0976,0×0976,0×0977,0×0977
DCW 0×0978,0×0978,0×0979,0×0979,0×097A,0×097A,0×097B,0×097B
DCW 0×097C,0×097C,0×097D,0×097E,0×097E,0×097F,0×097F,0×0980
DCW 0×0980,0×0981,0×0981,0×0982,0×0982,0×0983,0×0983,0×0984
DCW 0×0985,0×0985,0×0986,0×0986,0×0987,0×0987,0×0988,0×0988
DCW 0×0989,0×0989,0×098A,0×098B,0×098B,0×098C,0×098C,0×098D
DCW 0×098D,0×098E,0×098E,0×098F,0×098F,0×0990,0×0991,0×0991
DCW 0×0992,0×0992,0×0993,0×0993,0×0994,0×0994,0×0995,0×0996
DCW 0×0996,0×0997,0×0997,0×0998,0×0998,0×0999,0×0999,0×099A
DCW 0×099A,0×099B,0×099C,0×099C,0×099D,0×099D,0×099E,0×099E
DCW 0×099F,0×099F,0×09A0,0×09A1,0×09A1,0×09A2,0×09A2,0×09A3
DCW 0×09A3,0×09A4,0×09A4,0×09A5,0×09A6,0×09A6,0×09A7,0×09A7
DCW 0×09A8,0×09A8,0×09A9,0×09AA,0×09AA,0×09AB,0×09AB,0×09AC
DCW 0×09AC,0×09AD,0×09AD,0×09AE,0×09AF,0×09AF,0×09B0,0×09B0
DCW 0×09B1,0×09B1,0×09B2,0×09B3,0×09B3,0×09B4,0×09B4,0×09B5
DCW 0×09B5,0×09B6,0×09B7,0×09B7,0×09B8,0×09B8,0×09B9,0×09B9
DCW 0×09BA,0×09BA,0×09BB,0×09BC,0×09BC,0×09BD,0×09BD,0×09BE
DCW 0×09BE,0×09BF,0×09C0,0×09C0,0×09C1,0×09C1,0×09C2,0×09C2
DCW 0×09C3,0×09C4,0×09C4,0×09C5,0×09C5,0×09C6,0×09C7,0×09C7
DCW 0×09C8,0×09C8,0×09C9,0×09C9,0×09CA,0×09CB,0×09CB,0×09CC
DCW 0×09CC,0×09CD,0×09CD,0×09CE,0×09CF,0×09CF,0×09D0,0×09D0
DCW 0×09D1,0×09D1,0×09D2,0×09D3,0×09D3,0×09D4,0×09D4,0×09D5
DCW 0×09D6,0×09D6,0×09D7,0×09D7,0×09D8,0×09D8,0×09D9,0×09DA
DCW 0×09DA,0×09DB,0×09DB,0×09DC,0×09DD,0×09DD,0×09DE,0×09DE
DCW 0×09DF,0×09DF,0×09E0,0×09E1,0×09E1,0×09E2,0×09E2,0×09E3
DCW 0×09E4,0×09E4,0×09E5,0×09E5,0×09E6,0×09E7,0×09E7,0×09E8
DCW 0×09E8,0×09E9,0×09E9,0×09EA,0×09EB,0×09EB,0×09EC,0×09EC
DCW 0×09ED,0×09EE,0×09EE,0×09EF,0×09EF,0×09F0,0×09F1,0×09F1
DCW 0×09F2,0×09F2,0×09F3,0×09F4,0×09F4,0×09F5,0×09F5,0×09F6
DCW 0×09F7,0×09F7,0×09F8,0×09F8,0×09F9,0×09FA,0×09FA,0×09FB
DCW 0×09FB,0×09FC,0×09FD,0×09FD,0×09FE,0×09FE,0×09FF,0×09FF
DCW 0×0A00,0×0A01,0×0A01,0×0A02,0×0A03,0×0A03,0×0A04,0×0A04
DCW 0×0A05,0×0A06,0×0A06,0×0A07,0×0A07,0×0A08,0×0A09,0×0A09
DCW 0×0A0A,0×0A0A,0×0A0B,0×0A0C,0×0A0C,0×0A0D,0×0A0D,0×0A0E
DCW 0×0A0F,0×0A0F,0×0A10,0×0A10,0×0A11,0×0A12,0×0A12,0×0A13
DCW 0×0A13,0×0A14,0×0A15,0×0A15,0×0A16,0×0A16,0×0A17,0×0A18
DCW 0×0A18,0×0A19,0×0A1A,0×0A1A,0×0A1B,0×0A1B,0×0A1C,0×0A1D
DCW 0×0A1D,0×0A1E,0×0A1E,0×0A1F,0×0A20,0×0A20,0×0A21,0×0A21
DCW 0×0A22,0×0A23,0×0A23,0×0A24,0×0A25,0×0A25,0×0A26,0×0A26
DCW 0×0A27,0×0A28,0×0A28,0×0A29,0×0A29,0×0A2A,0×0A2B,0×0A2B
DCW 0×0A2C,0×0A2D,0×0A2D,0×0A2E,0×0A2E,0×0A2F,0×0A30,0×0A30
DCW 0×0A31,0×0A32,0×0A32,0×0A33,0×0A33,0×0A34,0×0A35,0×0A35
DCW 0×0A36,0×0A36,0×0A37,0×0A38,0×0A38,0×0A39,0×0A3A,0×0A3A
DCW 0×0A3B,0×0A3B,0×0A3C,0×0A3D,0×0A3D,0×0A3E,0×0A3F,0×0A3F
DCW 0×0A40,0×0A40,0×0A41,0×0A42,0×0A42,0×0A43,0×0A44,0×0A44
DCW 0×0A45,0×0A45,0×0A46,0×0A47,0×0A47,0×0A48,0×0A49,0×0A49
DCW 0×0A4A,0×0A4B,0×0A4B,0×0A4C,0×0A4C,0×0A4D,0×0A4E,0×0A4E
DCW 0×0A4F,0×0A50,0×0A50,0×0A51,0×0A51,0×0A52,0×0A53,0×0A53
DCW 0×0A54,0×0A55,0×0A55,0×0A56,0×0A57,0×0A57,0×0A58,0×0A58
DCW 0×0A59,0×0A5A,0×0A5A,0×0A5B,0×0A5C,0×0A5C,0×0A5D,0×0A5D
DCW 0×0A5E,0×0A5F,0×0A5F,0×0A60,0×0A61,0×0A61,0×0A62,0×0A63
DCW 0×0A63,0×0A64,0×0A64,0×0A65,0×0A66,0×0A66,0×0A67,0×0A68
DCW 0×0A68,0×0A69,0×0A6A,0×0A6A,0×0A6B,0×0A6C,0×0A6C,0×0A6D
DCW 0×0A6D,0×0A6E,0×0A6F,0×0A6F,0×0A70,0×0A71,0×0A71,0×0A72
DCW 0×0A73,0×0A73,0×0A74,0×0A75,0×0A75,0×0A76,0×0A76,0×0A77
DCW 0×0A78,0×0A78,0×0A79,0×0A7A,0×0A7A,0×0A7B,0×0A7C,0×0A7C
DCW 0×0A7D,0×0A7E,0×0A7E,0×0A7F,0×0A80,0×0A80,0×0A81,0×0A81
DCW 0×0A82,0×0A83,0×0A83,0×0A84,0×0A85,0×0A85,0×0A86,0×0A87
DCW 0×0A87,0×0A88,0×0A89,0×0A89,0×0A8A,0×0A8B,0×0A8B,0×0A8C
DCW 0×0A8D,0×0A8D,0×0A8E,0×0A8E,0×0A8F,0×0A90,0×0A90,0×0A91
DCW 0×0A92,0×0A92,0×0A93,0×0A94,0×0A94,0×0A95,0×0A96,0×0A96
DCW 0×0A97,0×0A98,0×0A98,0×0A99,0×0A9A,0×0A9A,0×0A9B,0×0A9C
DCW 0×0A9C,0×0A9D,0×0A9E,0×0A9E,0×0A9F,0×0AA0,0×0AA0,0×0AA1
DCW 0×0AA1,0×0AA2,0×0AA3,0×0AA3,0×0AA4,0×0AA5,0×0AA5,0×0AA6
DCW 0×0AA7,0×0AA7,0×0AA8,0×0AA9,0×0AA9,0×0AAA,0×0AAB,0×0AAB
DCW 0×0AAC,0×0AAD,0×0AAD,0×0AAE,0×0AAF,0×0AAF,0×0AB0,0×0AB1
DCW 0×0AB1,0×0AB2,0×0AB3,0×0AB3,0×0AB4,0×0AB5,0×0AB5,0×0AB6
DCW 0×0AB7,0×0AB7,0×0AB8,0×0AB9,0×0AB9,0×0ABA,0×0ABB,0×0ABB
DCW 0×0ABC,0×0ABD,0×0ABD,0×0ABE,0×0ABF,0×0ABF,0×0AC0,0×0AC1
DCW 0×0AC1,0×0AC2,0×0AC3,0×0AC3,0×0AC4,0×0AC5,0×0AC5,0×0AC6
DCW 0×0AC7,0×0AC7,0×0AC8,0×0AC9,0×0AC9,0×0ACA,0×0ACB,0×0ACB
DCW 0×0ACC,0×0ACD,0×0ACD,0×0ACE,0×0ACF,0×0ACF,0×0AD0,0×0AD1
DCW 0×0AD1,0×0AD2,0×0AD3,0×0AD3,0×0AD4,0×0AD5,0×0AD5,0×0AD6
DCW 0×0AD7,0×0AD8,0×0AD8,0×0AD9,0×0ADA,0×0ADA,0×0ADB,0×0ADC
DCW 0×0ADC,0×0ADD,0×0ADE,0×0ADE,0×0ADF,0×0AE0,0×0AE0,0×0AE1
DCW 0×0AE2,0×0AE2,0×0AE3,0×0AE4,0×0AE4,0×0AE5,0×0AE6,0×0AE6
DCW 0×0AE7,0×0AE8,0×0AE8,0×0AE9,0×0AEA,0×0AEA,0×0AEB,0×0AEC
DCW 0×0AED,0×0AED,0×0AEE,0×0AEF,0×0AEF,0×0AF0,0×0AF1,0×0AF1
DCW 0×0AF2,0×0AF3,0×0AF3,0×0AF4,0×0AF5,0×0AF5,0×0AF6,0×0AF7
DCW 0×0AF7,0×0AF8,0×0AF9,0×0AF9,0×0AFA,0×0AFB,0×0AFC,0×0AFC
DCW 0×0AFD,0×0AFE,0×0AFE,0×0AFF,0×0B00,0×0B00,0×0B01,0×0B02
DCW 0×0B02,0×0B03,0×0B04,0×0B04,0×0B05,0×0B06,0×0B07,0×0B07
DCW 0×0B08,0×0B09,0×0B09,0×0B0A,0×0B0B,0×0B0B,0×0B0C,0×0B0D
DCW 0×0B0D,0×0B0E,0×0B0F,0×0B10,0×0B10,0×0B11,0×0B12,0×0B12
DCW 0×0B13,0×0B14,0×0B14,0×0B15,0×0B16,0×0B16,0×0B17,0×0B18
DCW 0×0B18,0×0B19,0×0B1A,0×0B1B,0×0B1B,0×0B1C,0×0B1D,0×0B1D
DCW 0×0B1E,0×0B1F,0×0B1F,0×0B20,0×0B21,0×0B22,0×0B22,0×0B23
DCW 0×0B24,0×0B24,0×0B25,0×0B26,0×0B26,0×0B27,0×0B28,0×0B28
DCW 0×0B29,0×0B2A,0×0B2B,0×0B2B,0×0B2C,0×0B2D,0×0B2D,0×0B2E
DCW 0×0B2F,0×0B2F,0×0B30,0×0B31,0×0B32,0×0B32,0×0B33,0×0B34
DCW 0×0B34,0×0B35,0×0B36,0×0B36,0×0B37,0×0B38,0×0B39,0×0B39
DCW 0×0B3A,0×0B3B,0×0B3B,0×0B3C,0×0B3D,0×0B3D,0×0B3E,0×0B3F
DCW 0×0B40,0×0B40,0×0B41,0×0B42,0×0B42,0×0B43,0×0B44,0×0B45
DCW 0×0B45,0×0B46,0×0B47,0×0B47,0×0B48,0×0B49,0×0B49,0×0B4A
DCW 0×0B4B,0×0B4C,0×0B4C,0×0B4D,0×0B4E,0×0B4E,0×0B4F,0×0B50

Младшее значение 0×800h, что означает 2048. Cтаршее 0xB50, и оно означает 2896.

2896/2048 = 1.414, что соответствует 1/cos (45).

Для получения индекса массива, необходимо умножить Y на 2048 и разделить на Х.

Полученный индекс укажет на ячейку массива, из этой ячейки извлекаем значение, умножаем X на него и делим на 2048. Полученный результат есть длинна вектора.

Хочу заметить, что деление и умножение на 2048 выполняется сдвигом, и еще одно деление и умножение выполняется специальными командами или алгоритмами, если в используемой платформе нет команд умножения и/или деления.

В моем случае, применялся микроконтроллер STM32F103, который имел команды деления и умножения.

Подведем итог алгоритма.

Получившаяся программа на языке ассемблер для STM32F103.

Приведу пример работы алгоритма в сравнении с классическим методом для двух из четырех векторов, которые показаны на изображениях выше.

Возьмем синий вектор (из третьей области).

Его координаты X=-45, Y=-126 (можно проверить по пикселям)

(-45)^2+(-126)^2=2025+15876=17901
SQR (17901)=133 (усечено до целого)

пункт 1: 2002>2047? → нет. X=2047–2002=45
пункт 2: 1921>2047? → нет. Y=2047–1921=126
пункт 3: 126>45 → да. меняем местами X=126, Y=45
пункт 4: X=0 → нет. продолжаем
пункт 5: Y=Y*2048, Y=45×2048=92160
пункт 6: I=Y/X, I=92160/126=731
Пункт 7: в таблице 255 строк по 8 значений, ищем 731е значение.
Это 91я строка и 3е значение, которое равно 0×087e, или 2174 в десятичном
виде.
Пункт 8: X=X*2174, X=126×2174=273924
Пункт 9: A=X/2048, A=273924/2048=133 (усечено до целого)

Ч.Т. Д.

Теперь возьмем зеленый вектор (из четвертой области).

Его координаты X=-170, Y=95 (можно проверить по пикселям).

(-170)^2+(95)^2=28900+9025=37925
SQR (37925)=194 (усечено до целого)

пункт 1: 1877>2047? → нет. X=2047–1877=170
пункт 2: 2142>2047? → да. Y=2142–2047=95
пункт 3: 95>170 → нет. оставляем как есть.
пункт 4: X=0 → нет. продолжаем
пункт 5: Y=Y*2048, Y=95×2048=194560
пункт 6: I=Y/X, I=194560/170=1144
Пункт 7: в таблице ищем 1144е значение.
Это 143я строка и 0е значение, которое равно 0×092A, или 2346 в десятичном виде.
Пункт 8: X=X*2346, X=170×2346=398820
Пункт 9: A=X/2048, A=398820/2048=194 (усечено до целого)

Ч.Т. Д.

Подобный алгоритм можно использовать в ЦОС (как я), например, можно заметно ускорить Быстрое Преобразование Фурье. Также можно использовать в компьютерной графике, где используется трассировка лучей. Возможно и еще есть применение.

На этом все. Спасибо за внимание.

© Habrahabr.ru