java如何将多个矩形合并为一个多边形

java如何将多个矩形合并为一个多边形,java,algorithm,svg,geometry,batik,Java,Algorithm,Svg,Geometry,Batik,我希望有人能帮助我,因为我正在努力完成工作中的这部分任务。我故意不详细说明工作任务的背景,试图将重点放在问题上。我必须将矩形合并为一个多边形,如所附图像所示,但需要点列表,以便我可以将这些点写入Swing画布的多边形形状(DOM对象),然后导出SVG 我知道每个矩形的原点,即左上角的x和y坐标(浮动x,浮动y),以及每个矩形的宽度(浮动)和高度(浮动),因此可以由此计算每个矩形的所有四个角的坐标,即顶部、右侧、底部、左侧 即:顶部=原点=x,y,右侧=x+宽度,底部=x+宽度,y+高度,左侧=

我希望有人能帮助我,因为我正在努力完成工作中的这部分任务。我故意不详细说明工作任务的背景,试图将重点放在问题上。我必须将矩形合并为一个多边形,如所附图像所示,但需要点列表,以便我可以将这些点写入Swing画布的多边形形状(DOM对象),然后导出SVG

我知道每个矩形的原点,即左上角的x和y坐标(浮动x,浮动y),以及每个矩形的宽度(浮动)和高度(浮动),因此可以由此计算每个矩形的所有四个角的坐标,即顶部、右侧、底部、左侧 即:顶部=原点=x,y,右侧=x+宽度,底部=x+宽度,y+高度,左侧=x,y+高度

我有一个
列表矩形
,希望有一个算法能将这个列表转换成一个多边形(
列表
),其中一个点代表每个点的坐标(x,y),如标有红色“x”s的图所示

然后,我将使用这个点列表在DOM中写出一个元素,以便最终在SVG中打印网页。因此,我的最终结果必须是一个点列表(即,在SVG中构建多边形形状的x、y坐标)

我确实看到了这个答案,它做了一些类似的事情,但不确定我是否可以将其应用到我的案例中——它也是用Python编写的,而不是Java


这是我和同事提出的一个解决方案。希望它能帮助其他人

public class PolygonHelper {

    public Polygon makePolygon(List<Rectangle> rectangles){
        List<Point> points = calcPoints(rectangles);
        return new Polygon(points);
    }

    private List<Point> calcPoints(List<Rectangle> rectangles) {
        List<Point> ret = new ArrayList<>();

        List<Float> yCoords = new ArrayList<>(getAllYCoords(rectangles));
        yCoords.sort(Comparator.naturalOrder());

        float previousLeftCoord = 0;
        float previousRightCoord = 0;

        for(float yCoord : yCoords) {
            System.out.println("Considering yCoords "+ yCoord);
            float minimumXLeftCoord = minXLeftCoord(yCoord, rectangles);
            float maximumXRightCoord = maxXRightCoord(yCoord, rectangles);
            System.out.println("min X: "+minimumXLeftCoord);
            System.out.println("max X: "+maximumXRightCoord);

            if(yCoord == yCoords.get(0)) {
                ret.add(new Point(minimumXLeftCoord, yCoord));
                ret.add(new Point(maximumXRightCoord, yCoord));

            } else {

                if(minimumXLeftCoord!=previousLeftCoord) {
                    ret.add(0, new Point(previousLeftCoord, yCoord));
                    ret.add(0, new Point(minimumXLeftCoord, yCoord));
                } else {
                    ret.add(0, new Point(minimumXLeftCoord, yCoord));
                }

                if(maximumXRightCoord!=previousRightCoord) {
                    ret.add(new Point(previousRightCoord, yCoord));
                    ret.add(new Point(maximumXRightCoord, yCoord));
                } else {
                    ret.add(new Point(maximumXRightCoord, yCoord));
                }

            }

            previousLeftCoord = minimumXLeftCoord;
            previousRightCoord = maximumXRightCoord;
            System.out.println(ret);
        }

        return ret;

    }

    private Set<Float> getAllYCoords(List<Rectangle> rectangles) {
        List<Float> allBottomYCoords = rectangles.stream().map(rectangle -> rectangle.getBottom().getY()).collect(Collectors.toList());
        List<Float> allTopYCoords = rectangles.stream().map(rectangle -> rectangle.getTop().getY()).collect(Collectors.toList());

        Set<Float> allCoords = new HashSet<>();
        allCoords.addAll(allTopYCoords);
        allCoords.addAll(allBottomYCoords);
        return allCoords;
    }

    private float minXLeftCoord(Float y, List<Rectangle> rectangles) {
        return rectanglesAtY(y, rectangles).stream().map(rect -> rect.getLeft().getX()).min(Comparator.naturalOrder()).get();
    }

    private float maxXRightCoord(Float y, List<Rectangle> rectangles) {
        return rectanglesAtY(y, rectangles).stream().map(rect -> rect.getRight().getX()).max(Comparator.naturalOrder()).get();
    }

