Kinematic Equations Calculator












6














The program allows user to enter values for 3 of the following




  • initial velocity

  • final velocity

  • acceleration

  • displacement

  • time


and to specify an unknown (one of the previously mentioned variables). The program uses the Kinematic Equations to calculate the unknown.



I would like a review of the entire program. I have only studied programming online as a hobby so i have never received comments on my code. I want to become a better programmer and break any bad habits. Dont hold back on any criticism or praise, please comment anything you think of. What is inefficient/ unclear/ unnecessary? What can be improved or added? What is good? What approach would you have taken to the problem? Is the code understandable at all As far as I can tell the code at least works, does what it should.



OrderedArray.h, container class



#include "stdafx.h"
#include <assert.h>
#include <iostream>

class OrderedArray
{
private:
double* m_pdValues;
int* m_pnOrderKeys;
int m_nValuesLength;
int m_nKeysLength;
void erase()
{
delete m_pdValues;
delete m_pnOrderKeys;
m_pdValues = 0;
m_pnOrderKeys = 0;
m_nValuesLength = 0;
m_nKeysLength = 0;
}
public:
OrderedArray() : m_pdValues(0), m_nValuesLength(0), m_pnOrderKeys(0), m_nKeysLength(0)
{

}
double operator(int nIndex) //returns from values array
{
assert(nIndex >= 0 && nIndex < m_nValuesLength);
return m_pdValues[nIndex];
}
void insertLast(double dValue)
{
assert(nIndex >= 0 && nIndex <= m_nValuesLength);
double* pdValues = new double[m_nValuesLength + 1];
for (int i=0; i < m_nValuesLength; i++)
pdValues[i] = m_pdValues[i];
pdValues[m_nValuesLength] = dValue;
delete m_pdValues;
m_pdValues = pdValues;
m_nValuesLength += 1;
}
void insertLast(int nKey)
{
assert(nIndex >= 0 && nIndex <= m_nKeysLength);
int* pnKeys = new int[m_nKeysLength + 1];
for (int i=0; i < m_nKeysLength; i++)
pnKeys[i] = m_pnOrderKeys[i];
pnKeys[m_nKeysLength] = nKey;
delete m_pnOrderKeys;
m_pnOrderKeys = pnKeys;
m_nKeysLength += 1;
}
void insertBefore(double dValue, int nIndex)
{
assert(nIndex >= 0 && nIndex <= m_nValuesLength);
double* pdValues = new double[m_nValuesLength + 1];
for (int nBefore=0; nBefore < nIndex; nBefore++)
pdValues[nBefore] = m_pdValues[nBefore];
pdValues[nIndex] = dValue;
for (int nAfter=nIndex; nAfter < m_nValuesLength; nAfter++)
pdValues[nAfter+1] = m_pdValues[nAfter];
delete m_pdValues;
m_pdValues = pdValues;
m_nValuesLength += 1;
}
void insertBefore(int nKey, int nIndex)
{
assert(nIndex >= 0 && nIndex <= m_nKeysLength);
int* pnKeys = new int[m_nKeysLength + 1];
for (int nBefore=0; nBefore < nIndex; nBefore++)
pnKeys[nBefore] = m_pnOrderKeys[nBefore];
pnKeys[nIndex] = nKey;
for (int nAfter=nIndex; nAfter < m_nKeysLength; nAfter++)
pnKeys[nAfter+1] = m_pnOrderKeys[nAfter];
delete m_pnOrderKeys;
m_pnOrderKeys = pnKeys;
m_nKeysLength += 1;
}
void add(double dValue, int nKey)
{
if(m_nValuesLength >= 3)
{
std::cout << "OrderedArray full" << std::endl;
return;
}
if(m_pdValues == 0)
{
m_pdValues = new double[1];
m_nValuesLength = 1;
m_pdValues[0] = dValue;
m_pnOrderKeys = new int[1];
m_nKeysLength = 1;
m_pnOrderKeys[0] = nKey;
}
else
{
int keysLengthTemp = m_nKeysLength;
for(int i = 0; i < keysLengthTemp; i++)
{
if(nKey < m_pnOrderKeys[i])
{
insertBefore(dValue, i);
insertBefore(nKey, i);
return;
}
}
insertLast(dValue);
insertLast(nKey);
}
}
~OrderedArray()
{
delete m_pdValues;
delete m_pnOrderKeys;
}
int getLength() { return m_nValuesLength; }
double* getValuesArray()
{
assert(m_nValuesLength == 3);
return m_pdValues;
}
int getSumOfKeys()
{
assert(m_nKeysLength == 3);
return m_pnOrderKeys[0] + m_pnOrderKeys[1] + m_pnOrderKeys[2];
}
};


Physics Formulae.cpp



#include "stdafx.h"
#include <math.h>
#include <iostream>
#include <string>
#include "OrderedArray.h"
#define PI 3.14159265358979323846
//func name = original leftside variable in formula + variable to solve for
int translate(std::string s)
{
if(s == "d")
return 0;
if(s == "vf")
return 1;
if(s == "a")
return 2;
if(s == "t")
return 3;
if(s == "vi")
return 4;
return -1;
}
double* shit(double x, double y, double z) //placeholder function to fill out funcarray
{
static double pdArray[2];
pdArray[0] = PI;
pdArray[1] = PI;
return pdArray;
} //vf does not contain d
double* vfvf(double a, double t, double vi)
{
static double pdArray[2];
pdArray[0] = vi + a * t;
pdArray[1] = PI;
return pdArray;
}

double* vfa(double vf, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (vf - vi) / t;
pdArray[1] = PI;
return pdArray;
}
double* vft(double vf, double a, double vi)
{
static double pdArray[2];
pdArray[0] = (vf - vi) / a;
pdArray[1] = PI;
return pdArray;
}
double* vfvi(double vf, double a, double t)
{
static double pdArray[2];
pdArray[0] = vf - a * t;
pdArray[1] = PI;
return pdArray;
}
//d does not contain vf
double* dd(double a, double t, double vi)
{
static double pdArray[2];
pdArray[0] = vi * t + 0.5 * a * t * t;
pdArray[1] = PI;
return pdArray;
}
double* da(double d, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (d - vi * t) / pow(t, 2) * 2;
pdArray[1] = PI;
return pdArray;
}
double* dt(double d, double a, double vi) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = 0 - (vi / a) + sqrt(pow(vi/a, 2) + 2 * d / a);
pdArray[1] = 0 - (vi / a) - sqrt(pow(vi/a, 2) + 2 * d / a);
return pdArray;
}
double* dvi(double d, double a, double t)
{
static double pdArray[2];
pdArray[0] = (d - 0.5 * a * t * t) / t;
pdArray[1] = PI;
return pdArray;
}
//dd does not contain a
double* ddd(double vf, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (vi + vf) / 2 * t;
pdArray[1] = PI;
return pdArray;
}
double* ddvf(double d, double t, double vi)
{
static double pdArray[2];
pdArray[0] = d / t * 2 - vi;
pdArray[1] = PI;
return pdArray;
}
double* ddt(double d, double vf, double vi)
{
static double pdArray[2];
pdArray[0] = d / (vi + vf) * 2;
pdArray[1] = PI;
return pdArray;
}
double* ddvi(double d, double vf, double t)
{
static double pdArray[2];
pdArray[0] = d / t * 2 - vf;
pdArray[1] = PI;
return pdArray;
}
//vf2 does not contain t
double* vf2d(double vf, double a, double vi)
{
static double pdArray[2];
pdArray[0] = (pow(vf, 2) - pow(vi, 2)) / 2 / a;
pdArray[1] = PI;
return pdArray;
}
double* vf2vf(double d, double a, double vi) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = sqrt(pow(vi, 2) + 2 * a * d);
pdArray[1] = 0 - sqrt(pow(vi, 2) + 2 * a * d);
return pdArray;
}
double* vf2a(double d, double vf, double vi)
{
static double pdArray[2];
pdArray[0] = (pow(vf, 2) - pow(vi, 2)) / 2 / d;
pdArray[1] = PI;
return pdArray;
}
double* vf2vi(double d, double vf, double a) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = sqrt(pow(vf, 2) - 2 * a * d);
pdArray[1] = 0 - sqrt(pow(vf, 2) - 2 * a * d);
return pdArray;
}

