In order to be able to create color that is a blend of two colors, you need to know the distance between the colors at which you want to blend.
The problem with the way that your algorithm is currently implement is, you don't know the number of points which might be needed to create an individual line, so you can't calculate the color of the segement.
So, I modified your algorthim to return a List
of Point
s, instead of drawing them.
public class Bresenham {
public static List<Point> line(Point from, Point to) {
List<Point> points = new ArrayList<>(32);
// delta of exact value and rounded value of the dependent variable
int d = 0;
int dx = Math.abs(from.x - to.x);
int dy = Math.abs(from.y - to.y);
int deltaX = 2 * dx; // slope scaling factors to
int deltaY = 2 * dy; // avoid floating point
int ix = to.x < from.x ? 1 : -1; // increment direction
int iy = to.y < from.y ? 1 : -1;
int x = to.x;
int y = to.y;
if (dx >= dy) {
while (true) {
points.add(new Point(x, y));
if (x == from.x) {
break;
}
x += ix;
d += deltaY;
if (d > dx) {
y += iy;
d -= deltaX;
}
}
} else {
while (true) {
points.add(new Point(x, y));
if (y == from.y) {
break;
}
y += iy;
d += deltaX;
if (d > dy) {
x += ix;
d -= deltaY;
}
}
}
return points;
}
}
This now tells us how many points are in the line. From this we can calculate the progression value (0-1) along the line, which will allow use to generate a color blending algorthim.
I then took the ColorBand
implementation I have, which is based on Color fading algorithm? and Color fading algorithm? (and a few other) examples.
From that, I can calculate the color of the line segment based normalised progression through the line points.
For example...

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Line2D;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public final class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<List<Point>> lines;
private ColorBand colorBand;
public TestPane() {
lines = new ArrayList<>(4);
lines.add(Bresenham.line(new Point(0, 0), new Point(200, 200)));
lines.add(Bresenham.line(new Point(100, 0), new Point(100, 200)));
lines.add(Bresenham.line(new Point(200, 0), new Point(0, 200)));
lines.add(Bresenham.line(new Point(0, 100), new Point(200, 100)));
colorBand = new ColorBand(
new float[]{0f, 0.5f, 1f},
new Color[]{Color.RED, Color.GREEN, Color.BLUE}
);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
for (List<Point> line : lines) {
Point lastPoint = null;
float progress = 0f;
for (int index = 0; index < line.size(); index++) {
progress = (float) index / (float) line.size();
Point nextPoint = line.get(index);
if (lastPoint == null) {
lastPoint = nextPoint;
continue;
}
g2d.setColor(colorBand.colorAt(progress));
g2d.draw(new Line2D.Double(lastPoint, nextPoint));
lastPoint = nextPoint;
}
}
g2d.dispose();
}
}
public static class Bresenham {
public static List<Point> line(Point from, Point to) {
List<Point> points = new ArrayList<>(32);
// delta of exact value and rounded value of the dependent variable
int d = 0;
int dx = Math.abs(from.x - to.x);
int dy = Math.abs(from.y - to.y);
int deltaX = 2 * dx; // slope scaling factors to
int deltaY = 2 * dy; // avoid floating point
int ix = to.x < from.x ? 1 : -1; // increment direction
int iy = to.y < from.y ? 1 : -1;
int x = to.x;
int y = to.y;
if (dx >= dy) {
while (true) {
points.add(new Point(x, y));
if (x == from.x) {
break;
}
x += ix;
d += deltaY;
if (d > dx) {
y += iy;
d -= deltaX;
}
}
} else {
while (true) {
points.add(new Point(x, y));
if (y == from.y) {
break;
}
y += iy;
d += deltaX;
if (d > dy) {
x += ix;
d -= deltaY;
}
}
}
return points;
}
}
public class ColorBand {
private float[] fractions;
private Color[] colors;
public ColorBand(float[] fractions, Color[] colors) {
this.fractions = fractions;
this.colors = colors;
}
public Color colorAt(float progress) {
Color color = null;
if (fractions != null) {
if (colors != null) {
if (fractions.length == colors.length) {
int[] indicies = getFractionIndicies(progress);
float[] range = new float[]{fractions[indicies[0]], fractions[indicies[1]]};
Color[] colorRange = new Color[]{colors[indicies[0]], colors[indicies[1]]};
float max = range[1] - range[0];
float value = progress - range[0];
float weight = value / max;
color = blend(colorRange[0], colorRange[1], 1f - weight);
} else {
throw new IllegalArgumentException("Fractions and colours must have equal number of elements");
}
} else {
throw new IllegalArgumentException("Colours can't be null");
}
} else {
throw new IllegalArgumentException("Fractions can't be null");
}
return color;
}
protected int[] getFractionIndicies(float progress) {
int[] range = new int[2];
int startPoint = 0;
while (startPoint < fractions.length && fractions[startPoint] <= progress) {
startPoint++;
}
if (startPoint >= fractions.length) {
startPoint = fractions.length - 1;
}
range[0] = startPoint - 1;
range[1] = startPoint;
return range;
}
protected Color blend(Color color1, Color color2, double ratio) {
float r = (float) ratio;
float ir = (float) 1.0 - r;
float rgb1[] = new float[3];
float rgb2[] = new float[3];
color1.getColorComponents(rgb1);
color2.getColorComponents(rgb2);
float red = rgb1[0] * r + rgb2[0] * ir;
float green = rgb1[1] * r + rgb2[1] * ir;
float blue = rgb1[2] * r + rgb2[2] * ir;
if (red < 0) {
red = 0;
} else if (red > 255) {
red = 255;
}
if (green < 0) {
green = 0;
} else if (green > 255) {
green = 255;
}
if (blue < 0) {
blue = 0;
} else if (blue > 255) {
blue = 255;
}
Color color = null;
try {
color = new Color(red, green, blue);
} catch (IllegalArgumentException exp) {
NumberFormat nf = NumberFormat.getNumberInstance();
System.out.println(nf.format(red) + "; " + nf.format(green) + "; " + nf.format(blue));
exp.printStackTrace();
}
return color;
}
}
}
Now, because I'm curious, I modified the lines so some are draw backwards (bottom to top)
lines.add(Bresenham.line(new Point(0, 0), new Point(200, 200)));
lines.add(Bresenham.line(new Point(100, 200), new Point(100, 0)));
lines.add(Bresenham.line(new Point(0, 200), new Point(200, 0)));
lines.add(Bresenham.line(new Point(0, 100), new Point(200, 100)));
just to see what I would get...
