学习:实现任意角度的sin、cos求值-No.1

来源:互联网 发布:网络划分的策略 编辑:程序博客网 时间:2024/06/06 09:18

说明:

因为做的小游戏的需要,需要使用到任意角度的sin、cos的值。

这里 任意角度 包括无法通过三角函数的诱导公式转变为特殊角的角。

想法:

  1. 根据sin、cos的原始定义来计算角度的(现在实现的)
  2. 利用计算机绘正圆的方法,以圆心为原点建立坐标系,在根据sin、cos对应的圆内三角形的边来求值(还没有实现的)

学习目标:

  1. 学会使用for循环计算阶乘和n次方
  2. 使用泰勒展开式计算sin、cos的值

基础学习:

  • for循环计算阶乘
int factorial = 1, n;for (int i = 1; i <= n; i++)    factorial *= i;

factorial 为阶乘, nn! 里面的 n ,这里可以实现特殊情况 0! = 1 ,这里也需要注意“溢出”的问题

  • for循环计算n次方
int n_thPower, n, a;for (int i = 1; i <= n; i++)    n_thPower *= a;

上面代码计算a的n次方的结果n_thPowern_thPowern次方 , 见数学上的N次方如何用英文表达这里也可以实现 a的0次方等于1 的特殊情况,注意这里声明 n_thPower 使用的是 int 类型,如果 n 或者 n_thPower 过大很容易造成溢出,可以使用能够储存更大数据的类型

任意角度的sin、cos的计算

在这里我们会使用泰勒展开式来计算,泰勒展开式属于高等数学内容。
资料:
不借助工具,我怎么算出任意角三角函数?-来自知乎
上面链接不仅指出了实现办法,还讲了提高计算速度和精度的技巧
关于泰勒展开式的更多内容请自行搜索

  • 泰勒展开式

sinx的泰勒展开式

cosx的泰勒展开式

由于式子较为复杂,我们转化为较为简单的式子

这里写图片描述

这里写图片描述

下面就是代码实现了:

namespace Taylor{    public partial class Form1 : Form    {        double Pi = 3.14159265358979;        double x;        public Form1()        {            InitializeComponent();        }        private double sin(double x)        {            double sin_x = 0.0;            for (int n = 0; n < 5; n++) //取前五次的项来计算            {                double a = 1.0, b = 1.0, c = 1.0;                //使用double防止溢出,不过这样声明时就要为1.0而不是1                //计算(-1)的(n)次方                for (int i = 0; i < n; i++)                {                    a *= -1;                }                //计算(2n + 1)的阶乘                for (int i = 1; i <= 2 * n + 1; i++)                {                    b *= i;                }                //计算(x)的(2n+1)次方                for (int i = 0; i < 2 * n + 1; i++)                {                    c *= x;                }                sin_x += ((a / b) * c);            }            return sin_x;        }        private double cos(double x)        {            double cos_x = 0.0;            for (int n = 0; n < 5; n++) //取前五次的项来计算            {                double a = 1.0, b = 1.0, c = 1.0;                //计算(-1)的(n)次方                for (int i = 0; i < n; i++)                {                    a *= -1;                }                //计算(2n)的阶乘                for (int i = 1; i <= 2 * n; i++)                {                    b *= i;                }                //计算(x)的(2n+1)次方                for (int i = 0; i < 2 * n; i++)                {                    c *= x;                }                cos_x += ((a / b) * c);            }            return cos_x;        }        private void button1_Click(object sender, EventArgs e)        {            x = Pi / 4.0;  //这里用Pi/4作为例子计算            label1.Text = "sinx =" + sin(x).ToString();            label2.Text = "cosx =" + cos(x).ToString();        }    }}

缺陷和改进

  1. 现在这个程序还不能正确显示特殊角的sin、cos值,在第二篇中将会加入特殊角的判断
    特殊角的三角函数值
  2. 现在程序的精度还不高,因为没有控制在输入的角度时没有对其进行化简,精度最高的情况是在 x 属于 [0, Pi/2] 的情况,见 说明
  3. Pi的值为手打的,不够精确,下一步将从Pi的来源来计算Pi的值,而不是定义为常量
1 0
原创粉丝点击