| /* |
| * Twin - A Tiny Window System |
| * Copyright © 2004 Keith Packard <keithp@keithp.com> |
| * All rights reserved. |
| * |
| * This Library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Library General Public License as |
| * published by the Free Software Foundation; either version 2 of the |
| * License, or (at your option) any later version. |
| * |
| * This Library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Library General Public License for more details. |
| * |
| * You should have received a copy of the GNU Library General Public |
| * License along with the Twin Library; see the file COPYING. If not, |
| * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
| * Boston, MA 02111-1307, USA. |
| */ |
| |
| #include "twinint.h" |
| |
| #define TWIN_LOG2_SIN 10 |
| |
| /* |
| * construction: |
| int s = 10; for (int i = 0; i < (1 << s); i++) { |
| if (i % 8 == 0) printf ("\n "); |
| printf (" 0x%04x,", floor (sin(pi/2 * i / (1 << s)) * 2**16 + 0.5)); |
| } |
| */ |
| |
| static const uint16_t _twin_sin_table[1 << TWIN_LOG2_SIN] = { |
| 0x0000, 0x0065, 0x00c9, 0x012e, 0x0192, 0x01f7, 0x025b, 0x02c0, |
| 0x0324, 0x0389, 0x03ed, 0x0452, 0x04b6, 0x051b, 0x057f, 0x05e4, |
| 0x0648, 0x06ad, 0x0711, 0x0776, 0x07da, 0x083f, 0x08a3, 0x0908, |
| 0x096c, 0x09d1, 0x0a35, 0x0a9a, 0x0afe, 0x0b62, 0x0bc7, 0x0c2b, |
| 0x0c90, 0x0cf4, 0x0d59, 0x0dbd, 0x0e21, 0x0e86, 0x0eea, 0x0f4e, |
| 0x0fb3, 0x1017, 0x107b, 0x10e0, 0x1144, 0x11a8, 0x120d, 0x1271, |
| 0x12d5, 0x1339, 0x139e, 0x1402, 0x1466, 0x14ca, 0x152e, 0x1593, |
| 0x15f7, 0x165b, 0x16bf, 0x1723, 0x1787, 0x17eb, 0x1850, 0x18b4, |
| 0x1918, 0x197c, 0x19e0, 0x1a44, 0x1aa8, 0x1b0c, 0x1b70, 0x1bd4, |
| 0x1c38, 0x1c9b, 0x1cff, 0x1d63, 0x1dc7, 0x1e2b, 0x1e8f, 0x1ef3, |
| 0x1f56, 0x1fba, 0x201e, 0x2082, 0x20e5, 0x2149, 0x21ad, 0x2210, |
| 0x2274, 0x22d7, 0x233b, 0x239f, 0x2402, 0x2466, 0x24c9, 0x252d, |
| 0x2590, 0x25f4, 0x2657, 0x26ba, 0x271e, 0x2781, 0x27e4, 0x2848, |
| 0x28ab, 0x290e, 0x2971, 0x29d5, 0x2a38, 0x2a9b, 0x2afe, 0x2b61, |
| 0x2bc4, 0x2c27, 0x2c8a, 0x2ced, 0x2d50, 0x2db3, 0x2e16, 0x2e79, |
| 0x2edc, 0x2f3f, 0x2fa1, 0x3004, 0x3067, 0x30ca, 0x312c, 0x318f, |
| 0x31f1, 0x3254, 0x32b7, 0x3319, 0x337c, 0x33de, 0x3440, 0x34a3, |
| 0x3505, 0x3568, 0x35ca, 0x362c, 0x368e, 0x36f1, 0x3753, 0x37b5, |
| 0x3817, 0x3879, 0x38db, 0x393d, 0x399f, 0x3a01, 0x3a63, 0x3ac5, |
| 0x3b27, 0x3b88, 0x3bea, 0x3c4c, 0x3cae, 0x3d0f, 0x3d71, 0x3dd2, |
| 0x3e34, 0x3e95, 0x3ef7, 0x3f58, 0x3fba, 0x401b, 0x407c, 0x40de, |
| 0x413f, 0x41a0, 0x4201, 0x4262, 0x42c3, 0x4324, 0x4385, 0x43e6, |
| 0x4447, 0x44a8, 0x4509, 0x456a, 0x45cb, 0x462b, 0x468c, 0x46ec, |
| 0x474d, 0x47ae, 0x480e, 0x486f, 0x48cf, 0x492f, 0x4990, 0x49f0, |
| 0x4a50, 0x4ab0, 0x4b10, 0x4b71, 0x4bd1, 0x4c31, 0x4c90, 0x4cf0, |
| 0x4d50, 0x4db0, 0x4e10, 0x4e70, 0x4ecf, 0x4f2f, 0x4f8e, 0x4fee, |
| 0x504d, 0x50ad, 0x510c, 0x516c, 0x51cb, 0x522a, 0x5289, 0x52e8, |
| 0x5348, 0x53a7, 0x5406, 0x5464, 0x54c3, 0x5522, 0x5581, 0x55e0, |
| 0x563e, 0x569d, 0x56fc, 0x575a, 0x57b9, 0x5817, 0x5875, 0x58d4, |
| 0x5932, 0x5990, 0x59ee, 0x5a4c, 0x5aaa, 0x5b08, 0x5b66, 0x5bc4, |
| 0x5c22, 0x5c80, 0x5cde, 0x5d3b, 0x5d99, 0x5df6, 0x5e54, 0x5eb1, |
| 0x5f0f, 0x5f6c, 0x5fc9, 0x6026, 0x6084, 0x60e1, 0x613e, 0x619b, |
| 0x61f8, 0x6254, 0x62b1, 0x630e, 0x636b, 0x63c7, 0x6424, 0x6480, |
| 0x64dd, 0x6539, 0x6595, 0x65f2, 0x664e, 0x66aa, 0x6706, 0x6762, |
| 0x67be, 0x681a, 0x6876, 0x68d1, 0x692d, 0x6989, 0x69e4, 0x6a40, |
| 0x6a9b, 0x6af6, 0x6b52, 0x6bad, 0x6c08, 0x6c63, 0x6cbe, 0x6d19, |
| 0x6d74, 0x6dcf, 0x6e2a, 0x6e85, 0x6edf, 0x6f3a, 0x6f94, 0x6fef, |
| 0x7049, 0x70a3, 0x70fe, 0x7158, 0x71b2, 0x720c, 0x7266, 0x72c0, |
| 0x731a, 0x7373, 0x73cd, 0x7427, 0x7480, 0x74da, 0x7533, 0x758d, |
| 0x75e6, 0x763f, 0x7698, 0x76f1, 0x774a, 0x77a3, 0x77fc, 0x7855, |
| 0x78ad, 0x7906, 0x795f, 0x79b7, 0x7a10, 0x7a68, 0x7ac0, 0x7b18, |
| 0x7b70, 0x7bc8, 0x7c20, 0x7c78, 0x7cd0, 0x7d28, 0x7d7f, 0x7dd7, |
| 0x7e2f, 0x7e86, 0x7edd, 0x7f35, 0x7f8c, 0x7fe3, 0x803a, 0x8091, |
| 0x80e8, 0x813f, 0x8195, 0x81ec, 0x8243, 0x8299, 0x82f0, 0x8346, |
| 0x839c, 0x83f2, 0x8449, 0x849f, 0x84f5, 0x854a, 0x85a0, 0x85f6, |
| 0x864c, 0x86a1, 0x86f7, 0x874c, 0x87a1, 0x87f6, 0x884c, 0x88a1, |
| 0x88f6, 0x894a, 0x899f, 0x89f4, 0x8a49, 0x8a9d, 0x8af2, 0x8b46, |
| 0x8b9a, 0x8bef, 0x8c43, 0x8c97, 0x8ceb, 0x8d3f, 0x8d93, 0x8de6, |
| 0x8e3a, 0x8e8d, 0x8ee1, 0x8f34, 0x8f88, 0x8fdb, 0x902e, 0x9081, |
| 0x90d4, 0x9127, 0x9179, 0x91cc, 0x921f, 0x9271, 0x92c4, 0x9316, |
| 0x9368, 0x93ba, 0x940c, 0x945e, 0x94b0, 0x9502, 0x9554, 0x95a5, |
| 0x95f7, 0x9648, 0x969a, 0x96eb, 0x973c, 0x978d, 0x97de, 0x982f, |
| 0x9880, 0x98d0, 0x9921, 0x9972, 0x99c2, 0x9a12, 0x9a63, 0x9ab3, |
| 0x9b03, 0x9b53, 0x9ba3, 0x9bf2, 0x9c42, 0x9c92, 0x9ce1, 0x9d31, |
| 0x9d80, 0x9dcf, 0x9e1e, 0x9e6d, 0x9ebc, 0x9f0b, 0x9f5a, 0x9fa8, |
| 0x9ff7, 0xa045, 0xa094, 0xa0e2, 0xa130, 0xa17e, 0xa1cc, 0xa21a, |
| 0xa268, 0xa2b5, 0xa303, 0xa350, 0xa39e, 0xa3eb, 0xa438, 0xa485, |
| 0xa4d2, 0xa51f, 0xa56c, 0xa5b8, 0xa605, 0xa652, 0xa69e, 0xa6ea, |
| 0xa736, 0xa782, 0xa7ce, 0xa81a, 0xa866, 0xa8b2, 0xa8fd, 0xa949, |
| 0xa994, 0xa9df, 0xaa2a, 0xaa76, 0xaac1, 0xab0b, 0xab56, 0xaba1, |
| 0xabeb, 0xac36, 0xac80, 0xacca, 0xad14, 0xad5e, 0xada8, 0xadf2, |
| 0xae3c, 0xae85, 0xaecf, 0xaf18, 0xaf62, 0xafab, 0xaff4, 0xb03d, |
| 0xb086, 0xb0ce, 0xb117, 0xb160, 0xb1a8, 0xb1f0, 0xb239, 0xb281, |
| 0xb2c9, 0xb311, 0xb358, 0xb3a0, 0xb3e8, 0xb42f, 0xb477, 0xb4be, |
| 0xb505, 0xb54c, 0xb593, 0xb5da, 0xb620, 0xb667, 0xb6ad, 0xb6f4, |
| 0xb73a, 0xb780, 0xb7c6, 0xb80c, 0xb852, 0xb898, 0xb8dd, 0xb923, |
| 0xb968, 0xb9ae, 0xb9f3, 0xba38, 0xba7d, 0xbac1, 0xbb06, 0xbb4b, |
| 0xbb8f, 0xbbd4, 0xbc18, 0xbc5c, 0xbca0, 0xbce4, 0xbd28, 0xbd6b, |
| 0xbdaf, 0xbdf2, 0xbe36, 0xbe79, 0xbebc, 0xbeff, 0xbf42, 0xbf85, |
| 0xbfc7, 0xc00a, 0xc04c, 0xc08f, 0xc0d1, 0xc113, 0xc155, 0xc197, |
| 0xc1d8, 0xc21a, 0xc25c, 0xc29d, 0xc2de, 0xc31f, 0xc360, 0xc3a1, |
| 0xc3e2, 0xc423, 0xc463, 0xc4a4, 0xc4e4, 0xc524, 0xc564, 0xc5a4, |
| 0xc5e4, 0xc624, 0xc663, 0xc6a3, 0xc6e2, 0xc721, 0xc761, 0xc7a0, |
| 0xc7de, 0xc81d, 0xc85c, 0xc89a, 0xc8d9, 0xc917, 0xc955, 0xc993, |
| 0xc9d1, 0xca0f, 0xca4d, 0xca8a, 0xcac7, 0xcb05, 0xcb42, 0xcb7f, |
| 0xcbbc, 0xcbf9, 0xcc35, 0xcc72, 0xccae, 0xcceb, 0xcd27, 0xcd63, |
| 0xcd9f, 0xcddb, 0xce17, 0xce52, 0xce8e, 0xcec9, 0xcf04, 0xcf3f, |
| 0xcf7a, 0xcfb5, 0xcff0, 0xd02a, 0xd065, 0xd09f, 0xd0d9, 0xd113, |
| 0xd14d, 0xd187, 0xd1c1, 0xd1fa, 0xd234, 0xd26d, 0xd2a6, 0xd2df, |
| 0xd318, 0xd351, 0xd38a, 0xd3c2, 0xd3fb, 0xd433, 0xd46b, 0xd4a3, |
| 0xd4db, 0xd513, 0xd54b, 0xd582, 0xd5ba, 0xd5f1, 0xd628, 0xd65f, |
| 0xd696, 0xd6cd, 0xd703, 0xd73a, 0xd770, 0xd7a6, 0xd7dc, 0xd812, |
| 0xd848, 0xd87e, 0xd8b4, 0xd8e9, 0xd91e, 0xd954, 0xd989, 0xd9be, |
| 0xd9f2, 0xda27, 0xda5c, 0xda90, 0xdac4, 0xdaf8, 0xdb2c, 0xdb60, |
| 0xdb94, 0xdbc8, 0xdbfb, 0xdc2f, 0xdc62, 0xdc95, 0xdcc8, 0xdcfb, |
| 0xdd2d, 0xdd60, 0xdd92, 0xddc5, 0xddf7, 0xde29, 0xde5b, 0xde8c, |
| 0xdebe, 0xdef0, 0xdf21, 0xdf52, 0xdf83, 0xdfb4, 0xdfe5, 0xe016, |
| 0xe046, 0xe077, 0xe0a7, 0xe0d7, 0xe107, 0xe137, 0xe167, 0xe196, |
| 0xe1c6, 0xe1f5, 0xe224, 0xe253, 0xe282, 0xe2b1, 0xe2df, 0xe30e, |
| 0xe33c, 0xe36b, 0xe399, 0xe3c7, 0xe3f4, 0xe422, 0xe450, 0xe47d, |
| 0xe4aa, 0xe4d7, 0xe504, 0xe531, 0xe55e, 0xe58b, 0xe5b7, 0xe5e3, |
| 0xe610, 0xe63c, 0xe667, 0xe693, 0xe6bf, 0xe6ea, 0xe716, 0xe741, |
| 0xe76c, 0xe797, 0xe7c2, 0xe7ec, 0xe817, 0xe841, 0xe86b, 0xe895, |
| 0xe8bf, 0xe8e9, 0xe913, 0xe93c, 0xe966, 0xe98f, 0xe9b8, 0xe9e1, |
| 0xea0a, 0xea32, 0xea5b, 0xea83, 0xeaab, 0xead4, 0xeafc, 0xeb23, |
| 0xeb4b, 0xeb73, 0xeb9a, 0xebc1, 0xebe8, 0xec0f, 0xec36, 0xec5d, |
| 0xec83, 0xecaa, 0xecd0, 0xecf6, 0xed1c, 0xed42, 0xed68, 0xed8d, |
| 0xedb3, 0xedd8, 0xedfd, 0xee22, 0xee47, 0xee6b, 0xee90, 0xeeb4, |
| 0xeed9, 0xeefd, 0xef21, 0xef45, 0xef68, 0xef8c, 0xefaf, 0xefd2, |
| 0xeff5, 0xf018, 0xf03b, 0xf05e, 0xf080, 0xf0a3, 0xf0c5, 0xf0e7, |
| 0xf109, 0xf12b, 0xf14c, 0xf16e, 0xf18f, 0xf1b1, 0xf1d2, 0xf1f3, |
| 0xf213, 0xf234, 0xf254, 0xf275, 0xf295, 0xf2b5, 0xf2d5, 0xf2f5, |
| 0xf314, 0xf334, 0xf353, 0xf372, 0xf391, 0xf3b0, 0xf3cf, 0xf3ed, |
| 0xf40c, 0xf42a, 0xf448, 0xf466, 0xf484, 0xf4a2, 0xf4bf, 0xf4dd, |
| 0xf4fa, 0xf517, 0xf534, 0xf551, 0xf56e, 0xf58a, 0xf5a6, 0xf5c3, |
| 0xf5df, 0xf5fb, 0xf616, 0xf632, 0xf64e, 0xf669, 0xf684, 0xf69f, |
| 0xf6ba, 0xf6d5, 0xf6ef, 0xf70a, 0xf724, 0xf73e, 0xf758, 0xf772, |
| 0xf78c, 0xf7a5, 0xf7bf, 0xf7d8, 0xf7f1, 0xf80a, 0xf823, 0xf83b, |
| 0xf854, 0xf86c, 0xf885, 0xf89d, 0xf8b4, 0xf8cc, 0xf8e4, 0xf8fb, |
| 0xf913, 0xf92a, 0xf941, 0xf958, 0xf96e, 0xf985, 0xf99b, 0xf9b2, |
| 0xf9c8, 0xf9de, 0xf9f3, 0xfa09, 0xfa1f, 0xfa34, 0xfa49, 0xfa5e, |
| 0xfa73, 0xfa88, 0xfa9c, 0xfab1, 0xfac5, 0xfad9, 0xfaed, 0xfb01, |
| 0xfb15, 0xfb28, 0xfb3c, 0xfb4f, 0xfb62, 0xfb75, 0xfb88, 0xfb9a, |
| 0xfbad, 0xfbbf, 0xfbd1, 0xfbe3, 0xfbf5, 0xfc07, 0xfc18, 0xfc2a, |
| 0xfc3b, 0xfc4c, 0xfc5d, 0xfc6e, 0xfc7f, 0xfc8f, 0xfca0, 0xfcb0, |
| 0xfcc0, 0xfcd0, 0xfcdf, 0xfcef, 0xfcfe, 0xfd0e, 0xfd1d, 0xfd2c, |
| 0xfd3b, 0xfd49, 0xfd58, 0xfd66, 0xfd74, 0xfd83, 0xfd90, 0xfd9e, |
| 0xfdac, 0xfdb9, 0xfdc7, 0xfdd4, 0xfde1, 0xfdee, 0xfdfa, 0xfe07, |
| 0xfe13, 0xfe1f, 0xfe2b, 0xfe37, 0xfe43, 0xfe4f, 0xfe5a, 0xfe66, |
| 0xfe71, 0xfe7c, 0xfe87, 0xfe91, 0xfe9c, 0xfea6, 0xfeb0, 0xfeba, |
| 0xfec4, 0xfece, 0xfed8, 0xfee1, 0xfeeb, 0xfef4, 0xfefd, 0xff06, |
| 0xff0e, 0xff17, 0xff1f, 0xff28, 0xff30, 0xff38, 0xff3f, 0xff47, |
| 0xff4e, 0xff56, 0xff5d, 0xff64, 0xff6b, 0xff71, 0xff78, 0xff7e, |
| 0xff85, 0xff8b, 0xff91, 0xff96, 0xff9c, 0xffa2, 0xffa7, 0xffac, |
| 0xffb1, 0xffb6, 0xffbb, 0xffbf, 0xffc4, 0xffc8, 0xffcc, 0xffd0, |
| 0xffd4, 0xffd7, 0xffdb, 0xffde, 0xffe1, 0xffe4, 0xffe7, 0xffea, |
| 0xffec, 0xffef, 0xfff1, 0xfff3, 0xfff5, 0xfff7, 0xfff8, 0xfffa, |
| 0xfffb, 0xfffc, 0xfffd, 0xfffe, 0xffff, 0xffff, 0xffff, 0xffff, |
| }; |
| |
| /* |
| * angles are measured from -2048 .. 2048 |
| */ |
| |
| #if 0 |
| #include <stdio.h> |
| #define twin_angle_to_double(x) ((x) * 180.0 / TWIN_ANGLE_180) |
| #define A(x) twin_angle_to_double(x) |
| #define F(x) twin_fixed_to_double(x) |
| #define DBGMSG(x) printf x |
| #else |
| #define DBGMSG(x) |
| #endif |
| |
| twin_fixed_t |
| twin_sin (twin_angle_t a) |
| { |
| twin_fixed_t sin; |
| |
| /* limit to [0..360) */ |
| a = a & (TWIN_ANGLE_360 - 1); |
| /* special case for 90 degrees - no room in table */ |
| if ((a & ~(TWIN_ANGLE_180)) == TWIN_ANGLE_90) |
| sin = TWIN_FIXED_ONE; |
| else { |
| /* mirror second and third quadrant values across y axis */ |
| if (a & TWIN_ANGLE_90) |
| a = TWIN_ANGLE_180 - a; |
| sin = _twin_sin_table[a & (TWIN_ANGLE_90 - 1)]; |
| } |
| /* mirror third and fourth quadrant values across x axis */ |
| if (a & TWIN_ANGLE_180) |
| sin = -sin; |
| DBGMSG (("angle: %9.4f sin: %9.6f\n", A(a), F(sin))); |
| return sin; |
| } |
| |
| twin_fixed_t |
| twin_cos (twin_angle_t a) |
| { |
| return twin_sin (a + TWIN_ANGLE_90); |
| } |
| |
| twin_fixed_t |
| twin_tan (twin_angle_t a) |
| { |
| twin_fixed_t s = twin_sin (a); |
| twin_fixed_t c = twin_cos (a); |
| |
| if (c == 0) |
| { |
| if (s > 0) |
| return TWIN_FIXED_MAX; |
| else |
| return TWIN_FIXED_MIN; |
| } |
| if (s == 0) |
| return 0; |
| return ((s << 15) / c) << 1; |
| } |