Добавление точек многоугольника из значений Line2D

У меня есть небольшой блок кода, который считывает значения Line2D из массива с именем lineList (в другом классе) и сохраняет их в новом массиве с именем list. отсюда я пытался преобразовать все значения линии в точки многоугольника (точка для каждой координаты x, y конца линии).

до сих пор он работает, но не работает для самой первой точки первой строки в массиве (это то, что я подозреваю), который добавлен, и у меня возникли проблемы с поиском решения для этого, поскольку я пытался включить это в первый оператор if.

Я буду очень признателен за любую помощь, которую кто-либо может предоставить мне в этом.

Ниже приведен код, который я использую для добавления точек из значений Line2D:

Polygon p = new Polygon();
    ArrayList<Line2D> list = new ArrayList<Line2D>();
    Color pixel;
    boolean firstTime = true;

    list = segmentation.getLineList();

    //loop through lineList and add all x and y coordinates to relative x and y arrays
    for(int i = 0; i < list.size(); i++) {
        if(firstTime == true){
            Line2D line = list.get(i);
            Point2D startPoint = line.getP1();
            Point2D endPoint = line.getP2();
            int startX = (int) startPoint.getX();
            int startY = (int) startPoint.getY();
            int endX = (int) endPoint.getX();
            int endY = (int) endPoint.getY();
            p.addPoint(p.xpoints[i] = startX, p.ypoints[i] = startY);
            p.addPoint(p.xpoints[i] = endX, p.ypoints[i] = endY);
            startPoint = null;
            endPoint = null;
            line = null;
            firstTime = false;
        }
        else {
            Line2D line = list.get(i);
            Point2D endPoint = line.getP2();
            int endX = (int) endPoint.getX();
            int endY = (int) endPoint.getY();
            p.addPoint(p.xpoints[i] =  endX, p.ypoints[i] = endY);
            endPoint = null;
            line = null;    
        }
    }

Ниже приведен пример первой точки (самой нижней точки), не включенной в точки многоугольника. введите здесь описание изображения


person Mochi    schedule 20.02.2013    source источник
comment
Чтобы быстрее получить помощь, опубликуйте SSCCE.   -  person Andrew Thompson    schedule 20.02.2013
comment
написать тест junit и отладить.   -  person AlexWien    schedule 20.02.2013


Ответы (1)


Мне кажется, что много дублированного кода. Прежде чем мы попытаемся продолжить отладку, давайте реорганизуем код и упростим его понимание и отладку.

Рефакторинг

Первый фрагмент кода, который мы можем извлечь, — это код для добавления точки к многоугольнику. Вот новый метод.

protected void addPoint(Polygon p, Point2D point) {
    int x = (int) point.getX();
    int y = (int) point.getY();
    p.addPoint(x, y);
}

Я не дошел до этого за один рефакторинг. Я сначала вытащил код конечной точки, потому что он был идентичен. Еще немного поразмыслив над кодом, я обобщил его, чтобы использовать в качестве кода начальной точки.

Когда я впервые увидел эту строку кода

 p.addPoint(p.xpoints[i] = startX, p.ypoints[i] = startY);

Я подумал, ВТФ? Я никогда не видел, чтобы кто-то устанавливал значения в вызове метода. Конечно, в предложении where.

Примерно через 5 минут размышлений я понял, что внутренние значения класса Polygon устанавливаются после выполнения метода addPoint. Хотя это может быть полезно при вызове какого-либо другого метода, здесь в этом нет необходимости. Вызов метода можно упростить до

p.addPoint(x, y);

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

Предварительное чтение

Мы можем избавиться от первого переключения времени и большого количества кода, если воспользуемся малоизвестным алгоритмом, называемым первичным чтением.

Большинство циклов for имеют оператор ввода в качестве первого оператора в цикле. Конструкция цикла for (String s : stringList) скрывает тот факт, что оператор ввода является первым оператором в цикле.

Но иногда у вас есть метод, в котором вам нужно предварительное чтение. Этот метод как раз из таких.

В псевдокоде начальное чтение работает следующим образом.

Read input
for loop
    process input
    read input
end loop
process last input

Используя предварительное чтение, я смог значительно упростить метод createPolygon.

Любой программист на Cobol, прочитав это, подумал: «Ага, прайминг читал».

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

Рефакторинг кода

public Polygon createPolygon(Segmentation segmentation) {
    Polygon p = new Polygon();
    List<Line2D> list = segmentation.getLineList();
    if (list.size() < 2) return p;

    Line2D line = list.get(0);
    addPoint(p, line.getP1());

    // loop through lineList and add all x and y coordinates to relative x
    // and y arrays
    for (int i = 1; i < list.size(); i++) {
        addPoint(p, line.getP2());
        line = list.get(i);
    }

    addPoint(p, line.getP2());
    return p;
}

protected void addPoint(Polygon p, Point2D point) {
    int x = (int) point.getX();
    int y = (int) point.getY();
    p.addPoint(x, y);
}

Я сделал две дополнительные вещи в коде.

  1. Я добавил тест менее чем на 2 строки. По сути, для создания треугольника (многоугольника) требуется как минимум 2 линии. Не было смысла выполнять метод для 1 строки или нуля строк.

  2. Я изменил ссылку ArrayList на List. В Java лучше использовать интерфейс над конкретным классом. Поскольку единственным методом List, который мы используем в коде, является метод get, мы можем использовать интерфейс. Преимущество использования интерфейса заключается в том, что методу createPolygon не важно, возвращает ли метод getLineList ArrayList, LinkedList или пользовательский класс, реализующий List. Это упрощает будущие модификации.

person Gilbert Le Blanc    schedule 20.02.2013
comment
@AlexWien Я отлаживал его, но у меня были проблемы из-за того, что я видел, как все значения делают именно то, что я ожидал, но с неправильными результатами. Это помогло мне понять, почему я ошибаюсь, а не просто стало ответом на мою первоначальную проблему. - person Mochi; 21.02.2013