int _tmain(int argc, _TCHAR* argv)
{
double* (*funcArray[4][5])(double, double, double) = //[missing][unknown]
{
{shit, vfvf, vfa, vft, vfvi},
{dd, shit, da, dt, dvi},
{ddd, ddvf, shit, ddt, ddvi},
{vf2d, vf2vf, vf2a, shit, vf2vi}
};
OrderedArray OA = OrderedArray();
int nAccessVarMissing = -1;
int nAccessUnknownVar = -1;
using namespace std;
string s;
cout << "Which variable is unknown? (d, vf, vi, a or t)" << endl;
cin >> s;
nAccessUnknownVar = translate(s);
double dValueTemp = -1;
string strVarNameTemp = " ";
for(int i = 0; i < 3; i++)
{
cout << "Enter a known variable (d, vf, vi, a or t) followed by 'Enter' followed by the value of the variable: ";
cin >> strVarNameTemp;
cin >> dValueTemp;
OA.add(dValueTemp, translate(strVarNameTemp));
dValueTemp = -1;
strVarNameTemp = " ";
}
nAccessVarMissing = 1 + 2 + 3 + 4 - OA.getSumOfKeys() - nAccessUnknownVar;
if(nAccessVarMissing == 4)
{
cout << "Invalid combination of variables, vi must be either known or unknown" << endl;
cin.get();
exit(0);
}
cout << "unknown is: " << funcArray[nAccessVarMissing][nAccessUnknownVar](OA[0], OA[1], OA[2])[0] << endl;
double dTemp = funcArray[nAccessVarMissing][nAccessUnknownVar](OA[0], OA[1], OA[2])[1];
if(dTemp != PI)
cout << "unknown is: " << dTemp;
int x = 0;
cin >> x;
return 0;
}









share|improve this question
























  • I have a very similar project I'm working on. The code I use for the Kinematics part of it is here. I took a fairly different approach from you on it I think. I haven't looked it over too thoroughly but it looks like your code contains a lot of work that it doesn't have to.
    – Ulthran
    Dec 13 '15 at 4:45


















6














The program allows user to enter values for 3 of the following




  • initial velocity

  • final velocity

  • acceleration

  • displacement

  • time


and to specify an unknown (one of the previously mentioned variables). The program uses the Kinematic Equations to calculate the unknown.



I would like a review of the entire program. I have only studied programming online as a hobby so i have never received comments on my code. I want to become a better programmer and break any bad habits. Dont hold back on any criticism or praise, please comment anything you think of. What is inefficient/ unclear/ unnecessary? What can be improved or added? What is good? What approach would you have taken to the problem? Is the code understandable at all As far as I can tell the code at least works, does what it should.



OrderedArray.h, container class



#include "stdafx.h"
#include <assert.h>
#include <iostream>

class OrderedArray
{
private:
double* m_pdValues;
int* m_pnOrderKeys;
int m_nValuesLength;
int m_nKeysLength;
void erase()
{
delete m_pdValues;
delete m_pnOrderKeys;
m_pdValues = 0;
m_pnOrderKeys = 0;
m_nValuesLength = 0;
m_nKeysLength = 0;
}
public:
OrderedArray() : m_pdValues(0), m_nValuesLength(0), m_pnOrderKeys(0), m_nKeysLength(0)
{

}
double operator(int nIndex) //returns from values array
{
assert(nIndex >= 0 && nIndex < m_nValuesLength);
return m_pdValues[nIndex];
}
void insertLast(double dValue)
{
assert(nIndex >= 0 && nIndex <= m_nValuesLength);
double* pdValues = new double[m_nValuesLength + 1];
for (int i=0; i < m_nValuesLength; i++)
pdValues[i] = m_pdValues[i];
pdValues[m_nValuesLength] = dValue;
delete m_pdValues;
m_pdValues = pdValues;
m_nValuesLength += 1;
}
void insertLast(int nKey)
{
assert(nIndex >= 0 && nIndex <= m_nKeysLength);
int* pnKeys = new int[m_nKeysLength + 1];
for (int i=0; i < m_nKeysLength; i++)
pnKeys[i] = m_pnOrderKeys[i];
pnKeys[m_nKeysLength] = nKey;
delete m_pnOrderKeys;
m_pnOrderKeys = pnKeys;
m_nKeysLength += 1;
}
void insertBefore(double dValue, int nIndex)
{
assert(nIndex >= 0 && nIndex <= m_nValuesLength);
double* pdValues = new double[m_nValuesLength + 1];
for (int nBefore=0; nBefore < nIndex; nBefore++)
pdValues[nBefore] = m_pdValues[nBefore];
pdValues[nIndex] = dValue;
for (int nAfter=nIndex; nAfter < m_nValuesLength; nAfter++)
pdValues[nAfter+1] = m_pdValues[nAfter];
delete m_pdValues;
m_pdValues = pdValues;
m_nValuesLength += 1;
}
void insertBefore(int nKey, int nIndex)
{
assert(nIndex >= 0 && nIndex <= m_nKeysLength);
int* pnKeys = new int[m_nKeysLength + 1];
for (int nBefore=0; nBefore < nIndex; nBefore++)
pnKeys[nBefore] = m_pnOrderKeys[nBefore];
pnKeys[nIndex] = nKey;
for (int nAfter=nIndex; nAfter < m_nKeysLength; nAfter++)
pnKeys[nAfter+1] = m_pnOrderKeys[nAfter];
delete m_pnOrderKeys;
m_pnOrderKeys = pnKeys;
m_nKeysLength += 1;
}
void add(double dValue, int nKey)
{
if(m_nValuesLength >= 3)
{
std::cout << "OrderedArray full" << std::endl;
return;
}
if(m_pdValues == 0)
{
m_pdValues = new double[1];
m_nValuesLength = 1;
m_pdValues[0] = dValue;
m_pnOrderKeys = new int[1];
m_nKeysLength = 1;
m_pnOrderKeys[0] = nKey;
}
else
{
int keysLengthTemp = m_nKeysLength;
for(int i = 0; i < keysLengthTemp; i++)
{
if(nKey < m_pnOrderKeys[i])
{
insertBefore(dValue, i);
insertBefore(nKey, i);
return;
}
}
insertLast(dValue);
insertLast(nKey);
}
}
~OrderedArray()
{
delete m_pdValues;
delete m_pnOrderKeys;
}
int getLength() { return m_nValuesLength; }
double* getValuesArray()
{
assert(m_nValuesLength == 3);
return m_pdValues;
}
int getSumOfKeys()
{
assert(m_nKeysLength == 3);
return m_pnOrderKeys[0] + m_pnOrderKeys[1] + m_pnOrderKeys[2];
}
};


Physics Formulae.cpp



#include "stdafx.h"
#include <math.h>
#include <iostream>
#include <string>
#include "OrderedArray.h"
#define PI 3.14159265358979323846
//func name = original leftside variable in formula + variable to solve for
int translate(std::string s)
{
if(s == "d")
return 0;
if(s == "vf")
return 1;
if(s == "a")
return 2;
if(s == "t")
return 3;
if(s == "vi")
return 4;
return -1;
}
double* shit(double x, double y, double z) //placeholder function to fill out funcarray
{
static double pdArray[2];
pdArray[0] = PI;
pdArray[1] = PI;
return pdArray;
} //vf does not contain d
double* vfvf(double a, double t, double vi)
{
static double pdArray[2];
pdArray[0] = vi + a * t;
pdArray[1] = PI;
return pdArray;
}

