RosettaCodeData/Task/Xiaolin-Wus-line-algorithm/Java/xiaolin-wus-line-algorithm....

110 lines
3.1 KiB
Java

import java.awt.*;
import static java.lang.Math.*;
import javax.swing.*;
public class XiaolinWu extends JPanel {
public XiaolinWu() {
Dimension dim = new Dimension(640, 640);
setPreferredSize(dim);
setBackground(Color.white);
}
void plot(Graphics2D g, double x, double y, double c) {
g.setColor(new Color(0f, 0f, 0f, (float)c));
g.fillOval((int) x, (int) y, 2, 2);
}
int ipart(double x) {
return (int) x;
}
double fpart(double x) {
return x - floor(x);
}
double rfpart(double x) {
return 1.0 - fpart(x);
}
void drawLine(Graphics2D g, double x0, double y0, double x1, double y1) {
boolean steep = abs(y1 - y0) > abs(x1 - x0);
if (steep)
drawLine(g, y0, x0, y1, x1);
if (x0 > x1)
drawLine(g, x1, y1, x0, y0);
double dx = x1 - x0;
double dy = y1 - y0;
double gradient = dy / dx;
// handle first endpoint
double xend = round(x0);
double yend = y0 + gradient * (xend - x0);
double xgap = rfpart(x0 + 0.5);
double xpxl1 = xend; // this will be used in the main loop
double ypxl1 = ipart(yend);
if (steep) {
plot(g, ypxl1, xpxl1, rfpart(yend) * xgap);
plot(g, ypxl1 + 1, xpxl1, fpart(yend) * xgap);
} else {
plot(g, xpxl1, ypxl1, rfpart(yend) * xgap);
plot(g, xpxl1, ypxl1 + 1, fpart(yend) * xgap);
}
// first y-intersection for the main loop
double intery = yend + gradient;
// handle second endpoint
xend = round(x1);
yend = y1 + gradient * (xend - x1);
xgap = fpart(x1 + 0.5);
double xpxl2 = xend; // this will be used in the main loop
double ypxl2 = ipart(yend);
if (steep) {
plot(g, ypxl2, xpxl2, rfpart(yend) * xgap);
plot(g, ypxl2 + 1, xpxl2, fpart(yend) * xgap);
} else {
plot(g, xpxl2, ypxl2, rfpart(yend) * xgap);
plot(g, xpxl2, ypxl2 + 1, fpart(yend) * xgap);
}
// main loop
for (double x = xpxl1 + 1; x <= xpxl2 - 1; x++) {
if (steep) {
plot(g, ipart(intery), x, rfpart(intery));
plot(g, ipart(intery) + 1, x, fpart(intery));
} else {
plot(g, x, ipart(intery), rfpart(intery));
plot(g, x, ipart(intery) + 1, fpart(intery));
}
intery = intery + gradient;
}
}
@Override
public void paintComponent(Graphics gg) {
super.paintComponent(gg);
Graphics2D g = (Graphics2D) gg;
drawLine(g, 550, 170, 50, 435);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Xiaolin Wu's line algorithm");
f.setResizable(false);
f.add(new XiaolinWu(), BorderLayout.CENTER);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
});
}
}