下面式子一和式子二是最初的两个式子,其中只有和
是未知数,其余的都是已知数。通过推导求出相应的
和
两个未知数的值。
式子一:
式子二:
通过上面的两个式子进行联立求解 和
的值。
一开始上面的两个式子求解,最初的思路是使用两个二元一次方程之间进行联立求解,但是找了一下网上的代码,什么粒子群啥的、牛顿插值、非线性法都是不能用的,后来发现想复杂了,可以之间使用联立求解的方式进行求解。一直以为这两个式子是二元一次方程,但是联立之后就不是了,不要被式子表面现象给骗了。为了求出来这两个数值,心态emmmm都要炸了。
将上面的式子一那个式子带入到下面的式子二那个式子之中,注意这里的一定一定不要展开,展开就很很很痛苦了,会有一个cos的平方啥的,麻烦的很,想了好长时间,一定不要展开,展开就真的造孽了。
首先对于式子二进行一个变换,因为式子二之中是存在 和
两个未知数,将其变成只含有
一个未知数,消除掉
的影响。变换式子二得到
式子三:
将原来的式子一带入到式子三之中,消除掉 的影响。进而得到
式子四
对于式子四进一步整理,可以得到一个关于的一个一元二次方程,如下所示:
通过一元二次方程进行求解上面的式子,即可得出的值,进而求取到
的值。再将
的值反代到式子一之中,由
可以得到相应的 的值,从而求解出两个未知数的值。
代码是很简单,但是这个推导过程还是需要认真想的,真的想了好久,才最终倒算出来,写代码的时候有可能会出现错误,需要模拟一个值,反代入,利用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;
}
}