API for intersection.

V

Victor Bogado

I want to create a program that has an "element" class, the element is
a graphic object that has a finite shape. It goes some what like
this :

class Element
{
public :
// Returns the minimum radius that encompass the holle element
double radius() = 0;

void center(double &x, double &y) = 0;

double distance(Element &e) = 0;

// naive implementation
bool intersect(Element &e)
{
return distance(*this) < radius() + e.radius();
}
};

Now suppose I have a decedent class that holds a "circle element" and
another that holds a "square element", how do I make a smarter
intersect that compares both of them? If I simply create a "bool
intersect(CircleElement &e)" in the SquareElement class it will not be
called if I use this code :

Element *a = new CircleElement(...);
Element *b = new SquareElement(...);

if (b->intersect(a)) {...}

Because C++ does not make the dynamic binding on the parameters, only
on the class. So the best I can do is to compare a SquareElement to a
generic element. Is there a way out? How this is done usually?
 
V

Victor Bazarov

Victor said:
I want to create a program that has an "element" class, the element is
a graphic object that has a finite shape. It goes some what like
this :

class Element
{
[..]
// naive implementation
bool intersect(Element &e)
{
return distance(*this) < radius() + e.radius();
}
};

Now suppose I have a decedent class that holds a "circle element" and
another that holds a "square element", how do I make a smarter
intersect that compares both of them? [..] How this is done usually?

Read about "double dispatch". You will most likely have to make your
'Element' aware of all descendants, and then implement No-Op functions
that would 'intersect' the 'Element' with any of those. And then make
the descendants implement those they know about in a funny redirected
way:

class Element { // Circle Square Triangle will derive
public:
virtual bool intersectCircle(Element&) { return false; }
virtual bool intersectSquare(Element&) { return false; }
virtual bool intersectCircle(Element&) { return false; }
virtual bool intersect(Element&) = 0;
};


class Circle : public Element {
public:
virtual bool intersectCircle(Element&);
virtual bool intersectSquare(Element&);
virtual bool intersectCircle(Element&);
virtual bool intersect(Element& e) {
return e.intersectCircle(*this);
}
};

class Square : public Element {
public:
virtual bool intersectCircle(Element&);
virtual bool intersectSquare(Element&);
virtual bool intersectCircle(Element&);
virtual bool intersect(Element& e) {
return e.intersectSquare(*this);
}
};

class Triangle : public Element {
public:
virtual bool intersectCircle(Element&);
virtual bool intersectSquare(Element&);
virtual bool intersectCircle(Element&);
virtual bool intersect(Element& e) {
return e.intersectTriangle(*this);
}
};

The other functions implement as intended/required.

V
 
G

Gianni Mariani

Victor said:
I want to create a program that has an "element" class, the element is
a graphic object that has a finite shape. It goes some what like
this :

class Element
{
public :
// Returns the minimum radius that encompass the holle element
double radius() = 0;

void center(double &x, double &y) = 0;

double distance(Element &e) = 0;

// naive implementation
bool intersect(Element &e)
{
return distance(*this) < radius() + e.radius();
}
};

Now suppose I have a decedent class that holds a "circle element" and
another that holds a "square element", how do I make a smarter
intersect that compares both of them? If I simply create a "bool
intersect(CircleElement &e)" in the SquareElement class it will not be
called if I use this code :

Element *a = new CircleElement(...);
Element *b = new SquareElement(...);

if (b->intersect(a)) {...}

Because C++ does not make the dynamic binding on the parameters, only
on the class. So the best I can do is to compare a SquareElement to a
generic element. Is there a way out? How this is done usually?

Victor described one way. The static method of doing does not extend
easily.

The way I've done these things in the past is to have a dynamic system
where you register all the types of algorithms (Square/Square,
Circle/Square etc) and select the algorithm based on the type of
intersection. It still breaks down when you have 2 different people
extend the class types and you're left with missing methods, but you can
implement a rudimentary generic geometry like spline or nurb and
degenerate your interestions into these types as an approximation.
 
M

Mark P

Victor said:
Victor said:
I want to create a program that has an "element" class, the element is
a graphic object that has a finite shape. It goes some what like
this :

class Element
{
[..]
// naive implementation
bool intersect(Element &e)
{
return distance(*this) < radius() + e.radius();
}
};

Now suppose I have a decedent class that holds a "circle element" and
another that holds a "square element", how do I make a smarter
intersect that compares both of them? [..] How this is done usually?

Read about "double dispatch". You will most likely have to make your
'Element' aware of all descendants, and then implement No-Op functions
that would 'intersect' the 'Element' with any of those. And then make
the descendants implement those they know about in a funny redirected
way

To the OP, Scott Meyers discusses this topic at length (~30 pages, IIRC)
in "More Effective C++". Well worth checking out.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top