我无法找到解决此问题的方法。 我想在Java中用渐变绘制一个填充三角形,每个角都有不同的颜色。像这样:
我在网上发现了一些帖子,但我无法弄清楚如何在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);
提到类似内容的一些主题: Triangle Gradient With Core Graphics和Java 3 Color Gradient
答案 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 方法实现的。
答案 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]);
}
如果您尝试使用注释行,您将获得三种互补色。