
Geoff Carlton <gcarlton <at> iinet.net.au> writes:
I'd like a simple, common set of geom classes.
Let's see If I can do something for you ..
The concept of these traits is a very interesting and clever one,
Thanks !
but I don't think its useful in practice.
Well, before you say this, let's examine together the problem we are facing. What I'm doing here is not just one more point class, there are already plenty of them ! for example : template<class T> class point /// Simplistic (Unrealistic) view of points { public: point(T x, T y); // Handy ctor T get_x() const; void set_x(T t); // ... point operator+=(const point& pt); point operator-=(const point& pt); void normalize(); private: T coord[2]; // X and Y in an array }; This sollution is really acceptable only if : - In all your life, all you'll ever need is cartesian points. - In all your life, all you'll ever need is cartesian points implemented that way (in an array). That is, you are forced to use one representation (cartesian) and one implementation of that representation (using the terminology introduced in the geom manual). For a boost library (that is supposed to be the best you can find), this is not acceptable. We want more, We want better ! So the idea is here: - There is reasonably no single representation (cartesian, polar, homogenous) of points that fits everyone on every project. - For every representation, there no single implementation that fits everyone on every project. - A real boost library has to deal with that, it can't just close its eyes and pretend the whole world only needs cartesian points implemented in an array of two elements. And of course that is not limited to points, other geometric abstractions also are concerned.
You'd want a simple set of classes,
Simple ? You can't be simple and as general as we want (as I explained above),
and if they are generically useful then the conversion to library variants is simple: either construct a new temporary,
I don't want to create a temporary array of 1000 points just to do the conversion, I want to work with a compatible array from the start ..
or even a straight reinterpret_cast for performance.
Not always possible. If the two representation are different you can surley kiss your reinterpret_cast goodbye. Example: You're using a cartesian point => Library needs polar points or homogeneous points You're using rectangles represented as a corner and a size => Library needs rectangle represented as opposite corners That was the problem, traits classes are the sollution ... (more about it in the manual)
In particular, the basics are:
In the following I'll present corresponding code using Boost.Geom. Assume that the following takes effect #include <boost/geom/point.hpp> #include <boost/geom/point_xy.hpp> // For the present example I'll use 2D cartesian points // Now handy usings using boost::geom::point_xy; using boost::geom::point;
1.) Easy definition Preferably: class point2i; // descended from point2<int> void DoSomething(const point2i& mypoint);
typedef point< point_xy<int> > point2i; void DoSomething(const point2i& mypoint);
Alternatively: template<class T> class point2;
typedef point2<int> mypoint2i;
void DoSomething(const point2i& mypoint);
2.) Easy instantiation Definitely: point2i pos(1,2);
typedef point< point_xy<int> > point2i; void DoSomething(const point2i& mypoint); point2i p=point_xy<int>(1, 2); // Also possible to init with polar data e.g // point2i p=point_polar(3, 3.141592654)
Ideally (somehow): point2i pos2[2] = { { 3, 4 }, { 5, 6 } };
This is also possible, after having written an implementation of points that uses arrays: point<point_xy_array> pos2[2]={ {3, 4}, {5, 6} } ; /////... Actually, I was planning to write such an implementation.
3.) Very clear class layout So we can know when reinterpreting the object is possible.
Actually with Boost.Geom, you'll never have to reinterpret_cast ! For example if the underlying library uses BB_POINT, you'll have: point<BB_POINT> pt; BB_DRAW_POINT(&pt.impl()) ; // The return type of pt.impl() is BB_POINT&
4.) Minimum of templates and macros Want this to be compile-able across the board, and simple to understand.
Well, not possible if we aim for generality (BTW Boost.Geom makes heavy use of templeates and about no use of macros ). Besides, do you really need to understand how Boost.Geom is implemented to use it effectively, I doubt it. Also, I don't think we should limit our imagination just because compiler such and such doesn't yet support (such a usual thing as) partial template specialization.
5.) Basic methods in class Length(), LengthSq(), Normalise(), etc
pt.rho(); // Access to the distance between the origin and pt pt.rho()=1; // Set the distance to 1 i.e normalizing ... // and many more
6.) Set of algorithm functions to operate on these types Similar to STL, a separate group of functions.
Hummm.. sounds good. If only you could give some precise examples of potentially useful algorithms.. -- Anis Benyelloul