Skip to content

Instantly share code, notes, and snippets.

@chausen
Created April 9, 2025 07:19
Show Gist options
  • Save chausen/08f39c5d677fe46fecfa6f04af93482a to your computer and use it in GitHub Desktop.
Save chausen/08f39c5d677fe46fecfa6f04af93482a to your computer and use it in GitHub Desktop.
import java.awt.*;
import java.awt.image.BufferedImage;
public class CrosshatchDrawer {
/**
* Draws a crosshatch pattern (two sets of diagonal lines) on the given image.
*
* @param image the BufferedImage to draw on
* @param spacing distance (in pixels) between diagonal lines
* @param color the color for the hatch lines
*/
public static void drawCrosshatch(BufferedImage image, int spacing, Color color) {
int width = image.getWidth();
int height = image.getHeight();
Graphics2D g2d = image.createGraphics();
// Enable anti-aliasing if desired (optional)
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Set color and basic stroke (line thickness can be changed)
g2d.setColor(color);
g2d.setStroke(new BasicStroke(1.0f));
// Draw diagonal lines with slope +1 (45°)
// We shift the diagonal offset "d" from negative to positive
for (int d = -height; d <= width; d += spacing) {
// For slope +1, any line can be parameterized as y = x - d.
// We'll figure out the segment that lies within the image:
// Start point (x1, y1) on the left or bottom boundary
// End point (x2, y2) on the right or top boundary
// x1, y1
int x1 = Math.max(0, d); // if d is negative, x1=0, else x1=d
int y1 = x1 - d; // y1 = x1 - d
// y could exceed image height, so clamp
if (y1 > height) {
// if y1 is beyond bottom, adjust x1 so y1=height
y1 = height;
x1 = y1 + d;
}
// x2, y2
int x2 = Math.min(width, height + d); // we want x2 <= width, also x2 = height + d if the line's top intersects y=0
int y2 = x2 - d; // y2 = x2 - d
// if y2 < 0, clamp it, meaning we hit the top boundary
if (y2 < 0) {
y2 = 0;
x2 = y2 + d;
}
// Draw the line if it's within the image bounds
if (0 <= x1 && x1 <= width && 0 <= y1 && y1 <= height &&
0 <= x2 && x2 <= width && 0 <= y2 && y2 <= height) {
g2d.drawLine(x1, y1, x2, y2);
}
}
// Draw diagonal lines with slope -1 (135°)
// Similar approach, but now y = -x + d
for (int d = 0; d <= width + height; d += spacing) {
// y = -x + d
// We'll find the segment within the image.
// x1, y1
int x1 = Math.max(0, d - height); // if d < height, x1=0; otherwise x1=d-height
int y1 = -x1 + d; // y1 = -x1 + d
// if y1 < 0, shift x1 until y1=0
if (y1 < 0) {
y1 = 0;
x1 = d - y1; // x1 = d - 0 => x1 = d
}
// x2, y2
int x2 = Math.min(d, width);
int y2 = -x2 + d;
// if y2 > height, clamp
if (y2 > height) {
y2 = height;
x2 = d - y2;
}
// Draw the line if it's within the image bounds
if (0 <= x1 && x1 <= width && 0 <= y1 && y1 <= height &&
0 <= x2 && x2 <= width && 0 <= y2 && y2 <= height) {
g2d.drawLine(x1, y1, x2, y2);
}
}
g2d.dispose();
}
// Example usage
public static void main(String[] args) {
// Suppose we have a 400x300 BufferedImage
BufferedImage image = new BufferedImage(400, 300, BufferedImage.TYPE_INT_ARGB);
// Fill the background (optional)
Graphics2D g = image.createGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
g.dispose();
// Draw crosshatch with a 20-pixel spacing
drawCrosshatch(image, 20, Color.BLACK);
// At this point, 'image' has the crosshatch drawn on it.
// You can write it to a file if desired:
/*
try {
ImageIO.write(image, "PNG", new File("crosshatch_output.png"));
} catch (IOException e) {
e.printStackTrace();
}
*/
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment