从Line2D值添加多边形点

时间:2013-02-20 18:42:03

标签: java awt polygon java-2d point-in-polygon

我有一小段代码,它从一个名为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;    
        }
    }

下面是未包含在多边形点中的第一个点(最低点)的示例。 enter image description here

1 个答案:

答案 0 :(得分:4)

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

<强>重构

我们可以提取的第一部分代码是向Polygon添加一个点的代码。这是新方法。

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分钟的思考,我意识到在执行addPoint方法之后,Polygon类的内部值被设置为。虽然这可能对其他一些方法调用很有用,但这里没有必要。方法调用可以简化为

p.addPoint(x, y);

Java开发人员,如果您还需要另一个使您的类变量非公开的原因,这是一个非常好的。在您的setter方法中设置类变量之后,人们不会设置它们。

启动阅读

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

大多数for循环都将input语句作为循环中的第一个语句。循环的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的自定义类。这使得未来的修改更容易。