1

我有一小段代码从名为 lineList 的数组(在不同的类中)读取 Line2D 值,并将它们存储在名为 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;    
        }
    }

下面是第一个点(最低点)不包含在多边形点中的示例。 在此处输入图像描述

4

1 回答 1

4

对我来说似乎有很多重复的代码。在我们尝试更多调试之前,让我们重构代码并使其更易于理解和调试。

重构

我们可以提取的第一段代码是向多边形添加一个点的代码。这是新方法。

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

我想,WT​​F?我从未见过有人在方法调用中设置值。在 where 子句中,当然。

经过大约 5 分钟的思考,我意识到 Polygon 类的内部值是在执行 addPoint 方法之后设置的。虽然这可能对其他一些方法调用很有用,但这里没有必要。方法调用可以简化为

p.addPoint(x, y);

Java 开发人员,如果您需要另一个理由来使您的类变量不公开,这是一个非常好的理由。在您在 setter 方法中设置类变量后,阻止人们设置它们。

启动阅读

如果我们使用一种称为启动读取的鲜为人知的算法,我们可以摆脱第一次切换和大量代码。

大多数 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 行或 0 行执行该方法毫无意义。

  2. 我将 ArrayList 引用更改为 List。在 Java 中,最好在具体类上使用接口。由于我们在代码中使用的唯一 List 方法是 get 方法,因此我们可以使用接口。使用该接口的优点是 createPolygon 方法不关心 getLineList 方法是否返回 ArrayList、LinkedList 或实现 List 的自定义类。这使得将来的修改更容易。

于 2013-02-20T19:12:07.860 回答