Добавяне на многоъгълни точки от стойности на 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
напишете юнит тест и отстранете грешки.   -  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);

Помислих си, WTF? Никога не бях виждал някой да задава стойности в извикване на метод. В клауза 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