    private List<Rectangle> rectanglesAtY(Float y, List<Rectangle> rectangles) {
        List<Rectangle> rectsAtYExcBottomLines = rectsAtYExcBottomLines(y, rectangles);

        if(rectsAtYExcBottomLines.size()>0) {
            // there are rectangles that are not closing here, so ignore those that are closing.
            return rectsAtYExcBottomLines;
        } else {
            // there are only rectangle bottom lines so we need to consider them.
            return rectsAtYIncBottomLines(y, rectangles);
        }
    }

    private List<Rectangle> rectsAtYExcBottomLines(Float y, List<Rectangle> rectangles) {
        return rectangles.stream()
                .filter(rect -> rect.getTop().getY()<=y && rect.getBottom().getY()>y).collect(Collectors.toList());
    }

    private List<Rectangle> rectsAtYIncBottomLines(Float y, List<Rectangle> rectangles) {
        return rectangles.stream()
                .filter(rect -> rect.getTop().getY()<=y && rect.getBottom().getY()==y).collect(Collectors.toList());
    }

}
公共类PolygonHelper{
公共多边形生成多边形(列表矩形){
列表点=计算点(矩形);
返回新多边形(点);
}
私有列表计算点(列表矩形){
List ret=new ArrayList();
List yCoords=newarraylist(getAllYCoords(矩形));
sort(Comparator.naturalOrder());
float-previousLeftCoord=0;
float-previousRightCoord=0;
用于(浮动yCoord:yCoords){
System.out.println(“考虑yCoord”+yCoord);
float minimumXLeftCoord=minXLeftCoord(yCoord,矩形);
float maximumXRightCoord=maxXRightCoord(yCoord,矩形);
System.out.println(“最小X:+minimumXLeftCoord”);
System.out.println(“max X:+maximumXRightCoord”);
if(yCoord==yCoords.get(0)){
ret.add(新点(最小XleftCoord,yCoord));
ret.add(新点(maximumXRightCoord,yCoord));
}否则{
如果(最小XleftCoord!=以前的左坐标){
ret.add(0,新点(先前的leftcoord,yCoord));
重新添加(0,新点(最小XleftCoord,yCoord));
}否则{
重新添加(0,新点(最小XleftCoord,yCoord));
}
if(maximumXRightCoord!=先前的RightCoord){
ret.add(新点(先前的RightCoord,yCoord));
ret.add(新点(maximumXRightCoord,yCoord));
}否则{
ret.add(新点(maximumXRightCoord,yCoord));
}
}
previousLeftCoord=最小XleftCoord;
previousRightCoord=maximumXRightCoord;
系统输出打印项次(ret);
}
返回ret;
}
私有集getAllYCoords(列表矩形){
列出allBottomYCoords=rectangles.stream().map(rectangle->rectangle.getBottom().getY()).collect(collector.toList());
列出allTopYCoords=rectangles.stream().map(rectangle->rectangle.getTop().getY()).collect(Collectors.toList());
Set allCoords=new HashSet();
allCoords.addAll(allTopYCoords);
allCoords.addAll(allBottomYCoords);
返回所有坐标;
}
私有浮点minXLeftCoord(浮点y,列表矩形){
返回rectanglesAtY(y,矩形).stream().map(rect->rect.getLeft().getX()).min(Comparator.naturalOrder()).get();
}
专用浮点maxXRightCoord(浮点y,列表矩形){
返回rectanglesAtY(y,矩形).stream().map(rect->rect.getRight().getX()).max(Comparator.naturalOrder()).get();
}
私有列表矩形(浮动y,列表矩形){
列表矩形xCBotomlines=矩形xCBotomlines(y,矩形);
if(rectsatyXcbootlines.size()>0){
//这里有一些矩形没有闭合,所以忽略那些闭合的矩形。
返回矩形条底线;
}否则{
//只有矩形底线,所以我们需要考虑它们。
返回矩形(y,矩形);
}
}
私有列表矩形X底线(浮动y,列表矩形){
返回矩形。stream()
.filter(rect->rect.getTop().getY()y).collect(collector.toList());
}
私有列表矩形SatyInCbottomlines(浮动y,列表矩形){
返回矩形。stream()

.filter(rect->rect.getTop().getY())你可以使用内置的API或这类学校作业吗?哪些内置的API?不,这不是学校作业-这是我工作中必须完成的任务的一部分。为什么这个问题已经被否决了?!因为你要求别人给你答案,而不是试图自己编码。你可以使用
区域
形状添加到一起。假设您使用的是类似于
java.awt.Rectangle
的东西,那么您可以将其包装在一个
区域
中,并将其添加到另一个
区域
,该区域表示最终状态。您还可以查看
java.awt.Rectangle
,因为它还有许多
add
方法我自己做了几次编码尝试,但我对我的解决方案不满意——它工作不正常,我认为它不会构成解决方案的基础,所以我决定将其丢弃,重新开始