开发者

Combining shape objects to create a composite

i have a pr开发者_开发知识库ogram i have to do where i have to take individual shape objects and combine them to create a final car shape. we are given premade shapes such as front tire, back tire, body, windshield, and roof and supposed to combine them into one car shape. the code already given to me is the following:

CompositeShape shape = new CompositeShape();

  final double WIDTH = 60;
  Rectangle2D.Double body
     = new Rectangle2D.Double(0, WIDTH / 6, 
        WIDTH, WIDTH / 6);
  Ellipse2D.Double frontTire
     = new Ellipse2D.Double(WIDTH / 6, WIDTH / 3, 
        WIDTH / 6, WIDTH / 6);
  Ellipse2D.Double rearTire
     = new Ellipse2D.Double(WIDTH * 2 / 3, WIDTH / 3,
        WIDTH / 6, WIDTH / 6);
  shape.add(body);
  shape.add(frontTire);
  shape.add(rearTire);

now, i have to create the compositeShape class which is where the combining takes place, but im not sure what to do in the add(Shape) method. we were also told that we were supposed to use a pathiterator method, but we werent really taught about pathiterator or what we are supposed to do with it. Im not asking for someone to tell me what exactly to code, just some helpful starter points.

the first thing that came to my mind was something like this:

public class CompositeShape implements Shape  {
    Graphics2D g2;
    public void add(Shape shape){
        g2.draw(shape);
    }

but it doesnt work because i cant instantiate a new graphics object and i get a null pointer exception. after that, im pretty much stumped as to what to do. any help would be greatly appreciated. thanks!


Probably, instead of drawing the Shape inside the add() method, you're just supposed to store the added Shape for drawing later. You could do that by giving CompositeShape some kind of collection to hold Shapes that are added, and that's all I'd put in the add() method. Beyond that, it would depend what other behavior CompositeShape is supposed to have. If you have to be able to draw a CompositeShape, then you'll probably be given an Graphics object to draw on. You won't have to create your own. Then drawing a CompositeShape would be drawing all of the Shapes that it contains.


java.awt.geom.Area can combine multiple shapes with methods add, subtract, exclusiveOr, and intersect. It's a ready-made class for CompositeShape.

It seems extremely weird that you've been asked to recreate it as "CompositeShape", because Area already does what you want.

The solution could be as simple as

class CompositeShape extends java.awt.geom.Area {}

and you're done.

Or, the fact that you've been given a hint about PathIterator, it might be that you're being encouraged to manage the added shapes in a list manually, then implement all the methods of the Shape interface in terms of iterating over the other shapes.

E.g., getBounds() needs to return the rectangular bounds of the shape, so get the rectangular bounds of the first, then use Rectangle.union to join it with the bounds of the others.

And for getPathIterator(), return a new inner class implementing PathIterator that will iterate over all the shapes in your collection, and iterate the path segments of each of their getPathIterator methods, returning each path segment.

It all sounds unnecessary in practice, since the needed class already exists. I think you should get clarification on what is wanted. Good luck.


To clarify what I said about the implementation of getPathIterator, return something like this. I didn't test this. This assumes your list is called shapes.

public PathIterator getPathIterator(final AffineTransform at, final double flatness) {
    return new PathIterator() {
        private PathIterator currentPathIterator;
        private Iterator<Shape> shapeIterator = shapes.iterator();
        { nextShape(); }

        private void nextShape() {
            if (shapeIterator.hasNext()) {
                currentPathIterator = shapeIterator.next().getPathIterator(at, flatness);
            } else {
                currentPathIterator = null;
            }
        }

        public int getWindingRule() {
            return WIND_NON_ZERO;
        }

        public boolean isDone() {
            for (;;) {
                if (currentPathIterator == null) return true;
                if (!currentPathIterator.isDone()) return false;
                nextShape();
            }
        }

        public void next() {
            currentPathIterator.next();
        }

        public int currentSegment(float[] coords) {
            return currentPathIterator.currentSegment(coords);
        }

        public int currentSegment(double[] coords) {
            return currentPathIterator.currentSegment(coords);
        }
    };
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