gpt4 book ai didi

java - 如何使用双重分派(dispatch)来分析图元的交集?

转载 作者:行者123 更新时间:2023-11-30 08:29:30 24 4
gpt4 key购买 nike

我正在分析图形基元(矩形、直线、圆形等)的交互并计算重叠、相对方向、合并等。这被引用为双分派(dispatch)的主要示例(例如 Wikipedia )

Adaptive collision algorithms usually require that collisions between different objects be handled in different ways. A typical example is in a game environment where the collision between a spaceship and an asteroid is computed differently than the collision between a spaceship and a spacestation.1

但我还没有理解主要的解释,而且我也不大体上理解 SO 上的答案。

我当前的代码 (Java) 使用父类(super class) Shape,类似于:

for (int i = 0; i < shapes.size() - 1; i++) {
for (int j = i + 1; j < shapes.size(); j++) {
Shape shape = shapes.get(i).intersectionWith(shapes.get(j));
}
}

在子类(此处为 Rect)中具有特定实现,例如

public class Rect extends Shape {

public Shape intersectionWith(Shape shape) {
if (shape instanceof Rect) {
return this.getCommonBoundingBox((Rect)shape);
} else if (shape instanceof Line) {
return this.intersection((Line)shape);
} else if (shape instanceof Text) {
return this.intersection((Text) shape);
}
}
}

无论如何,我必须编写所有的 n*(n-1)/2 方法(并且已经这样做了)。我还必须有可扩展的代码来适应(比如)以后的日期:

        } else if (shape instanceof Circle) {
return this.intersection((Circle)shape);

我不知道如何使用双分派(dispatch)模式,也不知道它的值(value),希望有一个使用 Java 图形基元或类似伪代码的具体示例。

更新:我已经接受了@Flavio,因为(我认为)它回答了所问的确切问题。但是我实际上已经实现了@Slanec,因为它解决了我的问题并且(对我而言)更简单易读。我有一个附属问题“解决方案是否取决于对称关系?”。

“A 与 B 相交”通常等同于“B 与 A 相交”,但“A 与 B 碰撞”并不总是与“B 与 A 碰撞”相同。 (A == 汽车,B == 骑自行车的人)。可以想象,我的交叉点在未来可能不是对称的(例如,“Rect partially obscures Circle”不是对称的,可能有不同的语义。

@Flavio 很好地解决了维护问题,并指出编译器可以检查问题。 @Slanec 通过反射来做到这一点,它看起来像是一种有用的维护辅助工具——我不知道性能受到什么影响。

最佳答案

您可以通过 Visitor 模式在 Java 中实现双重分派(dispatch)。

public interface ShapeVisitor<P, R> { 
R visitRect(Rect rect, P param);
R visitLine(Line line, P param);
R visitText(Text text, P param);
}

public interface Shape {
<P, R> R accept(P param, ShapeVisitor<? super P, ? extends R> visitor);
Shape intersectionWith(Shape shape);
}

public class Rect implements Shape {

public <P, R> R accept(P param, ShapeVisitor<? super P, ? extends R> visitor) {
return visitor.visitRect(this, param);
}

public Shape intersectionWith(Shape shape) {
return shape.accept(this, RectIntersection);
}

public static ShapeVisitor<Rect, Shape> RectIntersection = new ShapeVisitor<Rect, Shape>() {
public Shape visitRect(Rect otherShape, Rect thisShape) {
// TODO...
}
public Shape visitLine(Line otherShape, Rect thisShape) {
// TODO...
}
public Shape visitText(Text otherShape, Rect thisShape) {
// TODO...
}
};
}

当您添加一个新的 Shape 子类时,您必须向 ShapeVisitor 接口(interface)添加一个新方法,并且您会因缺少的所有方法而出现编译错误。这很有用,但如果您正在编写一个库并且允许您的用户添加 Shape 子类(但显然不能扩展 ShapeVisitor 接口(interface)),这可能会成为一个大问题。

关于java - 如何使用双重分派(dispatch)来分析图元的交集?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19400582/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com