如何剪辑 Path2D?

问题描述 投票:0回答:1

有没有办法将 Path2D 剪切到区域/其他 path2D 实例?

简单的例子(我正在寻找一些可以在一般情况下工作的东西,其中路径可能包括四边形或立方体,并且可能是或不是单数):

我有一条线段 (0,10) -> (30,10),我想将其夹在三角形 (10,0)、(20,20)、(20,0) 内,理想情况下会产生线段 ( 15,10) -> (20,10)

我可以使用“new Area(Shape);”将 Path2D 转换为区域然后使用“Area.intersect(area)”进行剪辑,但是如果路径未闭合,这将返回一个空白区域。

我可以使用“Graphics2D.clip(Shape)”剪辑绘图区域,但我希望获得返回的形状(在某些情况下,我想在实际渲染之前进行进一步的操作)

在浏览了 API 文档后,我找不到直接执行此操作的方法。我是不是错过了什么?

java java-2d
1个回答
5
投票

无法使用

Path
剪辑
Area
的原因是
Path2D
对象的面积为零。路径的
width
未定义。
Area
类严格用于具有面积的对象。

您可以剪辑绘图,因为您已经定义了笔划宽度,该宽度用于定义路径的区域。

因此,如果要剪切路径,则需要使用

Stroke.createStrokedShape(Shape)

从路径创建描边形状

这是一个例子:

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.dispose();
    
    File img1 = new File( "/tmp/img1.png" );
    ImageIO.write( img, imgFormat, img1 );
}
© www.soinside.com 2019 - 2024. All rights reserved.