开发者

How to clip a Path2D?

开发者 https://www.devze.com 2023-02-11 01:38 出处:网络
Is there a way to clip a Path2D to an are开发者_运维知识库a / other path2D instance? Simple Example (I am looking for something that will work in the general case where paths may include quads or cub

Is there a way to clip a Path2D to an are开发者_运维知识库a / other path2D instance?

Simple Example (I am looking for something that will work in the general case where paths may include quads or cubics and may or may not be singular):

I have a line segment (0,10) -> (30,10) which I would like to clip within the triangle (10,0), (20,20), (20,0) ideally yielding the line segment (15,10) -> (20,10)

I can convert the Path2D to an area using "new Area(Shape);" and then clip using "Area.intersect(area)", but this will return an empty area if the path is unclosed.

I can clip a drawing area using "Graphics2D.clip(Shape)", but I wish to have the returned shape (There are cases where I will want to do further operations before actually rendering)

After scouring the API documentation, I can find no way of doing this directly. Am I missing something?


The reason you cannot clip a Path using Area is that a Path2D object has zero area. The width of a path is undefined. The Area class is strictly for use with objects that have area.

You can clip a drawing, because you have defined a stroke width, which is used in defining the area of a path.

So, if you want to clip a path, you need to create a stroked shape from the path, using Stroke.createStrokedShape(Shape)

Here's an example:

public static void main(String[] args) throws IOException {

    String imgFormat = "PNG";

    Path2D path = new Path2D.Double();
    BasicStroke pathStroke = 
        new BasicStroke( 2 );


    // Create the path to be clipped:       
    int pathPoints[] = { 0, 10, 30, 10 };
    path.moveTo( pathPoints[ 0 ], pathPoints[1] );
    for( int i = 2; i < pathPoints.length; i+=2 ) {
        path.lineTo( pathPoints[ i ], pathPoints[ i+1 ] );
    }
    // Create the shape representing the clip area
    Polygon clipShape = new Polygon();
    int triPoints[] = { 10, 0, 20, 20, 20, 0 };
    for( int i = 0; i < triPoints.length; i+=2 ) {
        clipShape.addPoint( triPoints[i], triPoints[i+1] );
    }
    // Create the path with area using the stroke
    Shape clippedPath = pathStroke.createStrokedShape( path );

    // Apply a scale so the image is easier to see
    int scale = 10;
    AffineTransform at = AffineTransform.getScaleInstance( scale, scale );
    Shape sPath = at.createTransformedShape( path );
    Shape sClip = at.createTransformedShape( clipShape );

    // Create the Area shape that represents the path that is clipped by the clipShape
    Area clipArea = new Area( sClip );
    clipArea.intersect( new Area( at.createTransformedShape( clippedPath ) ) );


    int bbox = 10;
    Rectangle rect = sPath.getBounds();
    rect.add( sClip.getBounds() );
    // Expand the drawing area      
    rect.width += bbox;
    rect.height += bbox;
    rect.x -= bbox/2;
    rect.y -= bbox/2;
    BufferedImage img = new BufferedImage( rect.width, rect.height, BufferedImage.TYPE_INT_ARGB  );
    Graphics2D g2 = img.createGraphics();

    g2.setStroke( pathStroke );
    g2.setColor( Color.black );
    g2.draw( sPath );

    g2.setColor( Color.red );
    g2.draw( sClip );

    g2.setColor( Color.green );
    g2.draw( clipArea );

    g2.finalize();

    File img1 = new File( "/tmp/img1.png" );
    ImageIO.write( img, imgFormat, img1 );
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号