2

我使用很多 2D 浮点多边形。我想出了一个用例,我需要从另一个中减去一个,所以我想我会使用 java.awt.geom.Area。我用四个点创建了一个 Area 对象:

100.0, 50.0
150.0, 0.0
151.41421356237308, 2.8284271247461112
99.99999999999973, 54.242640687118936

并且无论我在创建区域时如何排序这些点,我都会得到以下信息:

SEG_MOVETO, 150.0, 0.0
SEG_LINETO, 100.0, 50.0
SEG_LINETO, 99.99999999999973, 54.24264068711893
SEG_LINETO, 99.99999999999974, 54.24264068711893
SEG_LINETO, 151.41421356237308, 2.8284271247461112
SEG_LINETO, 150.0, 0.0
SEG_CLOSE, 150.0, 0.0

注意几乎相同的双99.99999999999973, 54.24264068711893坐标。

任何有关如何避免这种情况的线索都将受到欢迎。这是代码:

import java.awt.geom.Area;
import java.awt.geom.Path2D;
import java.awt.geom.PathIterator;

class Main {
    public static final void main( String args[] ) {
        double[] myPoly = {100.0, 50.0, 150.0, 0.0, 151.41421356237308, 2.8284271247461112, 99.99999999999973, 54.242640687118936};
        final Area myArea = makeArea(myPoly);
        System.out.println(areaToString(myArea));
    }

    private static Area makeArea(double coords[]) {
        final Path2D path = new Path2D.Double();
        path.moveTo(coords[0], coords[1]);
        for (int i = 2; i < coords.length; i+=2) {
            path.lineTo(coords[i], coords[i+1]);
        }
        path.closePath();
        return new Area(path);
    }

    private static String areaToString(final Area area) {
        final StringBuffer out = new StringBuffer("Area [\n");
        double []pt = new double[6];
        for (PathIterator pi = area.getPathIterator(null); !pi.isDone(); pi.next()) {
            int type = pi.currentSegment(pt);
            out.append(type).append(", ").append(pt[0]).append(", ").append(pt[1]).append("\n");
        }
        return out.append(']').toString();
    }
}
4

1 回答 1

0

如果仔细查看这些值,您会发现 99.99999999999973 和 99.99999999999974 彼此相差一个最小精度 (ULP) 单位。这是浮点数的常见问题。您不能准确地表示每个数字。

Path2D如果您更改内容并使用类似方法直接打印出对象,则不会发生任何重复。

区域状态的javadoc

即使原始轮廓简单明了,一个区域也可能需要更多的路径段来描述相同的几何图形。Area 类必须在路径上执行的分析可能与人类感知的“简单而明显”的概念不同。

所以总而言之,可能发生的是该区域优化了 Path 对象,从而引入了您看到的工件。我还没有深入研究 Area 的源代码,以了解这种特定的路径分解是如何选择的。

于 2016-06-07T22:12:29.217 回答