double* vfa(double vf, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (vf - vi) / t;
pdArray[1] = PI;
return pdArray;
}
double* vft(double vf, double a, double vi)
{
static double pdArray[2];
pdArray[0] = (vf - vi) / a;
pdArray[1] = PI;
return pdArray;
}
double* vfvi(double vf, double a, double t)
{
static double pdArray[2];
pdArray[0] = vf - a * t;
pdArray[1] = PI;
return pdArray;
}
//d does not contain vf
double* dd(double a, double t, double vi)
{
static double pdArray[2];
pdArray[0] = vi * t + 0.5 * a * t * t;
pdArray[1] = PI;
return pdArray;
}
double* da(double d, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (d - vi * t) / pow(t, 2) * 2;
pdArray[1] = PI;
return pdArray;
}
double* dt(double d, double a, double vi) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = 0 - (vi / a) + sqrt(pow(vi/a, 2) + 2 * d / a);
pdArray[1] = 0 - (vi / a) - sqrt(pow(vi/a, 2) + 2 * d / a);
return pdArray;
}
double* dvi(double d, double a, double t)
{
static double pdArray[2];
pdArray[0] = (d - 0.5 * a * t * t) / t;
pdArray[1] = PI;
return pdArray;
}
//dd does not contain a
double* ddd(double vf, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (vi + vf) / 2 * t;
pdArray[1] = PI;
return pdArray;
}
double* ddvf(double d, double t, double vi)
{
static double pdArray[2];
pdArray[0] = d / t * 2 - vi;
pdArray[1] = PI;
return pdArray;
}
double* ddt(double d, double vf, double vi)
{
static double pdArray[2];
pdArray[0] = d / (vi + vf) * 2;
pdArray[1] = PI;
return pdArray;
}
double* ddvi(double d, double vf, double t)
{
static double pdArray[2];
pdArray[0] = d / t * 2 - vf;
pdArray[1] = PI;
return pdArray;
}
//vf2 does not contain t
double* vf2d(double vf, double a, double vi)
{
static double pdArray[2];
pdArray[0] = (pow(vf, 2) - pow(vi, 2)) / 2 / a;
pdArray[1] = PI;
return pdArray;
}
double* vf2vf(double d, double a, double vi) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = sqrt(pow(vi, 2) + 2 * a * d);
pdArray[1] = 0 - sqrt(pow(vi, 2) + 2 * a * d);
return pdArray;
}
double* vf2a(double d, double vf, double vi)
{
static double pdArray[2];
pdArray[0] = (pow(vf, 2) - pow(vi, 2)) / 2 / d;
pdArray[1] = PI;
return pdArray;
}
double* vf2vi(double d, double vf, double a) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = sqrt(pow(vf, 2) - 2 * a * d);
pdArray[1] = 0 - sqrt(pow(vf, 2) - 2 * a * d);
return pdArray;
}

int _tmain(int argc, _TCHAR* argv)
{
double* (*funcArray[4][5])(double, double, double) = //[missing][unknown]
{
{shit, vfvf, vfa, vft, vfvi},
{dd, shit, da, dt, dvi},
{ddd, ddvf, shit, ddt, ddvi},
{vf2d, vf2vf, vf2a, shit, vf2vi}
};
OrderedArray OA = OrderedArray();
int nAccessVarMissing = -1;
int nAccessUnknownVar = -1;
using namespace std;
string s;
cout << "Which variable is unknown? (d, vf, vi, a or t)" << endl;
cin >> s;
nAccessUnknownVar = translate(s);
double dValueTemp = -1;
string strVarNameTemp = " ";
for(int i = 0; i < 3; i++)
{
cout << "Enter a known variable (d, vf, vi, a or t) followed by 'Enter' followed by the value of the variable: ";
cin >> strVarNameTemp;
cin >> dValueTemp;
OA.add(dValueTemp, translate(strVarNameTemp));
dValueTemp = -1;
strVarNameTemp = " ";
}
nAccessVarMissing = 1 + 2 + 3 + 4 - OA.getSumOfKeys() - nAccessUnknownVar;
if(nAccessVarMissing == 4)
{
cout << "Invalid combination of variables, vi must be either known or unknown" << endl;
cin.get();
exit(0);
}
cout << "unknown is: " << funcArray[nAccessVarMissing][nAccessUnknownVar](OA[0], OA[1], OA[2])[0] << endl;
double dTemp = funcArray[nAccessVarMissing][nAccessUnknownVar](OA[0], OA[1], OA[2])[1];
if(dTemp != PI)
cout << "unknown is: " << dTemp;
int x = 0;
cin >> x;
return 0;
}









share|improve this question
























  • I have a very similar project I'm working on. The code I use for the Kinematics part of it is here. I took a fairly different approach from you on it I think. I haven't looked it over too thoroughly but it looks like your code contains a lot of work that it doesn't have to.
    – Ulthran
    Dec 13 '15 at 4:45
















6












6








6







The program allows user to enter values for 3 of the following




  • initial velocity

  • final velocity

  • acceleration

  • displacement

  • time


and to specify an unknown (one of the previously mentioned variables). The program uses the Kinematic Equations to calculate the unknown.



I would like a review of the entire program. I have only studied programming online as a hobby so i have never received comments on my code. I want to become a better programmer and break any bad habits. Dont hold back on any criticism or praise, please comment anything you think of. What is inefficient/ unclear/ unnecessary? What can be improved or added? What is good? What approach would you have taken to the problem? Is the code understandable at all As far as I can tell the code at least works, does what it should.



OrderedArray.h, container class



#include "stdafx.h"
#include <assert.h>
#include <iostream>

class OrderedArray
{
private:
double* m_pdValues;
int* m_pnOrderKeys;
int m_nValuesLength;
int m_nKeysLength;
void erase()
{
delete m_pdValues;
delete m_pnOrderKeys;
m_pdValues = 0;
m_pnOrderKeys = 0;
m_nValuesLength = 0;
m_nKeysLength = 0;
}
public:
OrderedArray() : m_pdValues(0), m_nValuesLength(0), m_pnOrderKeys(0), m_nKeysLength(0)
{

}
double operator(int nIndex) //returns from values array
{
assert(nIndex >= 0 && nIndex < m_nValuesLength);
return m_pdValues[nIndex];
}
void insertLast(double dValue)
{
assert(nIndex >= 0 && nIndex <= m_nValuesLength);
double* pdValues = new double[m_nValuesLength + 1];
for (int i=0; i < m_nValuesLength; i++)
pdValues[i] = m_pdValues[i];
pdValues[m_nValuesLength] = dValue;
delete m_pdValues;
m_pdValues = pdValues;
m_nValuesLength += 1;
}
void insertLast(int nKey)
{
assert(nIndex >= 0 && nIndex <= m_nKeysLength);
int* pnKeys = new int[m_nKeysLength + 1];
for (int i=0; i < m_nKeysLength; i++)
pnKeys[i] = m_pnOrderKeys[i];
pnKeys[m_nKeysLength] = nKey;
delete m_pnOrderKeys;
m_pnOrderKeys = pnKeys;
m_nKeysLength += 1;
}
void insertBefore(double dValue, int nIndex)
{
assert(nIndex >= 0 && nIndex <= m_nValuesLength);
double* pdValues = new double[m_nValuesLength + 1];
for (int nBefore=0; nBefore < nIndex; nBefore++)
pdValues[nBefore] = m_pdValues[nBefore];
pdValues[nIndex] = dValue;
for (int nAfter=nIndex; nAfter < m_nValuesLength; nAfter++)
pdValues[nAfter+1] = m_pdValues[nAfter];
delete m_pdValues;
m_pdValues = pdValues;
m_nValuesLength += 1;
}
void insertBefore(int nKey, int nIndex)
{
assert(nIndex >= 0 && nIndex <= m_nKeysLength);
int* pnKeys = new int[m_nKeysLength + 1];
for (int nBefore=0; nBefore < nIndex; nBefore++)
pnKeys[nBefore] = m_pnOrderKeys[nBefore];
pnKeys[nIndex] = nKey;
for (int nAfter=nIndex; nAfter < m_nKeysLength; nAfter++)
pnKeys[nAfter+1] = m_pnOrderKeys[nAfter];
delete m_pnOrderKeys;
m_pnOrderKeys = pnKeys;
m_nKeysLength += 1;
}
void add(double dValue, int nKey)
{
if(m_nValuesLength >= 3)
{
std::cout << "OrderedArray full" << std::endl;
return;
}
if(m_pdValues == 0)
{
m_pdValues = new double[1];
m_nValuesLength = 1;
m_pdValues[0] = dValue;
m_pnOrderKeys = new int[1];
m_nKeysLength = 1;
m_pnOrderKeys[0] = nKey;
}
else
{
int keysLengthTemp = m_nKeysLength;
for(int i = 0; i < keysLengthTemp; i++)
{
if(nKey < m_pnOrderKeys[i])
{
insertBefore(dValue, i);
insertBefore(nKey, i);
return;
}
}
insertLast(dValue);
insertLast(nKey);
}
}
~OrderedArray()
{
delete m_pdValues;
delete m_pnOrderKeys;
}
int getLength() { return m_nValuesLength; }
double* getValuesArray()
{
assert(m_nValuesLength == 3);
return m_pdValues;
}
int getSumOfKeys()
{
assert(m_nKeysLength == 3);
return m_pnOrderKeys[0] + m_pnOrderKeys[1] + m_pnOrderKeys[2];
}
};


