一元二次函数求解(三角函数、二元一次函数转换为一元二次函数的思路)

18 篇文章 2 订阅
5 篇文章 0 订阅

下面式子一和式子二是最初的两个式子,其中只有\gamma\delta是未知数,其余的都是已知数。通过推导求出相应的 \gamma\delta两个未知数的值。

式子一:

式子二:

通过上面的两个式子进行联立求解 \gamma\delta 的值。

一开始上面的两个式子求解,最初的思路是使用两个二元一次方程之间进行联立求解,但是找了一下网上的代码,什么粒子群啥的、牛顿插值、非线性法都是不能用的,后来发现想复杂了,可以之间使用联立求解的方式进行求解。一直以为这两个式子是二元一次方程,但是联立之后就不是了,不要被式子表面现象给骗了。为了求出来这两个数值,心态emmmm都要炸了。

将上面的式子一那个式子带入到下面的式子二那个式子之中,注意这里的tan\left ( \gamma \right )一定一定不要展开,展开就很很很痛苦了,会有一个cos的平方啥的,麻烦的很,想了好长时间,一定不要展开,展开就真的造孽了。

首先对于式子二进行一个变换,因为式子二之中是存在 \gamma\delta 两个未知数,将其变成只含有\gamma一个未知数,消除掉\delta的影响。变换式子二得到

式子三:

将原来的式子一带入到式子三之中,消除掉 \delta的影响。进而得到

式子四

对于式子四进一步整理,可以得到一个关于tan\left ( \gamma \right )的一个一元二次方程,如下所示: 

通过一元二次方程进行求解上面的式子,即可得出tan\left ( \gamma \right )的值,进而求取到\gamma的值。再将\gamma的值反代到式子一之中,由

可以得到相应的 \delta的值,从而求解出两个未知数的值。

代码是很简单,但是这个推导过程还是需要认真想的,真的想了好久,才最终倒算出来,写代码的时候有可能会出现错误,需要模拟一个值,反代入,利用cout验证每一个步骤的正确与否。具体代码如下所示:

 注意:下面的代码之中,使用了一个转换,平时cos等三角函数是输入弧度,转换之后可以直接使用角度进行输入与输出。

//给二元一次方程组求解(带过程)
#include<iostream>
#include<math.h>
#define PI 3.14159265358979323846
using namespace std;

double tsin(double i)
{
	return sin(i * PI / 180);
}

double tcos(double i)
{
	return cos(i * PI / 180);
}

double ttan(double i)
{
	return tan(i * PI / 180);
}

double tatan(double i)
{
	return  atan(i) * 180.0 / PI;
}

double max(double solve1, double solve2)
{
	if (solve1 >= solve2)
	{
		return solve1;
	}
	else {
		return solve2;
	}
}


int main()
{

	double K1, K2;//输入相机1和相机2之中斜率。
	K1 = 1.0f;
	K2 = 1.0f;

	double X;//输入围绕x轴进行旋转的角度
	X = 0.0f;

	double Y;//输入围绕y轴进行旋转的角度
	Y = 120.0f;

	double b, a, c, t;
	double solve1, solve2;//输出的tan r 的值


	b = (double)((2.0f) * K2 * tsin(Y) * tcos(X) - K1 * ttan(Y) + tsin(X));
	
	

	//cout << "t1=" << t1<<" t2=" << t2 <<"t3=" << t3 << endl;

	a = (double)(K2 * tcos(X) * tsin(Y) * ttan(Y) + tsin(X) * ttan(Y));
	c = (double)(0.0f - K1 + K2 * tcos(Y) * tcos(X));

	//cout << "a=" << a << endl;
	//cout << "b=" << b << endl;
	//cout << "c=" << c << endl;

	t = (double)(b * b - 4.0f * a * c);

	double solve;
	//输出角度
	double r, q;//分别是左相机角度,倾斜角度

	if (a != 0) {
		if (t > 0) {//方程有两个不同的实根

				t = (double)(sqrt(t));//b^2-4ac开根号

				solve1 = (double)((-b + t) / (2.0 * a));
				solve2 = (double)((-b - t) / (2.0 * a));

				cout << "方程的第一个根为" << solve1 << endl;
				cout << "方程的第二个根为" << solve2 << endl;
				if ((solve1 >= 0) || (solve2 >= 0))
				{
					 solve = max(solve1, solve2);
					 cout << solve << endl;
				}
				else
				{
					cout << "出错"  << endl;
				}
			
		}
		if (t == 0) {//方程有两个相同的跟

			t = (double)(sqrt(t));
			solve1 = (double)((-b + t) / (2.0 * a));
			cout << "方程两个相同的实数根为" << solve1 << endl;

		}
		if (t < 0) {
			cout << "error!" << endl;

		}

		r = (double)(tatan(solve));
		cout << "相机1与圆柱投影之间的角度:"<<r<< endl;

		q = (double)(tatan(tsin(r) / (K2 * tcos(Y - r))) - X);
		cout << "相机1与圆柱体之间的原始夹角:" << q << endl;


		if (a == 0 && b != 0) {
			double x;
			x = -c / b;
			cout << "方程是一元一次方程,根为" << x << endl;
		}
		if (b == 0 && c != 0) {
			cout << "error!" << endl;
		}
		if (b == 0 && c == 0) {
			cout << "等式恒成立" << endl;
		}
		return 0;
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值