在Java中用3色渐变填充三角形

时间:2017-01-01 10:30:51

标签: java graphics gradient

我无法找到解决此问题的方法。 我想在Java中用渐变绘制一个填充三角形,每个角都有不同的颜色。像这样:

enter image description here

我在网上发现了一些帖子,但我无法弄清楚如何在Java中使用渐变。问题是在Java中你只能从一种颜色到另一种颜色做GradientPaint,这不适合填充三角形。

到目前为止,我已经提出了这个代码无法按预期工作:

triangle.p1().getValue();
Color color1 = calculateColor(triangle.p1().getValue());
Color color2 = calculateColor(triangle.p2().getValue());
Color color3 = calculateColor(triangle.p3().getValue());
Color transparent = new Color(0, 0, 0, 0);
Polygon polygon = new Polygon(
        new int[]{(int) triangle.p1().x(), (int) triangle.p2().x(), (int) triangle.p3().x()},
        new int[]{(int) triangle.p1().y(), (int) triangle.p2().y(), (int) triangle.p3().y()},
        3);
GradientPaint gradient1 = new GradientPaint(
        (float) triangle.p1().x(), (float) triangle.p1().y(), color1,
        (float) triangle.p2().x(), (float) triangle.p2().y(), transparent);
GradientPaint gradient2 = new GradientPaint(
        (float) triangle.p2().x(), (float) triangle.p2().y(), color2,
        (float) triangle.p3().x(), (float) triangle.p3().y(), transparent);
GradientPaint gradient3 = new GradientPaint(
        (float) triangle.p3().x(), (float) triangle.p3().y(), color3,
        (float) triangle.p1().x(), (float) triangle.p1().y(), transparent);
graphics2d.setPaint(gradient1);
graphics2d.fill(polygon);
graphics2d.setPaint(gradient2);
graphics2d.fill(polygon);
graphics2d.setPaint(gradient3);
graphics2d.fill(polygon);

以下是我得到的结果:points A and B have the same color but the triangles adjacent to AB have different color

提到类似内容的一些主题: Triangle Gradient With Core GraphicsJava 3 Color Gradient

2 个答案:

答案 0 :(得分:2)

我意识到这是一个老问题,但问题仍未得到满意答复。

问题是没有合适的 java.awt.Paint 实现支持在三角形内插入颜色,其中颜色在三角形顶点处给出。这在计算机图形学(光栅化)中很常见,其中重心坐标用于确定三角形内某个点的混合权重(请参阅 https://www.khronos.org/registry/OpenGL/specs/gl/glspec14.pdf 部分 3.5.1)。

由于我也无法在网络上找到任何用于 java.awt.Graphics2D 的此类 Paint 实现的实现,因此我自己实现了它。你可以在这里找到它(标题为 BarycentricGradientPaint ):https://gist.github.com/hageldave/391bacc787f31d2fb2c7a10d1446c5f6

参考截图,注意第二个三角形是部分透明的,边缘是抗锯齿的。 AA 是通过 4x MSAA 方法实现的。

screenshot of the demo of the paint implementation

答案 1 :(得分:1)

这是基于这样的想法:如果你在三角形中选择任何颜色,它将从三角形的三个点创建三个区域。因此,我们扩展了线性插值原理

color=(distance to p1)/(distance p1, p2)*c1+(distance to p2)/distance(p1, p2)*c2;

到2-D平面。因此,加权系数将是以下区域:

public int areaTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
  return (int)(0.5*Math.abs((x1-x3)*(y2-y1)-(x1-x2)*(y3-y1)));
}

BufferedImage b=new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
Polygon pl=new Polygon();
pl.addPoint(100, 100); pl.addPoint(200, 150); pl.addPoint(150, 200);
Rectangle r=pl.getBounds();
int a=areaTriangle(pl.xpoints[0], pl.ypoints[0], pl.xpoints[1], pl.ypoints[1], pl.xpoints[2], pl.ypoints[2]);
int[] c1={255, 0, 0}, c2={0, 255, 0}, c3={0, 0, 255};
for(i=0; i<r.width; i++)
for(j=0; j<r.height; j++)
  if(pl.contains(r.x+i, r.y+j)) {
    int ix=r.x+i, jy=r.y+j;
    int a1=areaTriangle(ix, jy, pl.xpoints[0], pl.ypoints[0], pl.xpoints[1], pl.ypoints[1]);
    int a2=areaTriangle(ix, jy, pl.xpoints[0], pl.ypoints[0], pl.xpoints[2], pl.ypoints[2]);
    int a3=areaTriangle(ix, jy, pl.xpoints[1], pl.ypoints[1], pl.xpoints[2], pl.ypoints[2]);

    int[] c=new int[3];
//      for(l=0; l<3; l++) c[l]=(int)((1-1.0*a1/a)*c1[l]+(1-1.0*a2/a)*c2[l]+(1-1.0*a3/a)*c3[l]);
    for(l=0; l<3; l++) c[l]=(int)((1.0*a1/a)*c3[l]+(1.0*a2/a)*c2[l]+(1.0*a3/a)*c1[l]);
    b.setRGB(ix, jy, 0xff000000|(c[0]<<16)|(c[1]<<8)|c[2]);
  }

如果您尝试使用注释行,您将获得三种互补色。

相关问题