How do I use double dispatch to analyze intersection of graphic primitives?

peter.murray.rust

I am analyzing the interaction of graphics primitives (rect, line, circle, etc.) and computing the overlap, relative orientation, merging, etc. This is quoted as a prime example of Double Dispatch (e.g. 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

but I haven't understood the main explanations and I also don't generally understand the answers on SO.

My current code (Java) uses a superclass Shape and is something like:

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));
    }
}

with specific implementations in subclasses (here Rect) such as

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);
        }
    }
}

I have to write all the n*(n-1)/2 methods anyway (and have done so). I also have to have extensible code to accommodate (say) at a later date:

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

I don't see how to use, or the value of, the double dispatch pattern and would appreciate a concrete example using Java graphics primitives or similar pseudocde.

UPDATE: I have accepted @Flavio as (I think) it answers the exact question asked. However I have actually implemented @Slanec as it solves my problem and (to me) is simpler and easier to read. I have a subsidiary question "Do the solutions depend on the relationship being symmetric?".

"A intersects B" is usually identical to "B intersects A" but "A collides with B" is not always the same as "B collides with A". (A == car, B == cyclist). It is conceivable that my intersections may not be symmetric in futute (e.g. "Rect partially obscures Circle" is not symmetric and may have different semantics.

@Flavio addresses the maintenance problem well, and points out that the compiler can check for problems. @Slanec does this through reflection which looks as if it is a useful maintenance aid - I don't know what the performance hit is.

Flavio

You can implement double dispatch in Java through the Visitor pattern.

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...
        }
    };
}

When you add a new Shape subclass, you must add a new method to the ShapeVisitor interface, and you get compile errors for all the methods you are missing. This is useful, but can become a big problem if you are writing a library and your users are allowed to add Shape subclasses (but clearly can not extend the ShapeVisitor interface).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How do I use double dispatch to analyze intersection of graphic primitives?

From Dev

Do I use a graphic card?

From Dev

How do I use the union and intersection on a list of Counters of unknown length?

From Dev

How do I use dispatch_sync in swift?

From Dev

How do I block the current thread until OnComplete has finished executing without the use of traditional threading primitives?

From Dev

How do I overlay a Highchart with a SVG graphic?

From Dev

How do I align a graphic in iTextPDF?

From Dev

How do I disable the fancy graphic effects?

From Dev

How do I find the intersection of 2 sets?

From Dev

How do I find the intersection of 2 sets?

From Dev

How do I make a dispatch table in Rust?

From Dev

How do I set Nautilus to use same window on double click?

From Dev

How do I set Nautilus to use same window on double click?

From Dev

How can I use Watson NLP to analyze Keywords with JS?

From Dev

How do I move a graphic across the screen with arrow keys?

From Dev

How do I analyze performance of cpp / assembly code

From Dev

How do I analyze Groovy code with Sonarlint for IntelliJ?

From Dev

How Do I Analyze Frequency of Emacs Key Commands?

From Dev

How do I analyze journalctl logs outside of journalctl?

From Dev

Do I need to use `next` or `store.dispatch` in my middleware

From Dev

Use dispatch_async to analyze an array concurrently in Swift

From Dev

How do I call Methods expecting unknown primitives when I have Strings?

From Dev

How do I call Methods expecting unknown primitives when I have Strings?

From Dev

How could I use join query to find the intersection

From Dev

Do I really need 1 GB Ram for a graphic card if i'm going to use only for HPC?

From Dev

How do I divide city streets by intersection using PostGIS?

From Dev

How do I compute the intersection point of two lines?

From Dev

How do I find the intersection of two line segments?

From Dev

How do I plot the intersection of two fit lines in gnuplot?

Related Related

  1. 1

    How do I use double dispatch to analyze intersection of graphic primitives?

  2. 2

    Do I use a graphic card?

  3. 3

    How do I use the union and intersection on a list of Counters of unknown length?

  4. 4

    How do I use dispatch_sync in swift?

  5. 5

    How do I block the current thread until OnComplete has finished executing without the use of traditional threading primitives?

  6. 6

    How do I overlay a Highchart with a SVG graphic?

  7. 7

    How do I align a graphic in iTextPDF?

  8. 8

    How do I disable the fancy graphic effects?

  9. 9

    How do I find the intersection of 2 sets?

  10. 10

    How do I find the intersection of 2 sets?

  11. 11

    How do I make a dispatch table in Rust?

  12. 12

    How do I set Nautilus to use same window on double click?

  13. 13

    How do I set Nautilus to use same window on double click?

  14. 14

    How can I use Watson NLP to analyze Keywords with JS?

  15. 15

    How do I move a graphic across the screen with arrow keys?

  16. 16

    How do I analyze performance of cpp / assembly code

  17. 17

    How do I analyze Groovy code with Sonarlint for IntelliJ?

  18. 18

    How Do I Analyze Frequency of Emacs Key Commands?

  19. 19

    How do I analyze journalctl logs outside of journalctl?

  20. 20

    Do I need to use `next` or `store.dispatch` in my middleware

  21. 21

    Use dispatch_async to analyze an array concurrently in Swift

  22. 22

    How do I call Methods expecting unknown primitives when I have Strings?

  23. 23

    How do I call Methods expecting unknown primitives when I have Strings?

  24. 24

    How could I use join query to find the intersection

  25. 25

    Do I really need 1 GB Ram for a graphic card if i'm going to use only for HPC?

  26. 26

    How do I divide city streets by intersection using PostGIS?

  27. 27

    How do I compute the intersection point of two lines?

  28. 28

    How do I find the intersection of two line segments?

  29. 29

    How do I plot the intersection of two fit lines in gnuplot?

HotTag

Archive