1 |
//-------------------------------------------------------------------------------
|
2 |
//$Header: /home/dashley/cvsrep/uculib01/uculib01/src/stm8/cosmic/modxx/atatanix100odegx1rrxx/src/atatanix100odegx1rrxx.c,v 1.4 2010/02/20 02:20:38 dashley Exp $
|
3 |
//-------------------------------------------------------------------------------
|
4 |
//Copyright (c)2010 David T. Ashley
|
5 |
//
|
6 |
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 |
//of this software source code and associated documentation files (the
|
8 |
//"Software"), to deal in the Software without restriction, including without
|
9 |
//limitation the rights to use, copy, modify, merge, publish, distribute,
|
10 |
//sublicense, and/or sell copies of the Software, and to permit persons to whom
|
11 |
//the Software is furnished to do so, subject to the following conditions:
|
12 |
//
|
13 |
//The above copyright notice and this permission notice shall be included in
|
14 |
//all copies or substantial portions of the Software.
|
15 |
//
|
16 |
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 |
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 |
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19 |
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 |
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 |
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 |
//THE SOFTWARE.
|
23 |
//-------------------------------------------------------------------------------
|
24 |
|
25 |
#include "uculib.h"
|
26 |
|
27 |
|
28 |
UCU_UINT8 UcuAtAtanIx100Odegx1RRxx(UCU_UINT16 arg)
|
29 |
{
|
30 |
static const UCU_UINT16 atan_lu[90] = // arctan() precision of 1 degree
|
31 |
{
|
32 |
//This table was generated by a C program.
|
33 |
//The integers below represent the "breakpoints". For example,
|
34 |
//the tangents of 48 and 49 degrees are:
|
35 |
// 48 : 1.1106
|
36 |
// 49 : 1.1504
|
37 |
//The entry under 48 below (113) does not represent the tangent of 48
|
38 |
//degrees. Rather, it represents the point at which the returned arctangent
|
39 |
//should switch from 48 to 49 degrees. The table entries are approximately
|
40 |
//the midpoints between arctangents of integer degrees. This allows the
|
41 |
//returned arctangent to be to the closest degree.
|
42 |
//
|
43 |
/* 0 degrees */ 0, 2, 4, 6, 7,
|
44 |
/* 5 degrees */ 9, 11, 13, 14, 16,
|
45 |
/* 10 degrees */ 18, 20, 22, 24, 25,
|
46 |
/* 15 degrees */ 27, 29, 31, 33, 35,
|
47 |
/* 20 degrees */ 37, 39, 41, 43, 45,
|
48 |
/* 25 degrees */ 47, 49, 52, 54, 56,
|
49 |
/* 30 degrees */ 58, 61, 63, 66, 68,
|
50 |
/* 35 degrees */ 71, 73, 76, 79, 82,
|
51 |
/* 40 degrees */ 85, 88, 91, 94, 98,
|
52 |
/* 45 degrees */ 101, 105, 109, 113, 117,
|
53 |
/* 50 degrees */ 121, 125, 130, 135, 140,
|
54 |
/* 55 degrees */ 145, 151, 156, 163, 169,
|
55 |
/* 60 degrees */ 176, 184, 192, 200, 209,
|
56 |
/* 65 degrees */ 219, 229, 241, 253, 267,
|
57 |
/* 70 degrees */ 282, 298, 317, 337, 360,
|
58 |
/* 75 degrees */ 386, 416, 451, 491, 539,
|
59 |
/* 80 degrees */ 597, 669, 759, 877, 1038,
|
60 |
/* 85 degrees */ 1270, 1634, 2290, 3818, 11458
|
61 |
};
|
62 |
|
63 |
UCU_UINT8 bottom, top, middle;
|
64 |
|
65 |
bottom = 0;
|
66 |
top = 90; //Note: element [90] in the lookup table
|
67 |
//isn't actually necessary. If 90 is the eventual
|
68 |
//return value, bottom converges to top and top
|
69 |
//remains unchanged.
|
70 |
//
|
71 |
//Once (bottom == top), no more dereferencing is done.
|
72 |
//This was verified both by hand analysis and by running
|
73 |
//the program on a *nix platform.
|
74 |
|
75 |
//This algorithm is a modified classic binary search.
|
76 |
//
|
77 |
while (bottom != top)
|
78 |
{
|
79 |
middle = bottom + top;
|
80 |
middle >>= 1;
|
81 |
|
82 |
if (atan_lu[middle] >= arg)
|
83 |
{
|
84 |
//The "middle" table entry is at least as large as the argument.
|
85 |
//We are clear to lower the ceiling to be the middle.
|
86 |
//
|
87 |
top = middle;
|
88 |
}
|
89 |
else
|
90 |
{
|
91 |
//The "middle" entry is less than the argument. That automatically
|
92 |
//makes the middle unsuitable, so the correct return value has
|
93 |
//to be at least one larger than the middle.
|
94 |
//
|
95 |
bottom = middle + 1;
|
96 |
}
|
97 |
}
|
98 |
return(bottom);
|
99 |
}
|
100 |
|
101 |
//-------------------------------------------------------------------------------
|
102 |
//End of $Id: atatanix100odegx1rrxx.c,v 1.4 2010/02/20 02:20:38 dashley Exp $
|
103 |
//-------------------------------------------------------------------------------
|
104 |
//$Log: atatanix100odegx1rrxx.c,v $
|
105 |
//Revision 1.4 2010/02/20 02:20:38 dashley
|
106 |
//Comments removed.
|
107 |
//
|
108 |
//Revision 1.3 2010/01/31 00:14:00 dashley
|
109 |
//Renaming/addition of arctangent function.
|
110 |
//
|
111 |
//Revision 1.2 2010/01/22 03:15:29 dashley
|
112 |
//Extra line removed.
|
113 |
//
|
114 |
//Revision 1.1 2010/01/22 03:14:47 dashley
|
115 |
//Initial checkin.
|
116 |
//-------------------------------------------------------------------------------
|
117 |
|