Physics Formulae.cpp



#include "stdafx.h"
#include <math.h>
#include <iostream>
#include <string>
#include "OrderedArray.h"
#define PI 3.14159265358979323846
//func name = original leftside variable in formula + variable to solve for
int translate(std::string s)
{
if(s == "d")
return 0;
if(s == "vf")
return 1;
if(s == "a")
return 2;
if(s == "t")
return 3;
if(s == "vi")
return 4;
return -1;
}
double* shit(double x, double y, double z) //placeholder function to fill out funcarray
{
static double pdArray[2];
pdArray[0] = PI;
pdArray[1] = PI;
return pdArray;
} //vf does not contain d
double* vfvf(double a, double t, double vi)
{
static double pdArray[2];
pdArray[0] = vi + a * t;
pdArray[1] = PI;
return pdArray;
}

double* vfa(double vf, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (vf - vi) / t;
pdArray[1] = PI;
return pdArray;
}
double* vft(double vf, double a, double vi)
{
static double pdArray[2];
pdArray[0] = (vf - vi) / a;
pdArray[1] = PI;
return pdArray;
}
double* vfvi(double vf, double a, double t)
{
static double pdArray[2];
pdArray[0] = vf - a * t;
pdArray[1] = PI;
return pdArray;
}
//d does not contain vf
double* dd(double a, double t, double vi)
{
static double pdArray[2];
pdArray[0] = vi * t + 0.5 * a * t * t;
pdArray[1] = PI;
return pdArray;
}
double* da(double d, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (d - vi * t) / pow(t, 2) * 2;
pdArray[1] = PI;
return pdArray;
}
double* dt(double d, double a, double vi) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = 0 - (vi / a) + sqrt(pow(vi/a, 2) + 2 * d / a);
pdArray[1] = 0 - (vi / a) - sqrt(pow(vi/a, 2) + 2 * d / a);
return pdArray;
}
double* dvi(double d, double a, double t)
{
static double pdArray[2];
pdArray[0] = (d - 0.5 * a * t * t) / t;
pdArray[1] = PI;
return pdArray;
}
//dd does not contain a
double* ddd(double vf, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (vi + vf) / 2 * t;
pdArray[1] = PI;
return pdArray;
}
double* ddvf(double d, double t, double vi)
{
static double pdArray[2];
pdArray[0] = d / t * 2 - vi;
pdArray[1] = PI;
return pdArray;
}
double* ddt(double d, double vf, double vi)
{
static double pdArray[2];
pdArray[0] = d / (vi + vf) * 2;
pdArray[1] = PI;
return pdArray;
}
double* ddvi(double d, double vf, double t)
{
static double pdArray[2];
pdArray[0] = d / t * 2 - vf;
pdArray[1] = PI;
return pdArray;
}
//vf2 does not contain t
double* vf2d(double vf, double a, double vi)
{
static double pdArray[2];
pdArray[0] = (pow(vf, 2) - pow(vi, 2)) / 2 / a;
pdArray[1] = PI;
return pdArray;
}
double* vf2vf(double d, double a, double vi) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = sqrt(pow(vi, 2) + 2 * a * d);
pdArray[1] = 0 - sqrt(pow(vi, 2) + 2 * a * d);
return pdArray;
}
double* vf2a(double d, double vf, double vi)
{
static double pdArray[2];
pdArray[0] = (pow(vf, 2) - pow(vi, 2)) / 2 / d;
pdArray[1] = PI;
return pdArray;
}
double* vf2vi(double d, double vf, double a) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = sqrt(pow(vf, 2) - 2 * a * d);
pdArray[1] = 0 - sqrt(pow(vf, 2) - 2 * a * d);
return pdArray;
}

int _tmain(int argc, _TCHAR* argv)
{
double* (*funcArray[4][5])(double, double, double) = //[missing][unknown]
{
{shit, vfvf, vfa, vft, vfvi},
{dd, shit, da, dt, dvi},
{ddd, ddvf, shit, ddt, ddvi},
{vf2d, vf2vf, vf2a, shit, vf2vi}
};
OrderedArray OA = OrderedArray();
int nAccessVarMissing = -1;
int nAccessUnknownVar = -1;
using namespace std;
string s;
cout << "Which variable is unknown? (d, vf, vi, a or t)" << endl;
cin >> s;
nAccessUnknownVar = translate(s);
double dValueTemp = -1;
string strVarNameTemp = " ";
for(int i = 0; i < 3; i++)
{
cout << "Enter a known variable (d, vf, vi, a or t) followed by 'Enter' followed by the value of the variable: ";
cin >> strVarNameTemp;
cin >> dValueTemp;
OA.add(dValueTemp, translate(strVarNameTemp));
dValueTemp = -1;
strVarNameTemp = " ";
}
nAccessVarMissing = 1 + 2 + 3 + 4 - OA.getSumOfKeys() - nAccessUnknownVar;
if(nAccessVarMissing == 4)
{
cout << "Invalid combination of variables, vi must be either known or unknown" << endl;
cin.get();
exit(0);
}
cout << "unknown is: " << funcArray[nAccessVarMissing][nAccessUnknownVar](OA[0], OA[1], OA[2])[0] << endl;
double dTemp = funcArray[nAccessVarMissing][nAccessUnknownVar](OA[0], OA[1], OA[2])[1];
if(dTemp != PI)
cout << "unknown is: " << dTemp;
int x = 0;
cin >> x;
return 0;
}









share|improve this question















The program allows user to enter values for 3 of the following




  • initial velocity

  • final velocity

  • acceleration

  • displacement

  • time


and to specify an unknown (one of the previously mentioned variables). The program uses the Kinematic Equations to calculate the unknown.



I would like a review of the entire program. I have only studied programming online as a hobby so i have never received comments on my code. I want to become a better programmer and break any bad habits. Dont hold back on any criticism or praise, please comment anything you think of. What is inefficient/ unclear/ unnecessary? What can be improved or added? What is good? What approach would you have taken to the problem? Is the code understandable at all As far as I can tell the code at least works, does what it should.



