前言
在项目开发中,有些项目对三角函数使用频繁,尤其是游戏项目,三角函数计算是很耗性能的,产品性能直接影响用户体验,这里对三角函数计算优化方案:查表法的算法解析,希望能对大家有所帮助
,
三角函数
在三角函数中,有一些特殊角,计算中可以直接求出具体的值
角度 | 0° | 15° | 30° | 45° | 60° | 90° | 120° | 135° | 150° | 180° | 270° |
---|---|---|---|---|---|---|---|---|---|---|---|
弧度 | 0 | π/12 | π/6 | π/4 | π/3 | π/2 | 2π/3 | 3π/4 | 5π/6 | π | 3π/2 |
sin值 | 0 | [(√6)-(√2)]/4 | 1/2 | (√2)/2 | (√3)/2 | 1 | (√3)/2 | (√2)/2 | 1/2 | 0 | -1 |
cos值 | 1 | [(√6)+(√2)]/4 | (√3)/2 | (√2)/2 | 1/2 | 0 | -1/2 | -(√2)/2 | -(√3)/2 | -1 | 0 |
我们先从sin函数中找规律,我们先打印出4个象限中的几个特殊角度的正玄值看看
for (var i=0;i<=360;i+=15) {
console.log(Math.sin(Math.PI/180*i)+"===>"+i+"度")
}
输出如下:
0===>0度
0.25881904510252074===>15度
0.49999999999999994===>30度
0.7071067811865475===>45度
0.8660254037844386===>60度
0.9659258262890683===>75度
1===>90度
0.9659258262890683===>105度
0.8660254037844387===>120度
0.7071067811865476===>135度
0.49999999999999994===>150度
0.258819045102521===>165度
1.2246467991473532e-16===>180度
-0.2588190451025208===>195度
-0.5000000000000001===>210度
-0.7071067811865475===>225度
-0.8660254037844385===>240度
-0.9659258262890683===>255度
-1===>270度
-0.9659258262890684===>285度
-0.8660254037844386===>300度
-0.7071067811865477===>315度
-0.5000000000000004===>330度
-0.2588190451025207===>345度
-2.4492935982947064e-16===>360度
规律:第一象限与第二象限的值 sin(75°)=sin(105°), sin(60°)=sin(120°),
得出sin(a)=sin (180-a),
也就是第一象限与第二象限中正玄值是反方向对应的
第三象限正玄值是第一象限的负值
第四象限正玄值是第二象限的负值
所以我们求出第一象限内的正玄值,就可以得到对应另外三个象限的角度的正玄值,
这里有两个特殊值
1.2246467991473532e-16===>180度
-2.4492935982947064e-16===>360度
其实大家都知道这两个特殊角的正玄值都是0,而实际计算出的值是用科学计数法表示的数,这是电脑计算出无限接近0的值,我们直接把它们忽略,直接给0就行
即sin(0°)=sin(180°)=sin(360°)=0
“如果我们把0-90度第一象限内的所有角度的正玄值都提前计算出来放到一个列表里,那么下次再计算相应角度的正玄值时,我们直接去这个表里查出结果就行”,这就是查表法优化的原理
当然我们也不可能把所有的角度都计算一次,我只能拿出一部分采样结果来存储起来,采样越多,结果的误差就越小
生成sin表
首先把0-90度分成1024份,这里用1024份采样为例
sintable=[]
for (var i = 0;i < 1024 ; i++){
sintable[i]=Math.sin(i/1024*Math.PI*0.5);
}
这是生成好的表
var sintable=[
0.000000,0.001534,0.003068,0.004602,0.006136,0.007670,0.009204,0.010738,
0.012272,0.013805,0.015339,0.016873,0.018407,0.019940,0.021474,0.023008,
0.024541,0.026075,0.027608,0.029142,0.030675,0.032208,0.033741,0.035274,
0.036807,0.038340,0.039873,0.041406,0.042938,0.044471,0.046003,0.047535,
0.049068,0.050600,0.052132,0.053664,0.055195,0.056727,0.058258,0.059790,
0.061321,0.062852,0.064383,0.065913,0.067444,0.068974,0.070505,0.072035,
0.073565,0.075094,0.076624,0.078153,0.079682,0.081211,0.082740,0.084269,
0.085797,0.087326,0.088854,0.090381,0.091909,0.093436,0.094963,0.096490,
0.098017,0.099544,0.101070,0.102596,0.104122,0.105647,0.107172,0.108697,
0.110222,0.111747,0.113271,0.114795,0.116319,0.117842,0.119365,0.120888,
0.122411,0.123933,0.125455,0.126977,0.128498,0.130019,0.131540,0.133061,
0.134581,0.136101,0.137620,0.139139,0.140658,0.142177,0.143695,0.145213,
0.146730,0.148248,0.149765,0.151281,0.152797,0.154313,0.155828,0.157343,
0.158858,0.160372,0.161886,0.163400,0.164913,0.166426,0.167938,0.169450,
0.170962,0.172473,0.173984,0.175494,0.177004,0.178514,0.180023,0.181532,
0.183040,0.184548,0.186055,0.187562,0.189069,0.190575,0.192080,0.193586,
0.195090,0.196595,0.198098,0.199602,0.201105,0.202607,0.204109,0.205610,
0.207111,