目标
光栅化2D直线(布雷森汉姆直线演算法、吴小林直线算法等)
实现
在前面的基础上,实现光栅化2D直线就简单多了,只需要在 ImageRaster 类中增加一个画线方法即可。具体的实现,我先选择布雷森汉姆(Bresenham )直线算法。
网上相关资料非常多,我参考的是这些文章:
实现代码如下:
/**
* 画线
*
* http://tech-algorithm.com/articles/drawing-line-using-bresenham-algorithm/
*
* @param x0
* @param y0
* @param x1
* @param y1
* @param color
*/
public void drawLine(int x0, int y0, int x1, int y1, ColorRGBA color) {
int x = x0;
int y = y0;
int w = x1 - x0;
int h = y1 - y0;
int dx1 = w < 0 ? -1 : (w > 0 ? 1 : 0);
int dy1 = h < 0 ? -1 : (h > 0 ? 1 : 0);
int dx2 = w < 0 ? -1 : (w > 0 ? 1 : 0);
int dy2 = 0;
int fastStep = Math.abs(w);
int slowStep = Math.abs(h);
if (fastStep <= slowStep) {
fastStep = Math.abs(h);
slowStep = Math.abs(w);
dx2 = 0;
dy2 = h < 0 ? -1 : (h > 0 ? 1 : 0);
}
int numerator = fastStep >> 1;
for (int i = 0; i <= fastStep; i++) {
drawPixel(x, y, color);
numerator += slowStep;
if (numerator >= fastStep) {
numerator -= fastStep;
x += dx1;
y += dy1;
} else {
x += dx2;
y += dy2;
}
drawPixel(x, y, color);
}
}
我需要多定义一个2D线段类,并让它实现Drawable接口。
package net.jmecn.geom;
import net.jmecn.math.ColorRGBA;
import net.jmecn.renderer.ImageRaster;
/**
* 代表一条线段。
*
* @author yanmaoyuan
*
*/
public class Line2D implements Drawable {
public int x0, y0;
public int x1, y1;
public ColorRGBA color = ColorRGBA.RED;
@Override
public void draw(ImageRaster imageRaster) {
imageRaster.drawLine(x0, y0, x1, y1, color);
}
}
挺简单的吧?
然后再写一个测试用例。
package net.jmecn.examples;
import java.util.Random;
import net.jmecn.Application;
import net.jmecn.geom.Line2D;
import net.jmecn.math.ColorRGBA;
/**
* 绘制2D线段
*
* @author yanmaoyuan
*
*/
public class Test2DLines extends Application {
public static void main(String[] args) {
Test2DLines app = new Test2DLines();
app.setResolution(720, 405);
app.setTitle("2D Lines");
app.setFrameRate(120);
app.start();
}
/**
* 初始化
*/
@Override
protected void initialize() {
Random rand = new Random();
/**
* 随机生成线段
*/
for(int i=0; i<100; i++) {
Line2D line = new Line2D();
line.x0 = rand.nextInt(width);
line.y0 = rand.nextInt(height);
line.x1 = rand.nextInt(width);
line.y1 = rand.nextInt(height);
line.color = new ColorRGBA(rand.nextInt(0x4FFFFFFF));
// 添加到场景中
scene.add(line);
}
}
@Override
protected void update(float delta) {
}
}
没有什么太多好解释的,不过是随机生成了一些直线。
运行结果:
总结
目标达成。
我没有尝试吴小林直线画法,主要是以前做TMXLoader项目时,用jME3的ImageRaster实现过这种抗拒齿直线算法,这里就不打算再做一遍了。