OrderedArray.h, container class



#include "stdafx.h"
#include <assert.h>
#include <iostream>

class OrderedArray
{
private:
double* m_pdValues;
int* m_pnOrderKeys;
int m_nValuesLength;
int m_nKeysLength;
void erase()
{
delete m_pdValues;
delete m_pnOrderKeys;
m_pdValues = 0;
m_pnOrderKeys = 0;
m_nValuesLength = 0;
m_nKeysLength = 0;
}
public:
OrderedArray() : m_pdValues(0), m_nValuesLength(0), m_pnOrderKeys(0), m_nKeysLength(0)
{

}
double operator(int nIndex) //returns from values array
{
assert(nIndex >= 0 && nIndex < m_nValuesLength);
return m_pdValues[nIndex];
}
void insertLast(double dValue)
{
assert(nIndex >= 0 && nIndex <= m_nValuesLength);
double* pdValues = new double[m_nValuesLength + 1];
for (int i=0; i < m_nValuesLength; i++)
pdValues[i] = m_pdValues[i];
pdValues[m_nValuesLength] = dValue;
delete m_pdValues;
m_pdValues = pdValues;
m_nValuesLength += 1;
}
void insertLast(int nKey)
{
assert(nIndex >= 0 && nIndex <= m_nKeysLength);
int* pnKeys = new int[m_nKeysLength + 1];
for (int i=0; i < m_nKeysLength; i++)
pnKeys[i] = m_pnOrderKeys[i];
pnKeys[m_nKeysLength] = nKey;
delete m_pnOrderKeys;
m_pnOrderKeys = pnKeys;
m_nKeysLength += 1;
}
void insertBefore(double dValue, int nIndex)
{
assert(nIndex >= 0 && nIndex <= m_nValuesLength);
double* pdValues = new double[m_nValuesLength + 1];
for (int nBefore=0; nBefore < nIndex; nBefore++)
pdValues[nBefore] = m_pdValues[nBefore];
pdValues[nIndex] = dValue;
for (int nAfter=nIndex; nAfter < m_nValuesLength; nAfter++)
pdValues[nAfter+1] = m_pdValues[nAfter];
delete m_pdValues;
m_pdValues = pdValues;
m_nValuesLength += 1;
}
void insertBefore(int nKey, int nIndex)
{
assert(nIndex >= 0 && nIndex <= m_nKeysLength);
int* pnKeys = new int[m_nKeysLength + 1];
for (int nBefore=0; nBefore < nIndex; nBefore++)
pnKeys[nBefore] = m_pnOrderKeys[nBefore];
pnKeys[nIndex] = nKey;
for (int nAfter=nIndex; nAfter < m_nKeysLength; nAfter++)
pnKeys[nAfter+1] = m_pnOrderKeys[nAfter];
delete m_pnOrderKeys;
m_pnOrderKeys = pnKeys;
m_nKeysLength += 1;
}
void add(double dValue, int nKey)
{
if(m_nValuesLength >= 3)
{
std::cout << "OrderedArray full" << std::endl;
return;
}
if(m_pdValues == 0)
{
m_pdValues = new double[1];
m_nValuesLength = 1;
m_pdValues[0] = dValue;
m_pnOrderKeys = new int[1];
m_nKeysLength = 1;
m_pnOrderKeys[0] = nKey;
}
else
{
int keysLengthTemp = m_nKeysLength;
for(int i = 0; i < keysLengthTemp; i++)
{
if(nKey < m_pnOrderKeys[i])
{
insertBefore(dValue, i);
insertBefore(nKey, i);
return;
}
}
insertLast(dValue);
insertLast(nKey);
}
}
~OrderedArray()
{
delete m_pdValues;
delete m_pnOrderKeys;
}
int getLength() { return m_nValuesLength; }
double* getValuesArray()
{
assert(m_nValuesLength == 3);
return m_pdValues;
}
int getSumOfKeys()
{
assert(m_nKeysLength == 3);
return m_pnOrderKeys[0] + m_pnOrderKeys[1] + m_pnOrderKeys[2];
}
};


Physics Formulae.cpp



#include "stdafx.h"
#include <math.h>
#include <iostream>
#include <string>
#include "OrderedArray.h"
#define PI 3.14159265358979323846
//func name = original leftside variable in formula + variable to solve for
int translate(std::string s)
{
if(s == "d")
return 0;
if(s == "vf")
return 1;
if(s == "a")
return 2;
if(s == "t")
return 3;
if(s == "vi")
return 4;
return -1;
}
double* shit(double x, double y, double z) //placeholder function to fill out funcarray
{
static double pdArray[2];
pdArray[0] = PI;
pdArray[1] = PI;
return pdArray;
} //vf does not contain d
double* vfvf(double a, double t, double vi)
{
static double pdArray[2];
pdArray[0] = vi + a * t;
pdArray[1] = PI;
return pdArray;
}

double* vfa(double vf, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (vf - vi) / t;
pdArray[1] = PI;
return pdArray;
}
double* vft(double vf, double a, double vi)
{
static double pdArray[2];
pdArray[0] = (vf - vi) / a;
pdArray[1] = PI;
return pdArray;
}
double* vfvi(double vf, double a, double t)
{
static double pdArray[2];
pdArray[0] = vf - a * t;
pdArray[1] = PI;
return pdArray;
}
//d does not contain vf
double* dd(double a, double t, double vi)
{
static double pdArray[2];
pdArray[0] = vi * t + 0.5 * a * t * t;
pdArray[1] = PI;
return pdArray;
}
double* da(double d, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (d - vi * t) / pow(t, 2) * 2;
pdArray[1] = PI;
return pdArray;
}
double* dt(double d, double a, double vi) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = 0 - (vi / a) + sqrt(pow(vi/a, 2) + 2 * d / a);
pdArray[1] = 0 - (vi / a) - sqrt(pow(vi/a, 2) + 2 * d / a);
return pdArray;
}
double* dvi(double d, double a, double t)
{
static double pdArray[2];
pdArray[0] = (d - 0.5 * a * t * t) / t;
pdArray[1] = PI;
return pdArray;
}
//dd does not contain a
double* ddd(double vf, double t, double vi)
{
static double pdArray[2];
pdArray[0] = (vi + vf) / 2 * t;
pdArray[1] = PI;
return pdArray;
}
double* ddvf(double d, double t, double vi)
{
static double pdArray[2];
pdArray[0] = d / t * 2 - vi;
pdArray[1] = PI;
return pdArray;
}
double* ddt(double d, double vf, double vi)
{
static double pdArray[2];
pdArray[0] = d / (vi + vf) * 2;
pdArray[1] = PI;
return pdArray;
}
double* ddvi(double d, double vf, double t)
{
static double pdArray[2];
pdArray[0] = d / t * 2 - vf;
pdArray[1] = PI;
return pdArray;
}
//vf2 does not contain t
double* vf2d(double vf, double a, double vi)
{
static double pdArray[2];
pdArray[0] = (pow(vf, 2) - pow(vi, 2)) / 2 / a;
pdArray[1] = PI;
return pdArray;
}
double* vf2vf(double d, double a, double vi) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = sqrt(pow(vi, 2) + 2 * a * d);
pdArray[1] = 0 - sqrt(pow(vi, 2) + 2 * a * d);
return pdArray;
}
double* vf2a(double d, double vf, double vi)
{
static double pdArray[2];
pdArray[0] = (pow(vf, 2) - pow(vi, 2)) / 2 / d;
pdArray[1] = PI;
return pdArray;
}
double* vf2vi(double d, double vf, double a) //RETURNS ARRAY
{
static double pdArray[2];
pdArray[0] = sqrt(pow(vf, 2) - 2 * a * d);
pdArray[1] = 0 - sqrt(pow(vf, 2) - 2 * a * d);
return pdArray;
}

