HiveBrain v1.2.0
Get Started
← Back to all entries
patterncMinor

Solving for every variable in a number of physics formulas

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
solvingnumberphysicseveryformulasforvariable

Problem

I'm working on making an iOS app to solve physics problems and I'm starting by just having it solve basic kinematics problems with the following formulas (I've coded it in C instead of Swift to start because I know C better):

  • Time: \$t\$



  • Change in Distance: \$d\$



  • Average Velocity: \$v_a\$



  • Initial Velocity: \$v_i\$



  • Final Velocity: \$v_f\$



  • Acceleration: \$a\$



  • \$v_a = \frac{v_f + v_i}{2}\$



  • \$v_f^2 = v_i^2 + 2ad\$



  • \$d = v_it + \frac{1}{2}at^2\$



  • \$a = \dfrac{v_f - v_i}{t}\$



  • \$v_a = \frac{d}{t}\$



I'm using the following code to solve for as many of the variables as possible once the given variables have been input. The array being passed in contains the variables I showed above in the same order. The boolean values such as tChanged or vaChanged are initialized as false and then changed to true if the user inputs a value for them or if my algorithm assigns them a value:

```
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: vfvf = vivi + 2ad------------------------------------------------/

if((viChanged)&&(aChanged)&&(dChanged

Solution

What does values[n] mean?

You have this array of 6 doubles, that you reference by index throughout:

values[2] = (values[4]+values[3]) / 2;


What does that line of code mean? Very little. You never use this array like an array - it's not a collection of like things. Instead, you should move these values into a struct:

typedef struct variables {
    double v_a;
    double v_f;
    double v_i;
    ...
};


And then take a struct variables* instead of a double[6] - so you can reference the right thing:

vars->v_a = (vars->v_i + vars->v_f) / 2;


That has meaning. This gets steadily more important as the number of elements in values you use increases.

Refactoring

Rather than one monolith, you should break each formula up into its own piece:

void calculateUnknowns1(struct variables* vars)
{
    int i;
    do {
        i = 0;
        i += applyAvgVelocity(vars);
        i += applyAcceleration(vars);
        ...
    } while (i>0);
}


Or even:

void calculateUnknowns1(struct variables* vars)
{
    while (applyAvgVelocity(vars) || applyAcceleration(vars) || ... )
        ;
}

Code Snippets

values[2] = (values[4]+values[3]) / 2;
typedef struct variables {
    double v_a;
    double v_f;
    double v_i;
    ...
};
vars->v_a = (vars->v_i + vars->v_f) / 2;
void calculateUnknowns1(struct variables* vars)
{
    int i;
    do {
        i = 0;
        i += applyAvgVelocity(vars);
        i += applyAcceleration(vars);
        ...
    } while (i>0);
}
void calculateUnknowns1(struct variables* vars)
{
    while (applyAvgVelocity(vars) || applyAcceleration(vars) || ... )
        ;
}

Context

StackExchange Code Review Q#113805, answer score: 4

Revisions (0)

No revisions yet.