Объединение объектов формы для создания композита

#java #awt

#java #awt

Вопрос:

у меня есть программа, которую я должен выполнить, где я должен взять отдельные объекты формы и объединить их, чтобы создать окончательную форму автомобиля. нам даны готовые формы, такие как передняя шина, задняя шина, кузов, лобовое стекло и крыша, и предполагается объединить их в одну форму автомобиля. код, уже предоставленный мне, следующий:

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

теперь мне нужно создать класс compositeShape, в котором происходит объединение, но я не уверен, что делать в методе add(Shape). нам также сказали, что мы должны использовать метод pathiterator, но на самом деле нас не учили о pathiterator или о том, что мы должны с ним делать. Я не прошу, чтобы кто-то сказал мне, что именно кодировать, просто несколько полезных начальных моментов.

первое, что пришло мне в голову, было что-то вроде этого:

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

но это не работает, потому что я не могу создать экземпляр нового графического объекта, и я получаю исключение нулевого указателя. после этого я в значительной степени озадачен тем, что делать. любая помощь будет принята с благодарностью. Спасибо!

Комментарии:

1. Я бы хотел, чтобы мой класс CompositeShape, возможно, содержал ArrayList<Shape> и реализовал Shape , а затем переопределил все методы интерфейса. Вы увидите, где вам нужно будет использовать PathIterator .

Ответ №1:

Вероятно, вместо того, чтобы рисовать фигуру внутри метода add(), вы просто должны сохранить добавленную фигуру для последующего рисования. Вы могли бы сделать это, предоставив CompositeShape какую-то коллекцию для хранения добавленных фигур, и это все, что я бы добавил в метод add() . Помимо этого, это будет зависеть от того, какое другое поведение должно иметь CompositeShape. Если вам нужно иметь возможность рисовать CompositeShape, то вам, вероятно, будет предоставлен графический объект для рисования. Вам не придется создавать свои собственные. Тогда рисование CompositeShape будет означать рисование всех фигур, которые он содержит.

Комментарии:

1. спасибо за комментарий. я создал список массивов для хранения фигур, отправленных в объект compositeShape, но я не уверен, как нарисовать их на графике, потому что им не дано рисовать

2. 1 Graphics2D может draw() или fill() любой Shape , поэтому List<Shape> является хорошей переменной-членом CompositeShape .

3. @Wonger: Вам действительно нужно графически рисовать композитную форму или это просто теоретическое упражнение? Если вам нужно выполнить рисование, есть ли у вас в настоящее время способ рисования фигуры?

Ответ №2:

java.awt.geom.Область может объединять несколько фигур с помощью методов add , subtract, exclusiveOr и intersect . Это готовый класс для CompositeShape.

Кажется чрезвычайно странным, что вас попросили воссоздать его как «CompositeShape», потому что Area уже делает то, что вы хотите.

Решение может быть таким же простым, как

класс CompositeShape расширяет java.awt.geom.Область {}

и все готово.

Или тот факт, что вам дали подсказку о PathIterator, может заключаться в том, что вам предлагается управлять добавленными фигурами в списке вручную, а затем реализовать все методы интерфейса Shape в терминах итерации по другим фигурам.

Например, getBounds() должен возвращать прямоугольные границы фигуры, поэтому получите прямоугольные границы первой, затем используйте Rectangle.union, чтобы соединить ее с границами других.

И для getPathIterator() верните новый внутренний класс, реализующий PathIterator, который будет перебирать все фигуры в вашей коллекции и перебирать сегменты пути каждого из их методов getPathIterator, возвращая каждый сегмент пути.

На практике все это кажется ненужным, поскольку необходимый класс уже существует. Я думаю, вам следует получить разъяснения относительно того, что требуется. Удачи.


Чтобы пояснить, что я сказал о реализации getPathIterator , верните что-то вроде этого. Я не проверял это. Предполагается, что ваш список вызывается 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);
        }
    };
}
  

Комментарии:

1. привет, итак, я добавил фигуры в список, но я не уверен, куда идти с помощью pathiterator. я посмотрел метод getBounds(), но из того, что я вижу, он работает только с прямоугольными объектами, верно? что произойдет, если я вызову getbounds и эллипс или линию?

2. getBounds() возвращает прямоугольник, который полностью охватывает фигуру . Не имеет значения, какая это форма. Для PathIterator я отредактировал свой ответ.