Library of Classes

Pages: 123... 7
What should we work with first temperature, distance, time, etc.?
If I were you, I would make some sort of a "traits" class that has a list of all the separate SI "units" (time, distance, temperature) and their power (like meters squared).

Boost MPL has a nice example using their template metaprogramming library (tbh I don't fully understand how to use it though, heh)
We should actually make an effort to seperate units of different demensions. Maybe four seperate base classes for each of the observable dimensions (height, width, length, time_frame)? Of course they would be named differently for each base class. Height has no meaning to a 'Newton' after all.

Am I over complicating this? Please stop me if I am, I don't want to derail this project with my rambling.
Last edited on
@Computergeek01: To me, height, width and length are just distance measurements. height is height because I measure it from the ground up. It is just a convension. They are all distances (or lengths in the general sense).
Good point, maybe a better way to say it would be: "Magnitude, Direction.x, Direction.y, Direction.z, time_frame" can you think of any others?

EDIT: Frequency. Or is this a function of displacement and time? It's been awhile since I've taken physics :,(

We would have these properties as data members of only their relavent base classes.
Last edited on
And Newton = Mass * Length / (Time ^ 2) or kgms^-2 in SI units. :)

EDIT: And as firedraco suggested, I would do something like
1
2
3
4
5
6
class BaseUnitType {
   unsigned mass_order, length_order, time_order; // the powers of mass, length and time in the unit
public:
   double GetSIScaleFactor(); // returns a factor to scale the units to SI units so that variables                  
                                              // with different unit scales can be added, etc
}

One could then throw an exception if variables of mismatched units were operated on together.

There is of course much more to it than this: units have to be multiplied when two variables are multiplied and so forth.
[edit] @firedraco - fair point; I have now suggested a slightly different approach (on the last page). The unit type is now a member variable of another type.
Last edited on
I haven't taken physics in YEARS! and I can only read wikipedia so fast! LOL! Good catch though.
Frequency is in Hertz, I think, which has units of Time^-1 (i.e. "per second").

EDIT: I think all units should be expressible in terms of a mass unit, a length unit, a time unit and a current/charge unit. I'm not sure about temperature though :/

PS: I only remember all this stuff as I have a physics A Level in 4 weeks :D
Last edited on
@Computergeek01: I like the fact that you are thinking about vectors! But I think you are misplacing them. The classes should be scalar, meaning they only have a magnitude and units, no direction. You can then create a vector class:

1
2
3
4
5
6
7
8
9
10
11
12
13
template<class T>
class Vector2D
{
    //Since it is 2D, you can either store cartesian (X and Y components), or radial (magnitude + angle) coordinates.
    T X;
    T Y;
};

class Vector3D
{
    //Since it is 3D, you can choose cartesian, cylindrical or spherical coordinates.
...
};


Or see if you can create a class VectorND. I made those two classes separate to exemplify the different coordinate systems. Cartesian are the simplest, though and they can be generalized to N dimensions.
Each dimension would need it's own template, you may want to express two dimensions with different data types after all so why limit yourself? But you seem to be headed in the same direction with this.
Last edited on
@Xander: that would work, but then you would have to respecialize all of your operator *// if you wanted to add a new type...
How about
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class temperature
{
   public:
      double temp ;
      double temp2 ;
      double timeinminutes ;
      double changeintemppermin=(temp2-temp)/timeinminutes ;
} Far, Cel, Kel ; //user could input temp type, temp, temp2, and timeinminutes and find change in temp per minute.
class speed
{
   public:
      double dist ;
      double timeinhours ;
      double speed=dist/timeinhours ;
} meters, kilometers, feet, yards, miles ;
Last edited on
Wait what are you guys talking about?
I've given this a little thought and I believe each unit should be represented by a class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Unit //or class MeasurementUnit to be more explicit?
{
public:
    bool IsStandardUnit() = 0; //Returns true if it represents the standard unit for its dimension.
    double GetConversionFactor() = 0; //In derived classes it should return the conversion factor to whatever standard unit is decided.
};

class DistanceUnit : public Unit //A class just to base all distance unit classes like Meter, Foot, Yard, etc.
{ };

class Meter : public DistanceUnit
{
public:
    bool IsStandardUnit() { return true; } //Making Meter the standard unit for the Distance dimension.
    double GetConversionFactor() { return 1.0; } //Because it is the standard unit.
};

class Foot : public DistanceUnit
{
public:
    bool IsStandardUnit() { return false; } //Because Meter is the standard unit for Distance.
    double GetConversionFactor() { return 0.3048; } // 0.3048 meters = 1 foot.
};
//etc. 
And for compound dimensions I think there should be a CompoundUnit class that derives from Unit. I don't know what methods/data it would hold, but my OOP sense tells me it is the way to go. :-)
What about functions for the measurements?
Oh at bottom when done measurements, this is good I think we should pretty much stick with it!
Also, could prefixes be treated as units?? See this:

1
2
3
4
5
6
class Kilo : public Unit
{
public:
    bool IsStandardUnit() { return false; } //I don't have use for this one in this case.
    double GetConversionFactor() { return 1000; } //Because kilo = 1000.
};


And thinking about presentation, modify Unit like this:

1
2
3
4
5
6
7
8
class Unit
{
public:
    bool IsStandardUnit() = 0;
    double GetConversionFactor() = 0;
    std::string GetName() = 0;
    std::string GetSymbol() = 0;
};


The class Kilo would return "kilo" from GetName() and "k" (lowercase because that is the correct symbol) from GetSymbol(). And the library should allow std::string or std::wstring. I would vote for a conditional typedef, like the Windows SDK:

1
2
3
4
5
6
7
#ifndef tstring
#ifdef _UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif // _UNICODE
#endif // tstring 
See was I thinking a little different. What about a single class for each Quantity? Like for mass we have something like this:

1
2
3
4
5
6
7
8
9
10
11
template<class K> /*Negotiable, we might not need templates at all*/
class Mass
{
      private:
          K   gram;

      public:
          K   mass() {return gram;} /*Just the Mass*/
          K   massSI() {return 1000 * gram;} /*Mass in SI units*/
          K   massEN() {return 2.2 * gram;} //Have to test this one /*Mass in English Standard*/
// ETC. 

This way we are only using one class and we can even do the conversions on the fly without any extra code.

EDIT:
Mass may not have been the best choice for my demonstration but it's the only one that I knew the English conversion to off the top of my head.
Last edited on
What about the functions for this? Think ahead to that and it might give us the best way.
Pages: 123... 7