我正在制作一个iOS应用程序来解决物理问题,我开始只是通过以下公式解决基本的运动学问题(我用C代替Swift进行编码,因为我知道C更好):
时间:t
距离变化:d
平均速度:va
初速度:vi
最终速度:vf
加速:a
va = (vf + vi) / 2
vf^2 = vi^2 + 2ad
d = vit + 1/2at^2
a = (vf - vi) / t
va = d / t
一旦输入了给定的变量,我正在使用以下代码来解决尽可能多的变量。传入的数组包含我在上面以相同顺序显示的变量。诸如tChanged或vaChanged之类的布尔值初始化为false,如果用户为它们输入值或者我的算法为它们赋值,则将其更改为true:
void calculateUnknowns1(double values[6])
{
int i = 0;
do{
i = 0;
/*-------------------------------------------DERIVED FROM: va = (vf+vi)/2----------------------------------------------------*/
if((vfChanged)&&(viChanged)){
if(!vaChanged){
values[2] = (values[4]+values[3]) / 2;
i++;
vaChanged = true;
}
}
if((vaChanged)&&(viChanged)){
if(!vfChanged){
values[4] = 2*values[2] - values[3];
i++;
vfChanged = true;
}
}
if((vaChanged)&&(vfChanged)){
if(!viChanged){
values[3] = 2*values[2] - values[4];
i++;
viChanged = true;
}
}
/*----------------------------------------DERIVED FROM: vf*vf = vi*vi + 2*a*d------------------------------------------------*/
if((viChanged)&&(aChanged)&&(dChanged)){
if(!vfChanged){
values[4] = sqrtl(values[3]*values[3] + 2*values[5]*values[1]);
i++;
vfChanged = true;
}
}
if((vfChanged)&&(aChanged)&&(dChanged)){
if(!viChanged){
values[3] = sqrtl(values[4]*values[4] - 2*values[5]*values[1]);
i++;
viChanged = true;
}
}
if((viChanged)&&(vfChanged)&&(aChanged)){
if(!dChanged){
values[1] = (values[4]*values[4] - values[3]*values[3]) / (2*values[5]);
i++;
dChanged = true;
}
}
if((viChanged)&&(vfChanged)&&(dChanged)){
if(!aChanged){
values[5] = (values[4]*values[4] - values[3]*values[3]) / (2*values[1]);
i++;
aChanged = true;
}
}
/*-------------------------------------------DERIVED FROM: d = vit+1/2at*t---------------------------------------------------*/
/*if((tChanged)&&(dChanged)&&(values[3]==0)){
if(!aChanged){
values[5] = values[1]/(0.5*values[0]*values[0]);
i++;
aChanged = true; EXTRANNEOUS
}
}
if((tChanged)&&(dChanged)&&(values[5]==0)){
if(!viChanged){
values[3] = values[1]/values[0];
i++;
viChanged = true;
}
}*/
if((tChanged)&&(viChanged)&&(aChanged)){
if(!dChanged){
values[1] = values[3]*values[0] + 0.5*values[5]*values[0]*values[0];
i++;
dChanged = true;
}
}
if((tChanged)&&(dChanged)&&(aChanged)){
if(!viChanged){
values[3] = (values[1] - 0.5*values[5]*values[0]*values[0]) / values[0];
i++;
viChanged = true;
}
}
if((tChanged)&&(dChanged)&&(viChanged)){
if(!aChanged){
values[5] = (values[1] - values[3]*values[0]) / (0.5*values[0]*values[0]);
i++;
aChanged = true;
}
}
if((dChanged)&&(viChanged)&&(aChanged)){
if(!tChanged){
values[0] = (-(values[3]) + sqrtl(values[3]*values[3] - 4*0.5*values[5]*(-values[1]))) / values[5];
if(!((values[1] == values[3]*values[0] + 0.5*values[5]*values[0]*values[0])&&(values[0]>=0))){
values[0] = (-(values[3]) - sqrtl(values[3]*values[3] - 4*0.5*values[5]*(-values[1]))) / values[5];
}
i++;
tChanged = true;
}
}
/*-------------------------------------------DERIVED FROM: a=(vf-vi)/t-------------------------------------------------------*/
if((vfChanged)&&(viChanged)&&(tChanged)){
if(!aChanged){
values[5] = (values[4]-values[3]) / values[0];
i++;
aChanged = true;
}
}
if((vfChanged)&&(viChanged)&&(aChanged)){
if(!tChanged){
values[0] = (values[4]-values[3]) / values[5];
i++;
tChanged = true;
}
}
if((vfChanged)&&(aChanged)&&(tChanged)){
if(!viChanged){
values[3] = values[4] - values[5]*values[0];
i++;
viChanged = true;
}
}
if((viChanged)&&(aChanged)&&(tChanged)){
if(!vfChanged){
values[4] = values[3] + values[5]*values[0];
i++;
vfChanged = true;
}
}
/*-------------------------------------------DERIVED FROM: va = d/t---------------------------------------------------------*/
if((dChanged)&&(tChanged)){
if(!vaChanged){
values[2] = values[1] / values[0];
i++;
vaChanged = true;
}
}
if((dChanged)&&(vaChanged)){
if(!tChanged){
values[0] = values[1] / values[2];
i++;
tChanged = true;
}
}
if((vaChanged)&&(tChanged)){
if(!dChanged){
values[1] = values[2]*values[0];
i++;
dChanged = true;
}
}
/*-------------------------------------------SOLVING FOR t WITH vi--------------------------------------------------------*/
if((aChanged)&&(vfChanged)&&(dChanged)){
if(!tChanged){
values[0] = (sqrtl(values[4]*values[4] - 2*values[5]*values[1]) + values[4]) / -(values[5]);
if(values[0]<=0){
values[0] = (sqrtl(values[4]*values[4] - 2*values[5]*values[1]) - values[4]) / -(values[5]);
}
i++;
tChanged = true;
}
}
}while(i>0);
}
这个算法运行正常,但对我来说效率似乎非常低效。在我进一步进入Forces and Momentum之前,有人可以建议一个替代方案吗?
答案 0 :(得分:1)
实质上,您所做的是在任何变量发生变化时迭代循环。对于每个变量,检查它所依赖的变量是否已更改,如果是,则重新计算变量。在以下if
语句中,可以测试此变量现在已更改的事实,并且依赖于它的变量重新计算,等等,但这不是必需的。
使用该阵列有点难以阅读该方法。使用具有适当名称的变量将更易于阅读。
我没有其他重要建议。方法很好。它不是非常昂贵/低效,因为它只使用基本的数学。可能在数学社区中有一个更好的算法来解决你的问题,但我不知道。
P.s。:的确,您的问题更适合Code Review的审核。