Skip to content

Instantly share code, notes, and snippets.

@hageldave
Last active January 3, 2022 14:57
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hageldave/391bacc787f31d2fb2c7a10d1446c5f6 to your computer and use it in GitHub Desktop.
Save hageldave/391bacc787f31d2fb2c7a10d1446c5f6 to your computer and use it in GitHub Desktop.
A java.awt.Paint implementation for triangular color interpolation (using barycentric coordinates). The svg file shows the result of the demo app (embedded image).
/* Copyright 2021 David Haegele - Source from JPlotter */
import java.awt.Color;
import java.awt.Paint;
import java.awt.PaintContext;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.ColorModel;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.lang.ref.WeakReference;
/**
* The BarycentricGradientPaint class provides a way to fill a {@link Shape}
* with a triangular color gradient.
* Colors are specified for the vertices of a triangle and interpolated within
* the triangle according to barycentric coordinates.
* Only areas of the filled shape that are intersecting with the triangle of
* this paint are colored.
* <p>
* This paint supports the {@code ANTIALIASING} rendering hint
* ({@link RenderingHints}) using a 4x multisampling approach.
* When enabled, the edges of the triangle will appear anti-aliased.
* It is recommended to disable AA when filling a triangle mesh (where triangles
* are adjacent), since otherwise triangle edges become visible.
* <p>
* Note that it is not necessary to use a triangular {@link Shape} to render a
* triangle. Instead a rectangle can be used as well, since only the intersecting
* area will be filled.
*
* @author hageldave
*/
public class BarycentricGradientPaint implements Paint {
protected Point2D.Float p1;
protected Point2D.Float p2;
protected Point2D.Float p3;
protected Color color1;
protected Color color2;
protected Color color3;
/**
* Creates a new {@link BarycentricGradientPaint} object with
* specified triangle vertices and vertex colors.
*
* @param p1 vertex of triangle
* @param p2 vertex of triangle
* @param p3 vertex of triangle
* @param color1 color of vertex
* @param color2 color of vertex
* @param color3 color of vertex
*/
public BarycentricGradientPaint(Point2D p1, Point2D p2, Point2D p3, Color color1, Color color2, Color color3) {
this.p1 = new Point2D.Float((float)p1.getX(), (float)p1.getY());
this.p2 = new Point2D.Float((float)p2.getX(), (float)p2.getY());
this.p3 = new Point2D.Float((float)p3.getX(), (float)p3.getY());
this.color1 = color1;
this.color2 = color2;
this.color3 = color3;
}
/**
* Creates a new {@link BarycentricGradientPaint} object with
* specified triangle vertices and vertex colors.
*
* @param x x-coordinates for the triangle vertices
* @param y y-coordinates for the triangle vertices
* @param color1 color of vertex
* @param color2 color of vertex
* @param color3 color of vertex
*/
public BarycentricGradientPaint(float[] x, float[] y, Color color1, Color color2, Color color3) {
this(x[0],y[0],x[1],y[1],x[2],y[2], color1,color2,color3);
}
/**
* Creates a new {@link BarycentricGradientPaint} object with
* specified triangle vertices and vertex colors.
*
* @param x1 x-coord of triangle vertex
* @param y1 y-coord of triangle vertex
* @param x2 x-coord of triangle vertex
* @param y2 y-coord of triangle vertex
* @param x3 x-coord of triangle vertex
* @param y3 y-coord of triangle vertex
* @param color1 color of vertex
* @param color2 color of vertex
* @param color3 color of vertex
*/
public BarycentricGradientPaint(double x1, double y1, double x2, double y2, double x3, double y3, Color color1, Color color2, Color color3) {
this((float)x1,(float)y1,(float)x2,(float)y2,(float)x3,(float)y3, color1,color2,color3);
}
/**
* Creates a new {@link BarycentricGradientPaint} object with
* specified triangle vertices and vertex colors.
*
* @param x1 x-coord of triangle vertex
* @param y1 y-coord of triangle vertex
* @param x2 x-coord of triangle vertex
* @param y2 y-coord of triangle vertex
* @param x3 x-coord of triangle vertex
* @param y3 y-coord of triangle vertex
* @param color1 color of vertex
* @param color2 color of vertex
* @param color3 color of vertex
*/
public BarycentricGradientPaint(float x1, float y1, float x2, float y2, float x3, float y3, Color color1, Color color2, Color color3) {
this.p1 = new Point2D.Float(x1, y1);
this.p2 = new Point2D.Float(x2, y2);
this.p3 = new Point2D.Float(x3, y3);
this.color1 = color1;
this.color2 = color2;
this.color3 = color3;
}
@Override
public int getTransparency() {
int a1 = color1.getAlpha();
int a2 = color2.getAlpha();
int a3 = color3.getAlpha();
return (((a1 & a2 & a3) == 0xff) ? OPAQUE : TRANSLUCENT);
}
@Override
public PaintContext createContext(ColorModel cm, Rectangle deviceBounds, Rectangle2D userBounds,
AffineTransform xform, RenderingHints hints) {
return new BarycentricGradientPaintContext(
p1,p2,p3,
color1,color2,color3,
xform,
hints.get(RenderingHints.KEY_ANTIALIASING) == RenderingHints.VALUE_ANTIALIAS_ON
);
}
/**
* This class is implements the {@link PaintContext} for
* {@link BarycentricGradientPaint}.
* <p>
* The context operates solely in ARGB color space (blue on least
* significant bits) with an integer packing {@link DirectColorModel}.
* <p>
* A cache for raster memory is implemented to avoid costly memory
* allocations.
*
* @author hageldave
*/
public static class BarycentricGradientPaintContext implements PaintContext {
protected static final float[] MSAA_SAMPLES;
static {
MSAA_SAMPLES = new float[8];
AffineTransform xform = new AffineTransform();
xform.translate(.5, .5);
xform.rotate(Math.PI*0.5*0.2);
xform.scale(.5, .5);
xform.translate(-.5, -.5);
xform.transform(new float[] {0,0, 1,0, 0,1, 1,1}, 0, MSAA_SAMPLES, 0, 4);
}
protected final float x1,x2,x3,y1,y2,y3;
protected final float x23,x13,y23,y13; //,x12,y12;
protected final float denom;
protected final int c1,c2,c3;
protected final DirectColorModel cm = new DirectColorModel(32,
0x00ff0000, // Red
0x0000ff00, // Green
0x000000ff, // Blue
0xff000000 // Alpha
);
protected final boolean antialiasing;
protected WritableRaster saved;
protected WeakReference<int[]> cache;
public BarycentricGradientPaintContext(
Point2D.Float p1, Point2D.Float p2, Point2D.Float p3,
Color color1, Color color2, Color color3,
AffineTransform xform, boolean antialiasing)
{
c1 = color1.getRGB();
c2 = color2.getRGB();
c3 = color3.getRGB();
p1 = (Point2D.Float) xform.transform(p1, new Point2D.Float());
p2 = (Point2D.Float) xform.transform(p2, new Point2D.Float());
p3 = (Point2D.Float) xform.transform(p3, new Point2D.Float());
// constants for barycentric coords
x1=p1.x; x2=p2.x; x3=p3.x; y1=p1.y; y2=p2.y; y3=p3.y;
x23=x2-x3; x13=x1-x3; y23=y2-y3; y13=y1-y3; // x12=x1-x2; y12=y1-y2;
denom=1f/((y23*x13)-(x23*y13));
this.antialiasing = antialiasing;
}
@Override
public void dispose() {
if(saved != null)
cacheRaster(saved);
saved = null;
}
@Override
public ColorModel getColorModel() {
return cm;
}
@Override
public Raster getRaster(int xA, int yA, int w, int h) {
WritableRaster rast = saved;
if (rast == null) {
rast = getCachedOrCreateRaster(w, h);
saved = rast;
} else if(rast.getWidth() != w || rast.getHeight() != h) {
int[] data = dataFromRaster(rast);
if(data.length < w*h) {
data = new int[w*h];
}
rast = createRaster(w, h, data);
saved = rast;
}
// fill data array with interpolated colors (barycentric coords)
int[] data = dataFromRaster(rast);
if(antialiasing)
fillRasterMSAA(xA, yA, w, h, data);
else
fillRaster(xA, yA, w, h, data);
return rast;
}
protected void fillRaster(int xA, int yA, int w, int h, int[] data) {
for(int i=0; i<h; i++) {
float y = yA+i+.5f;
float ypart11 = -x23*(y-y3);
float ypart21 = x13*(y-y3);
for(int j=0; j<w; j++) {
float x = xA+j+.5f;
// calculate barycentric coordinates for (x,y)
float l1 = ( y23*(x-x3)+ypart11)*denom;
float l2 = (-y13*(x-x3)+ypart21)*denom;
float l3 = 1f-l1-l2;
// determine color
int mix1;
if(l1<0||l2<0||l3<0) mix1 = 0;
else mix1 = mixColor3(c1, c2, c3, l1, l2, l3);
data[i*w+j] = mix1;
}
}
}
protected void fillRasterMSAA(int xA, int yA, int w, int h, int[] data) {
for(int i=0; i<h; i++) {
float y = yA+i+MSAA_SAMPLES[1];
float ypart11 = -x23*(y-y3);
float ypart21 = x13*(y-y3);
y = yA+i+MSAA_SAMPLES[3];
float ypart12 = -x23*(y-y3);
float ypart22 = x13*(y-y3);
y = yA+i+MSAA_SAMPLES[5];
float ypart13 = -x23*(y-y3);
float ypart23 = x13*(y-y3);
y = yA+i+MSAA_SAMPLES[7];
float ypart14 = -x23*(y-y3);
float ypart24 = x13*(y-y3);
for(int j=0; j<w; j++) {
float x = xA+j+MSAA_SAMPLES[0];
float xpart11 = y23*(x-x3);
float xpart21 = -y13*(x-x3);
x = xA+j+MSAA_SAMPLES[2];
float xpart12 = y23*(x-x3);
float xpart22 = -y13*(x-x3);
x = xA+j+MSAA_SAMPLES[4];
float xpart13 = y23*(x-x3);
float xpart23 = -y13*(x-x3);
x = xA+j+MSAA_SAMPLES[6];
float xpart14 = y23*(x-x3);
float xpart24 = -y13*(x-x3);
// calculate barycentric coordinates for the 4 sub pixel samples
float l11 = (xpart11+ypart11)*denom;
float l21 = (xpart21+ypart21)*denom;
float l31 = 1f-l11-l21;
float l12 = (xpart12+ypart12)*denom;
float l22 = (xpart22+ypart22)*denom;
float l32 = 1f-l12-l22;
float l13 = (xpart13+ypart13)*denom;
float l23 = (xpart23+ypart23)*denom;
float l33 = 1f-l13-l23;
float l14 = (xpart14+ypart14)*denom;
float l24 = (xpart24+ypart24)*denom;
float l34 = 1f-l14-l24;
// determine sample colors and weights (out of triangle samples have 0 weight)
int mix1,mix2,mix3,mix4;
float w1,w2,w3,w4;
if(l11<0||l21<0||l31<0) { mix1 = 0; w1=0f; }
else { mix1 = mixColor3(c1, c2, c3, l11, l21, l31); w1=1f; }
if(l12<0||l22<0||l32<0) { mix2 = 0; w2=0f; }
else { mix2 = mixColor3(c1, c2, c3, l12, l22, l32); w2=1f; }
if(l13<0||l23<0||l33<0) {mix3 = 0; w3=0f; }
else { mix3 = mixColor3(c1, c2, c3, l13, l23, l33); w3=1f; }
if(l14<0||l24<0||l34<0) { mix4 = 0; w4=0f; }
else { mix4 = mixColor3(c1, c2, c3, l14, l24, l34); w4=1f; }
int color = mixColor4(mix1, mix2, mix3, mix4, w1,w2,w3,w4);
data[i*w+j] = scaleColorAlpha(color,(w1+w2+w3+w4)*.25f);
}
}
}
protected WritableRaster getCachedOrCreateRaster(int w, int h) {
if(cache != null) {
int[] data = cache.get();
if (data != null && data.length >= w*h)
{
cache = null;
return createRaster(w, h, data);
}
}
return createRaster(w, h, new int[w*h]);
}
protected void cacheRaster(WritableRaster ras) {
int[] toCache = dataFromRaster(ras);
if (cache != null) {
int[] data = cache.get();
if (data != null) {
if (toCache.length < data.length) {
return;
}
}
}
cache = new WeakReference<>(toCache);
}
protected WritableRaster createRaster(int w, int h, int[] data) {
DataBufferInt buffer = new DataBufferInt(data, w*h);
WritableRaster raster = Raster.createPackedRaster(buffer, w, h, w, cm.getMasks(), null);
return raster;
}
private static int[] dataFromRaster(WritableRaster wr) {
return ((DataBufferInt)wr.getDataBuffer()).getData();
}
private static int mixColor3(int c1, int c2, int c3, float m1, float m2, float m3) {
float normalize = 1f/(m1+m2+m3);
float a = (a(c1)*m1 + a(c2)*m2 + a(c3)*m3)*normalize;
float r = (r(c1)*m1 + r(c2)*m2 + r(c3)*m3)*normalize;
float g = (g(c1)*m1 + g(c2)*m2 + g(c3)*m3)*normalize;
float b = (b(c1)*m1 + b(c2)*m2 + b(c3)*m3)*normalize;
return argb((int)a, (int)r, (int)g, (int)b);
}
private static int mixColor4(int c1, int c2, int c3, int c4, float m1, float m2, float m3, float m4) {
float normalize = 1f/(m1+m2+m3+m4);
float a = (a(c1)*m1 + a(c2)*m2 + a(c3)*m3 + a(c4)*m4)*normalize;
float r = (r(c1)*m1 + r(c2)*m2 + r(c3)*m3 + r(c4)*m4)*normalize;
float g = (g(c1)*m1 + g(c2)*m2 + g(c3)*m3 + g(c4)*m4)*normalize;
float b = (b(c1)*m1 + b(c2)*m2 + b(c3)*m3 + b(c4)*m4)*normalize;
return argb((int)a, (int)r, (int)g, (int)b);
}
private static int a(int argb) {
return (argb >> 24) & 0xff;
}
private static int r(int argb) {
return (argb >> 16) & 0xff;
}
private static int g(int argb) {
return (argb >> 8) & 0xff;
}
private static int b(int argb) {
return (argb) & 0xff;
}
private static int argb(final int a, final int r, final int g, final int b){
return (a<<24)|(r<<16)|(g<<8)|b;
}
private static int scaleColorAlpha(int color, float m) {
float normalize = 1f/255f;
float af = a(color)*normalize*m;
int a = (((int)(af*255f)) & 0xff) << 24;
return (color&0x00ffffff)|a;
}
}
}
Display the source blob
Display the rendered blob
Raw
<svg contentScriptType="text/ecmascript" width="180"
xmlns:xlink="http://www.w3.org/1999/xlink" zoomAndPan="magnify"
contentStyleType="text/css" height="150"
preserveAspectRatio="xMidYMid meet" xmlns="http://www.w3.org/2000/svg"
version="1.0">
<defs id="JPlotterDefs"/>
<g font-size="12px">
<g>
<defs id="defs1">
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath1">
<path d="M0 0 L180 0 L180 150 L0 150 L0 0 Z"/>
</clipPath>
<clipPath clipPathUnits="userSpaceOnUse" id="clipPath2">
<path d="M0 0 L0 150 L180 150 L180 0 Z"/>
</clipPath>
</defs>
<g fill="rgb(238,238,238)" font-family="sans-serif"
stroke="rgb(238,238,238)">
<rect x="0" width="180" height="150" y="0"
clip-path="url(#clipPath1)" stroke="none"/>
</g>
<g fill="rgb(51,51,51)" font-family="sans-serif"
stroke="rgb(51,51,51)">
<image x="0" y="0" clip-path="url(#clipPath2)" width="180"
xmlns:xlink="http://www.w3.org/1999/xlink"
xlink:href="data:image/png;base64,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
NfNDWHrW+/CM7F9JWTm/kHPyfo7Iyf+Jml/wI7Ww8DG9sOgho6T4Hquk5E50WelN
TnnZDW5l+QivqvIKv6bqEr+2elBQX9MrbKjtFjbWdSadqe9Ibm5oTW093ZTW3ng6
o72pLrOjuTr7XEtFTmdraV5XW1F+T3t+Yd/ZnKL+jsySgXPpZRc6k8ovdgkrhrrj
q670xFQP93Jrhvui6671MxpGB6Iab1yIODM2SGq6fTG05fZQcOudywHtd6/4tj8Y
9jr34OrJzkcjrl0T15y6n4za9/543bZv8obVwLOb5hee3zp+8cVto0uv7hgMvRrX
u/L67uGrb+5pj7y9rzX67sHe0fcPd4/9PrHz1sfH229/erL1zuenm+9++VHl3tdJ
5QdTz9Y8ImpXPoHm9x38Q2ibpo8myaM4LXUMtbMNUDXXAGXzDFG8wAj58kbIUTBG
xjITpKwwQeLK44hfY4pYZTNwVMzA2mwO2lYLULZZgLTTEqEaVgjStIb/fmt4H7TB
yUO2cD1iC0d9O5wwOAFrY3tYmNrjuLkDjKwciaO2jtC1dyIOOTlDy9UZe91doOHp
ip0+blDzd4NqkDtUQk5COewksZrsASWKJ5bRvKDA9MIitjfkuD6YG+sD6XhfzBT6
wYBHxlRAauqfgWlpn4IzMj6cysp8F5ad9SY8N/slKS/nOakgdzKyMO9HSnH+46ji
goe0ssJxRnnxbWZlyVh0Zekou7rsKreu/DKvoeJSbENlP7+xqjf+THWXoLmmQ9hc
157YWt+S3N7QmNJxuiGto7E2rfNMVUZXU3lWT3NJTl9LYW5/a17+QHtWweDZjKKL
HalFQ+eSy4Y6E8qGz8dVXO2KrRjp5tSM9rBqbvTS68b6qfW3BiIab18IaxwfDG26
ezGo+f4l/9YHQz6tjy57np244t7xZNil8+mI4/nJaye6n43a9Dy/btn34oZZ/8ux
4xde3TQcfH3r6KU3t3WH3t3RufLu7sHh9/f2j3y4r3nt4wON0U8Pd974/GjbzS8T
W25NPd50Z+rJhrvfqtY9wJ7vG/iH0j5dFy0zdNE4Sw/1MvqoltVHxfyjKFl0DIWL
DZC7xACZioZIUzJC0mojJKwzBn+9CcHbaIJo1eNgqJmCusOMiNhlhrDd5gjea4EA
LQv4aFvC87AV3PSsCeej1rA3tCFsTWxhaWYLM0s7GNucgIGdPfQc7KHj7EAcdHPE
Pg9H7PF2grqvM7YHOGNLsAs2hbpiPckNayPdsJLqDkX6SSxhnYQ8xwMLYjwhG+cF
GYEXpBK9YRATjim/jJTP/tmpHwOy034Lykt/F5yX8Tq0MPNlWGHWc1JxziSpOPcJ
uTTvUURF/n1qRcE4tarwFr226Aajtvgaq75kOLqh9BK7sXyQd6ain9dc2cNvreri
t1d3CNpr2oQdtc3CjrrTSV319cldDTUpPY2Vab1nSjP6moozB5oLswdbcnMutWbm
DbWl519uTym8cjax6GqHoORaJ7/0+nle+Y0uTsWNbmbVrR5a9e1eSs14X0Td3f6w
hvsDpxofXAhonLjo3zRxyaflyZBH69PLbu2TV5zbfxp2PPf86onOFyNWXS+vWXS/
GjXr/eWGcd+bMYOBtzf1L/x268jF97d1Ln24c2Do0/i+K5/u7rn6+d6ukS/3d4xO
PVS7PvVoy9i3io13/sFD/sv5aYfQIamDVikdNM0+jIa5R1A7TxeVC3SJUnk9FCno
I2+ZPrJXHEX6ymNIWWMAobIB4lUMEbPZiOBsNQJzmzFoO00QqWGCcM3jCNlvisCD
ZvA7ZAavI+Y4qW8BFwMLOBpbws7UCtbm1jC3soaJrQ0M7W2h72SLI6520HY/AS1P
e2j62EPD3wE7ghyhFuKIzWFOUCE7Yx3FGatoLljBdMVStht+4LphYaw7IRd/EnOE
JyGd7IEkajQSotj45Jub/NE/L/W3gMK0XwML038JLs54caok83lYWdZkeHn2E1Jl
zkNSVe69yJq8cWptwS1qfeGNqIaiq4zG4svMxpJL0U2lF9gtZX3ctvJuXnvFudiO
yrP8c9VtgvM1ZwRdtaeFPXV1ib311cl9DRUpA6fL0gYbi9IGzxRkXG7Kybrckpkz
3JqeN9KWnH+tPaHg2tn4orGO2KKxc7yym53RZbfPMyrGu6Iq7/ZEVt/vJdU86Aup
e9QfXD8xEND45IJv49NBr6bJiyebn11ybf1pyLHtxZUT7T8P23a8umrV+XrE/Pzr
a8e7344a9by7fqzv/Q29/g9jOhc+3jx48eNtrUuf7+wd+jK++8rXu+rDX+9tG/lW
uvUGdn8/939Y3dMP4NyMg0T7LG00y2ijUfYQ6ubroGqRDsoXH0bxkiMoUNRFjpIu
MlfrIXWdPpLW60Ow8Sj4qsfAVTMAa4cB6LsMQdltBPJeI4RqGSNY2wT+h03go3cc
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
RU5ErkJggg==" xlink:type="simple" xlink:actuate="onLoad" height="150"
preserveAspectRatio="none" xlink:show="embed"/>
</g>
</g>
</g>
<g transform="translate(0,0)"/>
</svg>
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class TriangularColorInterpolationDemo {
public static void main(String[] args) {
JComponent triangleDisplay = new JComponent() {
private static final long serialVersionUID = 1L;
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(new BarycentricGradientPaint(20, 100, 100, 120, 60, 20, Color.red, Color.green, Color.blue));
g2d.fillRect(20, 20, 100, 100);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(new BarycentricGradientPaint(100, 20, 170, 70, 70, 120, Color.yellow, Color.cyan, new Color(0x44ff00ff, true)));
g2d.fillRect(70, 20, 100, 100);
}
};
triangleDisplay.setPreferredSize(new Dimension(180, 150));
JFrame frame = new JFrame();
frame.getContentPane().add(triangleDisplay);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SwingUtilities.invokeLater(()->{
frame.pack();
frame.setVisible(true);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment