代码拉取完成,页面将自动刷新
Harryzhang 503433013@qq.com/harryzhangpro@gmail.com
突然有了一个想法:
如果不用第三个电机,只用两个电机、两根硬联杆实现画正弦波、三角波和任意图形?(不用第三个电机也能做出来)
于是,有了以下思路:
那么,通过这个思路,我只要输入A的值,然后解算出H、L的坐标,不就可以画正玄波、画三角波、画方波、画任意图形了吗!
个人感觉挺麻烦的,请对着上图看代码。
static solution invx(solution solu2)
{
solution solu = solu2;
float L1_U,L2_U;
if(solu.CACL_A > solu.CACL_B){
L1_U = L1;
L2_U = L2;
}else{
L1_U = L2;
L2_U = L1;
}
float ax = solu.CACL_A-solu.CACL_B;
float A = pow(H,2)+pow(L1_U,2)-pow(ax,2)-pow(L2_U,2);
float B = 2*H*L1_U;
float C = 2*ax*L2_U;
float a = pow(B,2)*pow(L2_U,2)+pow(C,2)*pow(L1_U,2);
float b = -2*L1_U*A*B*pow(L2_U,2)-2*H*pow(L1_U,2)*pow(C,2);
float c = pow(A,2)*pow(L1_U,2)*pow(L2_U,2)-pow(C,2)*pow(L1_U,2)*pow(L2_U,2)+pow(C,2)*pow(L1_U,2)*pow(H,2);
solution solu3 = caclduo(a,b,c);
if(solu.CACL_A > solu.CACL_B){
solu.solved.x = solu.CACL_B + sqrt(pow(L1,2)-pow(solu3.DeltaX,2));
solu.solved.y = solu3.DeltaX;
}else{
solu.solved.x = solu.CACL_A + sqrt(pow(L2,2)-pow(solu3.DeltaX,2));
solu.solved.y = H-solu3.DeltaX;
}
// cout << sqrt(pow(L2,2)-pow(solu.DeltaX,2)) << "," << sqrt(pow(L1,2)-pow(solu.DeltaX,2)) << "," << org_a << "," << org_b << "," << ax << endl;
return solu;
}
假设,我们第一步输入了A(x,y)值,这个值是不能直接带入公式计算的,因为L1固定到原点以后,A点的活动范围只有以L1为半径的半圆,A(x,y)不能保证直接落到半圆上,否则会无解。此时我们需要把它转换成思路图片的相对坐标系,也就是让这个xy落到这个半圆上,才能够进行逆解计算。那么怎么才能找到这个"差值"呢?,这里我们设L点为(X0,0),则向量LA=(x-X0,y);则该向量的模为L1。利用这个关系,我们可以列出一个包含X0/x/y/L1的一个二元一次方程,然后计算它的根,并取较小(靠近原点)那个。
实现代码:
static solution getx(float x,float y) //计算
{
solution solu = caclduo(1,-2*x,pow(x,2)+pow(y,2)-pow(L1,2)); //计算二元一次函数,并取较小的那个根
if(solu.success)
{
x -= solu.DeltaX; //在这一步我们得到了最小的那个根,也就是L(X0,0),然后把他转换到相对坐标轴上,把原点通过X轴平移到L点。
float a1 = atan(y/x); //请结合上图,理解下面的代码
float sina2 = (H-L1*sin(a1))/L2; //请结合上图,理解下面的代码
float cosa2 = sqrt(1-pow(sina2,2)); //请结合上图,理解下面的代码
float ax = L2*cosa2;
// cout << "a1:" << a1 << " sina1:" << sin(a1) << " sina2:" << sina2 << " cosa2:" << cosa2 << " ax:" << ax <<" DeltaX:" << solu.DeltaX << endl;
solu.CACL_A = solu.DeltaX + (x-ax); //解算完成,由于是在相对坐标系上计算了,需要把原点移回绝对坐标系
solu.CACL_B = solu.DeltaX;
}
return solu;
}
//ax^2+bx+c=0,返回较小方程的根
static solution caclduo(float a,float b,float c) //二元一次方程计算函数,输入a,b,c
{
solution solu;
float root = pow(b,2)-4*a*c; //计算根
solu.success = true;
if(root>=0 || a!=0) //二次函数不存在
{
if(root == 0) //二次函数只有一个解
{
solu.DeltaX = -b/2*a; //返回解
solu.success = true;
goto end;
}
float x1 = (-b+sqrt(root))/(2*a); //通过求根公式计算方程的解
float x2 = (-b-sqrt(root))/(2*a);
// cout << "a:" << a << " b:" << b << " c:" << c << " root:" << root << " Dx1:" << x1 << " Dx2:" << x2 << endl;
if(x1>x2)
solu.DeltaX = x2; //由于安装方式,取最靠近原点的值作为增量值。
else
solu.DeltaX = x1;
}
else
solu.success = false;
end:return solu;
}
...(约200行左右)
#define Ax 218
#define Ay 32
...
...(约160行左右)
const float L1 = 110.0;
const float L2 = 110.0;
const float H = 110.0;
...
g++ plot.c -lgdi32 -o plot.exe
./plot.exe
按照上面的方法,输入A(218,32)并执行:
按照上面的方法,输入A(218,97)并执行:
至此,我们实现了输入一个坐标,就能够自动计算出相对于的H、L的坐标值,通过加入直线插补、圆弧插补算法,然后通过编码器和电机去执行就可以实现只用俩个电机画图的功能。
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。
1. 开源生态
2. 协作、人、软件
3. 评估模型