【问题标题】:Draw triangle with rounded corner画圆角三角形
【发布时间】:2015-08-12 09:55:14
【问题描述】:

我想在 Java Swing 中绘制一个顶点稍微平滑的三角形。我学会了如何用这几行代码画一个三角形

Polygon p=new Polygon (vertice_x, vertices_y, number_of_vertices);
g.drawPolygon(p);

但我对圆角一无所知。我读到 Graphics2D 中有一种方法可以让您绘制一个带有圆角边框的矩形,但对于一般的多边形?我该怎么做?

【问题讨论】:

标签: java swing polygon rounded-corners


【解决方案1】:

如果您想要相对少量的舍入,请查看 StrokeBasicStroke,它们允许您对任何多边形的角进行舍入。如果你想要一个非常圆的三角形,你必须自己构建线条形状。绘制圆弧而不是角,或使用样条线来创建形状。

这里是a tutorial for Strokes

【讨论】:

    【解决方案2】:

    为了更好地控制圆角(除了使用Stroke),您可以将 3 条线组合成边,3 条贝塞尔曲线组合成圆角。使用线性插值得到直线和曲线的起点/终点,角点是曲线的控制点。

    public Point interpolate(Point p1, Point p2, double t){
        return new Point((int)Math.round(p1.x * (1-t) + p2.x*t), 
                (int)Math.round(p1.y * (1-t) + p2.y*t));
    }
    
    Point p1 = new Point(50,10);
    Point p2 = new Point(10,100);
    Point p3 = new Point(100,100);
    
    Point p1p2a = interpolate(p1, p2, 0.2);
    Point p1p2b = interpolate(p1, p2, 0.8);
    
    Point p2p3a = interpolate(p2, p3, 0.2);
    Point p2p3b = interpolate(p2, p3, 0.8);
    
    Point p3p1a = interpolate(p3, p1, 0.2);
    Point p3p1b = interpolate(p3, p1, 0.8);
    ...
    
    g.drawLine(p1p2a.x, p1p2a.y, p1p2b.x, p1p2b.y);
    g.drawLine(p2p3a.x, p2p3a.y, p2p3b.x, p2p3b.y);
    g.drawLine(p3p1a.x, p3p1a.y, p3p1b.x, p3p1b.y);
    QuadCurve2D c1 = new QuadCurve2D.Double(p1p2b.x, p1p2b.y, p2.x, p2.y, p2p3a.x, p2p3a.y);
    QuadCurve2D c2 = new QuadCurve2D.Double(p2p3b.x, p2p3b.y, p3.x, p3.y, p3p1a.x, p3p1a.y);
    QuadCurve2D c3 = new QuadCurve2D.Double(p3p1b.x, p3p1b.y, p1.x, p1.y, p1p2a.x, p1p2a.y);
    g.draw(c1);
    g.draw(c2);
    g.draw(c3);
    

    在上面的代码中,您可以调整传递给interpolatet 参数来改变圆角的圆度。

    您还可以将所有这些附加到Path2DPath2D 实现了Shape 接口,其中允许将对象传递给Graphics2D.fill 以填充形状

    Path2D path = new Path2D.Double();
    AffineTransform at = new AffineTransform();
    path.moveTo(p1p2a.x, p1p2a.y);
    path.lineTo(p1p2b.x, p1p2b.y);
    path.append(c1.getPathIterator(at), true);
    path.lineTo(p2p3b.x, p2p3b.y);
    path.append(c2.getPathIterator(at), true);
    path.lineTo(p3p1b.x, p3p1b.y);
    path.append(c3.getPathIterator(at), true);
    path.closePath();
    g.fill(path);
    

    【讨论】:

    • 谢谢,因为这正是我需要的...只是另一个问题...如果我有彩色三角形?
    • 可以通过设置Graphics的颜色来改变颜色,例如g.setColor(Color.RED)
    • 我在最后一点上编辑/扩展了使用包含所有必需点的 Path2D 对象,允许您使用给定颜色填充形状。