I am having trouble designing the part of my application that deals with geometry. In particular, I would like to have a hierarchy of classes and separate methods for intersections.
The problem
The hierarchy would be something like this:
- Geometry
- Mesh
- Parametric
- Box
- Sphere
 
 
And the intersection methods something like:
namespace intersections
{
  bool intersection( const Box &, const Box &);
  bool intersection( const Box &, const Sphere &);
}
This is quite simple. The problem arises now, when I want to store all geometries together in a single structure, say for example a std::vector (or a KD-Tree, or whatever).
To do that, I need to use a std::vector<Geometry*>. However, reading from this vector would get me Geometry* objects and thus I have no way of calling the appropriate intersection function.
Example of the problem:
std::vector<Geometry*> arrGeometry;
// add the elements
arrGeometry.push( new Box() );
arrGeometry.push( new Sphere() );
// ... some more code
// try to intersect them?
Geometry* g1 = arrGeometry[0];
Geometry* g2 = arrGeometry[1];
bool intersecting = intersections::intersection( g1, g2 ); //< As expected, this does
                                                          // not work
If I implemented the algorithms inside the geometry objects the problem could be solved by a visitor and some pretty weird function call bouncing.
However, I would like to keep the intersection algorithms outside the Geometry classes. the reasons are:
- to avoid deciding which should have the ownership (eg. where do you implement the intersection between box and sphere, in - Boxor in- Sphere?)
- to avoid cluttering the geometry objects will all that can be done to geometry, which is quite a lot (just to name a few: voxelize it, compute intersections, applying constructive geometry operators...). Thus, separating logic from data is quite desirable here. 
On the other hand, I need to have a hierarchy instead of templates because for some things the specific geometry can be abstracted away... (eg. for storing it in a std::vector, or a KD-Tree, or... ).
How would you solve this? Is there any design pattern appropriate for this? I tried looking at some libraries but I ended up more confused that I already was...
The easiest way (which is sometimes used) is to use RTTI (or to fake it) and downcastings, but that is not exactly maintainable... (adding a new geometry implies change a lot of switch statement though all the code).
Any thoughts?
Thanks you very much in advance.
 
     
     
    