int _tmain(int argc, _TCHAR* argv)
{
double* (*funcArray[4][5])(double, double, double) = //[missing][unknown]
{
{shit, vfvf, vfa, vft, vfvi},
{dd, shit, da, dt, dvi},
{ddd, ddvf, shit, ddt, ddvi},
{vf2d, vf2vf, vf2a, shit, vf2vi}
};
OrderedArray OA = OrderedArray();
int nAccessVarMissing = -1;
int nAccessUnknownVar = -1;
using namespace std;
string s;
cout << "Which variable is unknown? (d, vf, vi, a or t)" << endl;
cin >> s;
nAccessUnknownVar = translate(s);
double dValueTemp = -1;
string strVarNameTemp = " ";
for(int i = 0; i < 3; i++)
{
cout << "Enter a known variable (d, vf, vi, a or t) followed by 'Enter' followed by the value of the variable: ";
cin >> strVarNameTemp;
cin >> dValueTemp;
OA.add(dValueTemp, translate(strVarNameTemp));
dValueTemp = -1;
strVarNameTemp = " ";
}
nAccessVarMissing = 1 + 2 + 3 + 4 - OA.getSumOfKeys() - nAccessUnknownVar;
if(nAccessVarMissing == 4)
{
cout << "Invalid combination of variables, vi must be either known or unknown" << endl;
cin.get();
exit(0);
}
cout << "unknown is: " << funcArray[nAccessVarMissing][nAccessUnknownVar](OA[0], OA[1], OA[2])[0] << endl;
double dTemp = funcArray[nAccessVarMissing][nAccessUnknownVar](OA[0], OA[1], OA[2])[1];
if(dTemp != PI)
cout << "unknown is: " << dTemp;
int x = 0;
cin >> x;
return 0;
}






c++ beginner object-oriented array physics






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Oct 4 '15 at 16:36









SuperBiasedMan

11.8k52660




11.8k52660










asked Oct 4 '15 at 16:32









Johan Ribbing

311




311












  • I have a very similar project I'm working on. The code I use for the Kinematics part of it is here. I took a fairly different approach from you on it I think. I haven't looked it over too thoroughly but it looks like your code contains a lot of work that it doesn't have to.
    – Ulthran
    Dec 13 '15 at 4:45




















  • I have a very similar project I'm working on. The code I use for the Kinematics part of it is here. I took a fairly different approach from you on it I think. I haven't looked it over too thoroughly but it looks like your code contains a lot of work that it doesn't have to.
    – Ulthran
    Dec 13 '15 at 4:45


















I have a very similar project I'm working on. The code I use for the Kinematics part of it is here. I took a fairly different approach from you on it I think. I haven't looked it over too thoroughly but it looks like your code contains a lot of work that it doesn't have to.
– Ulthran
Dec 13 '15 at 4:45






I have a very similar project I'm working on. The code I use for the Kinematics part of it is here. I took a fairly different approach from you on it I think. I haven't looked it over too thoroughly but it looks like your code contains a lot of work that it doesn't have to.
– Ulthran
Dec 13 '15 at 4:45












2 Answers
2






active

oldest

votes


















8














This is pretty clever work for someone self taught! In my opinion, it's more work than is necessary, though. Your OrderedArray class looks like a cross between std::map and std::vector, but it also looks like it will never hold more than 4 elements, if I understand it correctly.



Simplify



I think you can do away with the OrderedArray class and the funcArray, and just use some enums and a switch statement. For example, something like this:



enum {
kUnknown_Displacement,
kUnknown_InitialVelocity,
kUnknown_FinalVelocity,
kUnknown_Acceleration,
kUnknown_Time
};


Then, after collecting your knowns, just do something simple like:



switch(unknown) {
case kUnknown_Displacement:
calculateDisplacement(initialVelocity, Acceleration, time); // or whatever variables you need
break;

case kUnknown_InitialVelocity:
// etc...
break;
};


Naming



The other thing I think you could improve is your naming. Function names like vfvf, vfa, and ddd don't tell a reader of the code (including you 6 months from now) what these functions actually do. Renaming them as I did in my example above to things like calculateDisplacement(), calculateAcceleration(), etc. would go a long way towards helping this.



Types



Each of your functions returns 2 values, and so you're returning them as an array. It's not clear to me what the meaning of each value is, but if it's something like an x and y of a point, you should make a Point type and use that. If it's a magnitude and angle, then you should make a structure with those members and use that. Another alternative is to return a std::tuple, though when the values are clearly related (like for a Point), it's better to put it into a structure with named members.



Don't reinvent the wheel



You made your own constant PI. You should use M_PI because it's portable and will have enough digits for the precision you need.






