使用访客图案检测两个形状之间的相交 [英] Using Visitor Pattern to detect intersection between two shapes

查看:103
本文介绍了使用访客图案检测两个形状之间的相交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我意识到这是一个非常具体的问题,因此如果人们给出的答案包括有关如何执行此操作的明确代码,这将很有帮助。谢谢。

I realize this is a very specific question so it would be helpful if the answer people give includes explicit codes on how to do this. Thanks.

我有一个抽象的基类Shape:

I have an abstract base class Shape:

class Shape
{
    .....
    virtual bool GetIntersection(Shape* _shape) = 0;
}

class Circle : public Shape  {...}
class Triangle : public Shape {...}

这两个派生类均覆盖GetIntersection;

Both these derived classes overrides GetIntersection;

我有:

//main.cpp
....
Shape* shape;
Shape* circle = new Circle;

if(input == 0) shape = new Circle;
else shape = new Triangle;

circle->GetIntersection(shape);

这会导致错误。

I阅读有关访问者模式的内容,并认为这可能是解决我的问题的方法,因为我基本上需要确定GetIntersection的参数正在使用哪个派生类。有人可以解释我将如何针对这种情况实施访客模式吗?或者,如果还有其他更简单的解决方案。

I read something about visitor patterns and think that this might be the way to solve my problem as I basically need to determine which derived class the parameter to GetIntersection is using. Can someone explain how I would implement a visitor pattern for this case? Or if there is another simpler solution to this problem.

任何帮助将不胜感激。

推荐答案

我现在正面临着相同的问题,即不同形状之间的碰撞。

I'm right now facing the same problem with collisions between different shapes.

我认为我们不能按原样使用Visitor模式,因为它要求层次结构A的类(访问者)访问另一个层次结构B的类(访问的元素),其中B的类仅了解A的抽象(例如, IVisitor )而B的类知道A的子类( VisitedElement1 VisitedElement2 ... VisitedElement的子类)。

I think we cannot use the Visitor pattern "as is", because it requires that the classes of a hierarchy A (visitors) visit the classes of another hierarchy B (visited elements), where the classes of B only know about the abstraction of A (IVisitor, for example) while the classes of B know about the subclasses of A (VisitedElement1, VisitedElement2... subclasses of VisitedElement).

在我们的例子中,我们尝试访问Shapes with Shapes,同时保持Shape类与子类分离,因此,Visitor模式不适用。

In our case, we are trying to visit Shapes with Shapes while keeping our Shape class decoupled from the subclasses, so the Visitor pattern doesn't apply.

最好我能想到的解决方案是Shape类直接或通过另一个接口声明 GetSpecificIntersect所有子类型的离子方法:

The best solution I can think of is that the Shape class, directly or through another interface, declares "GetSpecificIntersection" methods for all the subtypes:

class Shape
{
    .....
public:
    virtual bool GetIntersection(Shape* _shape) = 0;    
protected:
    virtual bool GetSpecificIntersection(Circle* _circle) = 0;
    virtual bool GetSpecificIntersection(Triangle* _triangle) = 0;
}

class Circle
{
    .....
public:
    virtual bool GetIntersection(Shape* _shape);
    {
        return _shape->GetSpecificIntersection(this);
    }
protected:
    virtual bool GetSpecificIntersection(Circle* _circle) { ... }
    virtual bool GetSpecificIntersection(Triangle* _triangle) { ... }
}

class Triangle { /* analog to Circle */ }

因此,您必须为每种形状实现到任何其他形状的那些特定的相交方法,并将Shape类耦合到所有可能的形状。如果我没有记错,则违反了 OCP ,但保留了 LSP

Therefore, you must implement those specific intersection methods for each kind of shape to any other kind of shape and the Shape class is coupled to all the possible shapes. If I'm not wrong, this violates OCP but preserves LSP.

我刚想出的另一个选择是偏爱于继承而不是继承,并进行如下操作:

Another option I've just come up with is to "favor composition over inheritance" and make something like this:

class Shape
{
    .....
public:
    virtual bool GetIntersection(Shape* _shape)
    {
        return _shape->figure->GetIntersection(this->figure);
    }

private:
    Figure* figure;
}

class Figure
{
    .....
public:
    virtual bool GetIntersection(Figure* _figure) = 0;
protected:
    virtual bool GetSpecificIntersection(Circle* _circle) = 0;
    virtual bool GetSpecificIntersection(Triangle* _triangle) = 0;
}

class Circle
{
    .....
public:
    virtual bool GetIntersection(Figure* _figure)
    {
        return _figure->GetSpecificIntersection(this);
    }
protected:
    virtual bool GetSpecificIntersection(Circle* _circle) { ... }
    virtual bool GetSpecificIntersection(Triangle* _triangle) { ... }
}

class Triangle { /* analog to Circle */ }

与以前相同,但是通过执行此操作,可以将Shape类(游戏类使用的接口)与不同的 Figures(我并没有更好的名字)分离,因此应添加新的Figures甚至不会导致重新编译您的客户端类。这仅在图形层次结构中违反了 OCP ,并保留了 LSP 用于形状和图形。

It's the same as before, but by doing this you decouple your Shape class (which is the interface used by the classes of your game) from the different "Figures" (I didn't come up with a better name), so adding new Figures shouldn't even lead to recompile your client classes. This violates OCP only in the "Figures" hierarchy, and preserves LSP for both "Shape" and "Figure".

如果有人可以建议一种更好的方法,同时避免 downcasting ,我将非常感激:D

If someone can suggest a better way to do this while avoiding downcasting, I'll be very thankful :D

这篇关于使用访客图案检测两个形状之间的相交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