求解公式中每个变量的算法

时间:2015-12-12 17:28:00

标签: c algorithm physics

我正在制作一个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之前,有人可以建议一个替代方案吗?

1 个答案:

答案 0 :(得分:1)

实质上,您所做的是在任何变量发生变化时迭代循环。对于每个变量,检查它所依赖的变量是否已更改,如果是,则重新计算变量。在以下if语句中,可以测试此变量现在已更改的事实,并且依赖于它的变量重新计算,等等,但这不是必需的。

使用该阵列有点难以阅读该方法。使用具有适当名称的变量将更易于阅读。

我没有其他重要建议。方法很好。它不是非常昂贵/低效,因为它只使用基本的数学。可能在数学社区中有一个更好的算法来解决你的问题,但我不知道。

P.s。:的确,您的问题更适合Code Review的审核。