简体   繁体   English

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

[英]Fill triangle with 3 color gradient in Java

I was not able to find a solution for this problem.我无法找到解决此问题的方法。 I would like to paint a filled triangle in Java with gradient where each corner has different color.我想在 Java 中绘制一个带有渐变的填充三角形,其中每个角都有不同的颜色。 Something like this:像这样的东西:

在此处输入图片说明

I found some posts online but I was not able to figure out how to do the gradient in Java.我在网上找到了一些帖子,但我无法弄清楚如何在 Java 中进行渐变。 The problem is that in Java you can do GradientPaint only from one color to another, which is not suitable to fill a triangle.问题是在 Java 中你只能从一种颜色到另一种颜色做 GradientPaint,这不适合填充三角形。

So far I have come up with this code which does not work as expected:到目前为止,我想出了这个不能按预期工作的代码:

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);

Here is the result I am getting:这是我得到的结果: 点 A 和 B 具有相同的颜色,但与 AB 相邻的三角形具有不同的颜色

Some threads that mention similar thing: Triangle Gradient With Core Graphics and Java 3 Color Gradient一些提到类似事情的线程: Triangle Gradient With Core GraphicsJava 3 Color Gradient

This is based on the idea that if you pick any color inside the triangle it will create three areas from the three points of the triangle.这是基于这样的想法:如果您在三角形内选择任何颜色,它将从三角形的三个点创建三个区域。 Therefore we are extendng the principle of linear interpolation因此我们扩展了线性插值的原理

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

to the 2-D plane.到二维平面。 Thus the weighting coefficents will be areas:因此,加权系数将是区域:

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]);
  }

If you try the commented line you will get the three complementary colors.如果您尝试注释行,您将获得三种互补色。

I realize that this is an old question, still the issue has not been satisfactorily answered.我意识到这是一个老问题,但问题仍未得到令人满意的回答。

The problem is that there is no appropriate java.awt.Paint implementation that supports interpolating color within a triangle where colors are given at the triangle vertices.问题是没有合适的java.awt.Paint实现支持在三角形内插入颜色,在三角形顶点处给出颜色。 This is a common thing in computer graphics (rasterization) where barycentric coordinates are used to determine the mixing weights for a point within the triangle (see https://www.khronos.org/registry/OpenGL/specs/gl/glspec14.pdf section 3.5.1).这在计算机图形(光栅化)中很常见,其中重心坐标用于确定三角形内某个点的混合权重(参见https://www.khronos.org/registry/OpenGL/specs/gl/glspec14.pdf第 3.5.1 节)。

Since I also could not find any implementation of such a Paint implementation for java.awt.Graphics2D around the web, I implemented it myself.由于我在网上也找不到java.awt.Graphics2D的此类 Paint 实现的任何实现,因此我自己实现了它。 You can find it here (titled BarycentricGradientPaint ): https://gist.github.com/hageldave/391bacc787f31d2fb2c7a10d1446c5f6你可以在这里找到它(名为BarycentricGradientPaint ): https : //gist.github.com/hageldave/391bacc787f31d2fb2c7a10d1446c5f6

A screenshot for reference, notice how the second triangle is partially transparent and edges are anti-aliased.供参考的屏幕截图,请注意第二个三角形如何部分透明并且边缘是抗锯齿的。 AA is realized through a 4x MSAA approach. AA 是通过 4x MSAA 方法实现的。

绘制实现演示的屏幕截图

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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