share|improve this answer





















  • Sorry, the returning of two values might be a bit unclear. Most of the functions only return one "legit" value and one rubbish value, PI. If you compile and test the program you will see that only the "legit" values are printed. The reason for needing to return two values is that some of the equations (marked by //RETURNS ARRAY) are quadratic and have 2 solutions. How would i go about collecting the knowns? The program does not know which 3 out of 5 possible knowns to collect.
    – Johan Ribbing
    Oct 4 '15 at 20:51










  • From your example switch block: assuming case kUnknownDisplacement is true, how should i implement checking which of the 3 then possible functions to call? (dd, ddd or vf2d) would not that become a very complex switch block?
    – Johan Ribbing
    Oct 4 '15 at 20:52








  • 1




    Regarding some functions returning 1 value and some returning 2 - if that's the case, then you should create a structure or class which represents that. For example, you could have an object which tells how many values it contains, and allows you to get each solution. At the very least, it should be a std::vector so callers can determine how many values it contains. Though I think a custom class with appropriately named methods would be more clear.
    – user1118321
    Oct 4 '15 at 21:15






  • 2




    In terms of not wanting to create a huge switch statement - just break it into functions. For example, if the user is looking for kUnknown_Displacement, and there are 3 functions it could call, then make a function which further narrows it down to one of those 3 and call that function from the original switch statement. It's much easier to read, and maintain than a function table which needs to be edited any time you change a function name or whatever.
    – user1118321
    Oct 4 '15 at 21:17












  • I know we are not supposed to say thanks, but I really appreciate this guys! Thank you!
    – Johan Ribbing
    Oct 5 '15 at 6:25



















0














I did not understand a thing......






share|improve this answer








New contributor




user189330 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.


















    Your Answer





    StackExchange.ifUsing("editor", function () {
    return StackExchange.using("mathjaxEditing", function () {
    StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
    StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
    });
    });
    }, "mathjax-editing");

    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "196"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: false,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: null,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f106547%2fkinematic-equations-calculator%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    8














    This is pretty clever work for someone self taught! In my opinion, it's more work than is necessary, though. Your OrderedArray class looks like a cross between std::map and std::vector, but it also looks like it will never hold more than 4 elements, if I understand it correctly.



    Simplify



    I think you can do away with the OrderedArray class and the funcArray, and just use some enums and a switch statement. For example, something like this:



    enum {
    kUnknown_Displacement,
    kUnknown_InitialVelocity,
    kUnknown_FinalVelocity,
    kUnknown_Acceleration,
    kUnknown_Time
    };


    Then, after collecting your knowns, just do something simple like:



    switch(unknown) {
    case kUnknown_Displacement:
    calculateDisplacement(initialVelocity, Acceleration, time); // or whatever variables you need
    break;

    case kUnknown_InitialVelocity:
    // etc...
    break;
    };


    Naming



    The other thing I think you could improve is your naming. Function names like vfvf, vfa, and ddd don't tell a reader of the code (including you 6 months from now) what these functions actually do. Renaming them as I did in my example above to things like calculateDisplacement(), calculateAcceleration(), etc. would go a long way towards helping this.



    Types



    Each of your functions returns 2 values, and so you're returning them as an array. It's not clear to me what the meaning of each value is, but if it's something like an x and y of a point, you should make a Point type and use that. If it's a magnitude and angle, then you should make a structure with those members and use that. Another alternative is to return a std::tuple, though when the values are clearly related (like for a Point), it's better to put it into a structure with named members.



    Don't reinvent the wheel



    You made your own constant PI. You should use M_PI because it's portable and will have enough digits for the precision you need.






    share|improve this answer





















    • Sorry, the returning of two values might be a bit unclear. Most of the functions only return one "legit" value and one rubbish value, PI. If you compile and test the program you will see that only the "legit" values are printed. The reason for needing to return two values is that some of the equations (marked by //RETURNS ARRAY) are quadratic and have 2 solutions. How would i go about collecting the knowns? The program does not know which 3 out of 5 possible knowns to collect.
      – Johan Ribbing
      Oct 4 '15 at 20:51










    • From your example switch block: assuming case kUnknownDisplacement is true, how should i implement checking which of the 3 then possible functions to call? (dd, ddd or vf2d) would not that become a very complex switch block?
      – Johan Ribbing
      Oct 4 '15 at 20:52








    • 1




      Regarding some functions returning 1 value and some returning 2 - if that's the case, then you should create a structure or class which represents that. For example, you could have an object which tells how many values it contains, and allows you to get each solution. At the very least, it should be a std::vector so callers can determine how many values it contains. Though I think a custom class with appropriately named methods would be more clear.
      – user1118321
      Oct 4 '15 at 21:15






    • 2




      In terms of not wanting to create a huge switch statement - just break it into functions. For example, if the user is looking for kUnknown_Displacement, and there are 3 functions it could call, then make a function which further narrows it down to one of those 3 and call that function from the original switch statement. It's much easier to read, and maintain than a function table which needs to be edited any time you change a function name or whatever.
      – user1118321
      Oct 4 '15 at 21:17












    • I know we are not supposed to say thanks, but I really appreciate this guys! Thank you!
      – Johan Ribbing
      Oct 5 '15 at 6:25
















    8














    This is pretty clever work for someone self taught! In my opinion, it's more work than is necessary, though. Your OrderedArray class looks like a cross between std::map and std::vector, but it also looks like it will never hold more than 4 elements, if I understand it correctly.



    Simplify



    I think you can do away with the OrderedArray class and the funcArray, and just use some enums and a switch statement. For example, something like this:



    enum {
    kUnknown_Displacement,
    kUnknown_InitialVelocity,
    kUnknown_FinalVelocity,
    kUnknown_Acceleration,
    kUnknown_Time
    };


    Then, after collecting your knowns, just do something simple like:



    switch(unknown) {
    case kUnknown_Displacement:
    calculateDisplacement(initialVelocity, Acceleration, time); // or whatever variables you need
    break;

    case kUnknown_InitialVelocity:
    // etc...
    break;
    };


    Naming



    The other thing I think you could improve is your naming. Function names like vfvf, vfa, and ddd don't tell a reader of the code (including you 6 months from now) what these functions actually do. Renaming them as I did in my example above to things like calculateDisplacement(), calculateAcceleration(), etc. would go a long way towards helping this.



    Types



    Each of your functions returns 2 values, and so you're returning them as an array. It's not clear to me what the meaning of each value is, but if it's something like an x and y of a point, you should make a Point type and use that. If it's a magnitude and angle, then you should make a structure with those members and use that. Another alternative is to return a std::tuple, though when the values are clearly related (like for a Point), it's better to put it into a structure with named members.



    Don't reinvent the wheel



    You made your own constant PI. You should use M_PI because it's portable and will have enough digits for the precision you need.






    share|improve this answer





















    • Sorry, the returning of two values might be a bit unclear. Most of the functions only return one "legit" value and one rubbish value, PI. If you compile and test the program you will see that only the "legit" values are printed. The reason for needing to return two values is that some of the equations (marked by //RETURNS ARRAY) are quadratic and have 2 solutions. How would i go about collecting the knowns? The program does not know which 3 out of 5 possible knowns to collect.
      – Johan Ribbing
      Oct 4 '15 at 20:51










    • From your example switch block: assuming case kUnknownDisplacement is true, how should i implement checking which of the 3 then possible functions to call? (dd, ddd or vf2d) would not that become a very complex switch block?
      – Johan Ribbing
      Oct 4 '15 at 20:52








    • 1




      Regarding some functions returning 1 value and some returning 2 - if that's the case, then you should create a structure or class which represents that. For example, you could have an object which tells how many values it contains, and allows you to get each solution. At the very least, it should be a std::vector so callers can determine how many values it contains. Though I think a custom class with appropriately named methods would be more clear.
      – user1118321
      Oct 4 '15 at 21:15






    • 2




      In terms of not wanting to create a huge switch statement - just break it into functions. For example, if the user is looking for kUnknown_Displacement, and there are 3 functions it could call, then make a function which further narrows it down to one of those 3 and call that function from the original switch statement. It's much easier to read, and maintain than a function table which needs to be edited any time you change a function name or whatever.
      – user1118321
      Oct 4 '15 at 21:17












    • I know we are not supposed to say thanks, but I really appreciate this guys! Thank you!
      – Johan Ribbing
      Oct 5 '15 at 6:25














    8












    8








    8






    This is pretty clever work for someone self taught! In my opinion, it's more work than is necessary, though. Your OrderedArray class looks like a cross between std::map and std::vector, but it also looks like it will never hold more than 4 elements, if I understand it correctly.



    Simplify



    I think you can do away with the OrderedArray class and the funcArray, and just use some enums and a switch statement. For example, something like this:



    enum {
    kUnknown_Displacement,
    kUnknown_InitialVelocity,
    kUnknown_FinalVelocity,
    kUnknown_Acceleration,
    kUnknown_Time
    };


    Then, after collecting your knowns, just do something simple like:



    switch(unknown) {
    case kUnknown_Displacement:
    calculateDisplacement(initialVelocity, Acceleration, time); // or whatever variables you need
    break;

    case kUnknown_InitialVelocity:
    // etc...
    break;
    };


    Naming



    The other thing I think you could improve is your naming. Function names like vfvf, vfa, and ddd don't tell a reader of the code (including you 6 months from now) what these functions actually do. Renaming them as I did in my example above to things like calculateDisplacement(), calculateAcceleration(), etc. would go a long way towards helping this.



    Types



    Each of your functions returns 2 values, and so you're returning them as an array. It's not clear to me what the meaning of each value is, but if it's something like an x and y of a point, you should make a Point type and use that. If it's a magnitude and angle, then you should make a structure with those members and use that. Another alternative is to return a std::tuple, though when the values are clearly related (like for a Point), it's better to put it into a structure with named members.



    Don't reinvent the wheel



    You made your own constant PI. You should use M_PI because it's portable and will have enough digits for the precision you need.






    share|improve this answer












    This is pretty clever work for someone self taught! In my opinion, it's more work than is necessary, though. Your OrderedArray class looks like a cross between std::map and std::vector, but it also looks like it will never hold more than 4 elements, if I understand it correctly.



    Simplify



    I think you can do away with the OrderedArray class and the funcArray, and just use some enums and a switch statement. For example, something like this:



    enum {
    kUnknown_Displacement,
    kUnknown_InitialVelocity,
    kUnknown_FinalVelocity,
    kUnknown_Acceleration,
    kUnknown_Time
    };


    Then, after collecting your knowns, just do something simple like:



    switch(unknown) {
    case kUnknown_Displacement:
    calculateDisplacement(initialVelocity, Acceleration, time); // or whatever variables you need
    break;

    case kUnknown_InitialVelocity:
    // etc...
    break;
    };


    Naming



    The other thing I think you could improve is your naming. Function names like vfvf, vfa, and ddd don't tell a reader of the code (including you 6 months from now) what these functions actually do. Renaming them as I did in my example above to things like calculateDisplacement(), calculateAcceleration(), etc. would go a long way towards helping this.



    Types



    Each of your functions returns 2 values, and so you're returning them as an array. It's not clear to me what the meaning of each value is, but if it's something like an x and y of a point, you should make a Point type and use that. If it's a magnitude and angle, then you should make a structure with those members and use that. Another alternative is to return a std::tuple, though when the values are clearly related (like for a Point), it's better to put it into a structure with named members.



    Don't reinvent the wheel



    You made your own constant PI. You should use M_PI because it's portable and will have enough digits for the precision you need.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Oct 4 '15 at 18:14









    user1118321

    10.8k11145




    10.8k11145












    • Sorry, the returning of two values might be a bit unclear. Most of the functions only return one "legit" value and one rubbish value, PI. If you compile and test the program you will see that only the "legit" values are printed. The reason for needing to return two values is that some of the equations (marked by //RETURNS ARRAY) are quadratic and have 2 solutions. How would i go about collecting the knowns? The program does not know which 3 out of 5 possible knowns to collect.
      – Johan Ribbing
      Oct 4 '15 at 20:51










    • From your example switch block: assuming case kUnknownDisplacement is true, how should i implement checking which of the 3 then possible functions to call? (dd, ddd or vf2d) would not that become a very complex switch block?
      – Johan Ribbing
      Oct 4 '15 at 20:52








    • 1




      Regarding some functions returning 1 value and some returning 2 - if that's the case, then you should create a structure or class which represents that. For example, you could have an object which tells how many values it contains, and allows you to get each solution. At the very least, it should be a std::vector so callers can determine how many values it contains. Though I think a custom class with appropriately named methods would be more clear.
      – user1118321
      Oct 4 '15 at 21:15






    • 2




      In terms of not wanting to create a huge switch statement - just break it into functions. For example, if the user is looking for kUnknown_Displacement, and there are 3 functions it could call, then make a function which further narrows it down to one of those 3 and call that function from the original switch statement. It's much easier to read, and maintain than a function table which needs to be edited any time you change a function name or whatever.
      – user1118321
      Oct 4 '15 at 21:17












    • I know we are not supposed to say thanks, but I really appreciate this guys! Thank you!
      – Johan Ribbing
      Oct 5 '15 at 6:25


















    • Sorry, the returning of two values might be a bit unclear. Most of the functions only return one "legit" value and one rubbish value, PI. If you compile and test the program you will see that only the "legit" values are printed. The reason for needing to return two values is that some of the equations (marked by //RETURNS ARRAY) are quadratic and have 2 solutions. How would i go about collecting the knowns? The program does not know which 3 out of 5 possible knowns to collect.
      – Johan Ribbing
      Oct 4 '15 at 20:51










    • From your example switch block: assuming case kUnknownDisplacement is true, how should i implement checking which of the 3 then possible functions to call? (dd, ddd or vf2d) would not that become a very complex switch block?
      – Johan Ribbing
      Oct 4 '15 at 20:52








    • 1




      Regarding some functions returning 1 value and some returning 2 - if that's the case, then you should create a structure or class which represents that. For example, you could have an object which tells how many values it contains, and allows you to get each solution. At the very least, it should be a std::vector so callers can determine how many values it contains. Though I think a custom class with appropriately named methods would be more clear.
      – user1118321
      Oct 4 '15 at 21:15






    • 2




      In terms of not wanting to create a huge switch statement - just break it into functions. For example, if the user is looking for kUnknown_Displacement, and there are 3 functions it could call, then make a function which further narrows it down to one of those 3 and call that function from the original switch statement. It's much easier to read, and maintain than a function table which needs to be edited any time you change a function name or whatever.
      – user1118321
      Oct 4 '15 at 21:17












    • I know we are not supposed to say thanks, but I really appreciate this guys! Thank you!
      – Johan Ribbing
      Oct 5 '15 at 6:25
















    Sorry, the returning of two values might be a bit unclear. Most of the functions only return one "legit" value and one rubbish value, PI. If you compile and test the program you will see that only the "legit" values are printed. The reason for needing to return two values is that some of the equations (marked by //RETURNS ARRAY) are quadratic and have 2 solutions. How would i go about collecting the knowns? The program does not know which 3 out of 5 possible knowns to collect.
    – Johan Ribbing
    Oct 4 '15 at 20:51




    Sorry, the returning of two values might be a bit unclear. Most of the functions only return one "legit" value and one rubbish value, PI. If you compile and test the program you will see that only the "legit" values are printed. The reason for needing to return two values is that some of the equations (marked by //RETURNS ARRAY) are quadratic and have 2 solutions. How would i go about collecting the knowns? The program does not know which 3 out of 5 possible knowns to collect.
    – Johan Ribbing
    Oct 4 '15 at 20:51












    From your example switch block: assuming case kUnknownDisplacement is true, how should i implement checking which of the 3 then possible functions to call? (dd, ddd or vf2d) would not that become a very complex switch block?
    – Johan Ribbing
    Oct 4 '15 at 20:52






    From your example switch block: assuming case kUnknownDisplacement is true, how should i implement checking which of the 3 then possible functions to call? (dd, ddd or vf2d) would not that become a very complex switch block?
    – Johan Ribbing
    Oct 4 '15 at 20:52






    1




    1




    Regarding some functions returning 1 value and some returning 2 - if that's the case, then you should create a structure or class which represents that. For example, you could have an object which tells how many values it contains, and allows you to get each solution. At the very least, it should be a std::vector so callers can determine how many values it contains. Though I think a custom class with appropriately named methods would be more clear.
    – user1118321
    Oct 4 '15 at 21:15




    Regarding some functions returning 1 value and some returning 2 - if that's the case, then you should create a structure or class which represents that. For example, you could have an object which tells how many values it contains, and allows you to get each solution. At the very least, it should be a std::vector so callers can determine how many values it contains. Though I think a custom class with appropriately named methods would be more clear.
    – user1118321
    Oct 4 '15 at 21:15




    2




    2




    In terms of not wanting to create a huge switch statement - just break it into functions. For example, if the user is looking for kUnknown_Displacement, and there are 3 functions it could call, then make a function which further narrows it down to one of those 3 and call that function from the original switch statement. It's much easier to read, and maintain than a function table which needs to be edited any time you change a function name or whatever.
    – user1118321
    Oct 4 '15 at 21:17






    In terms of not wanting to create a huge switch statement - just break it into functions. For example, if the user is looking for kUnknown_Displacement, and there are 3 functions it could call, then make a function which further narrows it down to one of those 3 and call that function from the original switch statement. It's much easier to read, and maintain than a function table which needs to be edited any time you change a function name or whatever.
    – user1118321
    Oct 4 '15 at 21:17














    I know we are not supposed to say thanks, but I really appreciate this guys! Thank you!
    – Johan Ribbing
    Oct 5 '15 at 6:25




    I know we are not supposed to say thanks, but I really appreciate this guys! Thank you!
    – Johan Ribbing
    Oct 5 '15 at 6:25













    0














    I did not understand a thing......






    share|improve this answer








    New contributor




    user189330 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.























      0














      I did not understand a thing......






      share|improve this answer








      New contributor




      user189330 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





















        0












        0








        0






        I did not understand a thing......






        share|improve this answer








        New contributor




        user189330 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        I did not understand a thing......







        share|improve this answer








        New contributor




        user189330 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        share|improve this answer



        share|improve this answer






        New contributor




        user189330 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.









        answered 25 mins ago









        user189330

        1




        1




        New contributor




        user189330 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.





        New contributor





        user189330 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.






        user189330 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
        Check out our Code of Conduct.






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Code Review Stack Exchange!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            Use MathJax to format equations. MathJax reference.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f106547%2fkinematic-equations-calculator%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Costa Masnaga

            Fotorealismo

            Sidney Franklin