{NOTE sorry if this question is poorly worded, I'm a very basic C++ user.} I want to create a method that either selects one of the arguments in another method i've made, or applicably converts the argument. Let me explain more.
I am writing a simple program which presents vectors in either cartesian or spherical polar space. My cartesian vector looks like this:
{code removed}
And my spherical polar method looks like this:
{code removed}
I have already defined my xcoord, ycoord, xcoord variables in the private section of my class, and this code has all been written in the header file. Also the char unit == r or d is simply to identify between degrees or radian units (also to serve as a dummy variable to prevent overloading).
As you can see, I can now define some simple 3D vectors in my main, in either cartesian or spherical polar without the risk of overloading.
However, I now wish to create an access method which returns the values of theta or phi for either type of vector. This is easy for the cartesian coordinates, and my access method looks as such:
{code removed}
As you can see, the method 'getphi()' will convert the respective cartesian vector into a spherical polar quantity. However, if a vector (lets call it v1) is applied to the method in the main as v1.getphi(), then my code will clearly only work if v1 is cartesian. If v1 is polar, it will use r and theta in the method, clearly wrong.
I want to add a statement, most likely using if/else, which identifies between my vectors as either cartesian or polar. If the vector is polar, instead of having to convert to polar as shown above, I want the method to simply return the coordinate phi or theta with no modification to it (much like it does in the access method for cartesian coordinate section of my code above).
I think I have to exploit the number of arguments in the method 'threevector', but I dont know how to create a statement which recognises if the vector i'm applying to 'getphi()' or 'gettheta()' is either cartesian or polar.
Why not add a boolean variable to your class: bool isCartesian; ?
In your three argument constructor, set isCartesian = true;
In your four argument constructor, set isCartesian = false;
Then where you need to distinguish, simply test isCartesian.
Am I missing something? It's been a long time since I've dealt with this stuff.
That sounds like a really neat way of differentiating between them, but I have no idea how boolean variables work lol. What exactly do I need to test isCartesian?
Also @Marcos, here is my full class. Sorry if some of the code seems a little inessential, or lacking coherence, i'm still trying to piece things together
The easy solution (and the cleanest approach) is making your vector class have more private members describing it. A vector should have:
1 2 3 4 5
class threevector
{
private:
double phi, zeta; // Private data members, polar data
double xcoord, ycoord, zcoord; // Private data members, cartesian data
Whichever constructor user may employ, you get the info for the rest of the variables.
It's easiest this way, and by looking at the code, anyone can understand what a threevector's attributes are.
You don't need any boolean isCartesian to determine whether a threevector is cartesian or spherical polar coordinates since you always store the vector with its xyz coordinates. It doesn't even make sense to ask whether the vector is in Cartesian or spherical polar coordinates. For any vector you can get its coordinates in either coordinate system.
1 2 3 4 5 6 7 8 9
threevector v( 1.0, 2.0, 3.0 );
double x = v.getx();
double y = v.gety();
double z = v.getz();
double phi = v.getphi();
double theta = v.gettheta();
double radius = v.getr(); // You need to add this function to your class
You need to add the method double threevector::getr() to your class.
I'm assuming that your formulas are correct.
Edit:
I see you already have the equivalent of getr() in mag().
One other thought:
In your constructor threevector(double r, double theta, double phi, char unit) you might want to add tests for uppercase 'D' or 'R'.
if (unit == 'r' || unit == 'R') ...elseif (unit == 'd' || unit == 'D') ...
The user of the class shouldn't have to care about upper or lowercase.
If you use the toupper (or tolower) function, you can avoid testing the input twice.
1 2 3 4 5 6
#include <locale>
unit = std::toupper(unit);
if (unit == 'R') {}
elseif (unit == 'D'){}
It would also be good if you put the class declaration into a header file, put the implementation (the function definitions) into a .cpp file. The definitions would look like this:
1 2 3 4 5
void threevector::print() {
//your code here
}
Then there would be no need to call get functions like you do on line 102. Member functions have direct access to member variables.
The header file needs to be include in any .cpp file that needs to use that class.
It is a bad idea to include files that have implementation code in them, because they may be included multiple times in an application.
Also there is a convention to name member variables with a leading m_ . This makes it easier for naming parameters & member variables:
Obviously you need to change the declaration of the class. You can use find-replace to alter each appearance of xcoord etc in the .cpp file.
I think you should also have functions to convert from degrees to radians and vice versa. At the moment you have code that does that 5 times - it is better to have a function.
There you go - some stuff to have a go at & have fun!!