简体   繁体   中英

Java how to draw and fill a Polygon which has holes

I am currently trying to draw and fill a Polygon which has a hole in it in Java. Normally this would not be a big problem, since I would draw the exterior ring and then draw the interior ring with the color of the background.

But the problem is, that the polygon is displayed above a image which should be "seen" through the hole.

I am writing the code in Java and am using JTS Topology Suite for my geometry data.

This is my current code, which just paints the border and fills the polygon with a color.

private void drawPolygon(com.vividsolutions.jts.geom.Polygon gpoly, Color color, Graphics2D g2d){

    java.awt.Polygon poly = (java.awt.Polygon)gpoly;

    for(Coordinate co : gpoly.getExteriorRing().getCoordinates() {
        poly.addPoint(co.x, co.y);
    }
    g2d.setColor(col);
    g2d.fill(poly);

    g2d.setColor(Color.BLACK);
    g2d.draw(poly);
}

Sadly java.awt.Polygon does not support Polygons with holes.

  • Use the Polygon as the basis for an Area (eg called polygonShape ).
  • Create an Ellipse2D for the 'hole', then establish an Area for it ( ellipseShape ).
  • Use Area.subtract(Area) something like:

     Area polygonWithHole = polygonShape.subtract(ellipseShape); 

There are some ways to draw shapes or areas that are more complex than a simple polygon (another answer already mentioned Area ).

Besides those, you could try to tessellate your final polygon. There are lots of algorithms to do this. For more complex shapes, the algorithms get a bit more complex as well. Basically, you're dividing your final shape into little polygons (usually triangles, but it also can be something else) and then draw those polygons.

You can take a look at your possibilities by searching for "Tessellation Algorithm" , there are also some already implemented libraries for Java.

You can use java.awt.geom.Path2D to render a "compound shape" with a hole in it:

  • If you have java.awt.Shape objects defining the outside & inside edges of the shape, use append(shape, false) to add each shape.

  • If you have a set of path points for the outside edge and a set of path points for the inside edge, use lineTo() to add the first set of points - creating a closed loop by either ending with the same point you started with, or calling closePath() to automatically close the loop. Then use moveTo() to create a break before adding the inner set of points via more lineTo() calls.

In either case, you must create the path passing Path.WIND_NON_ZERO to the constructor - otherwise the hole won't be left unfilled.

See How to create shape with a hole? for a longer code example.

您可以先填充多边形,然后在顶部绘制孔,给人一种错觉,即除了孔之外它还可以填充所有东西。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM