我在使用BSPline路径时遇到了derivativeAt()方法的问题,因为它没有返回正确的值,但是derivativeAt()方法可以找到CatmullRomSpline路径,因此这是SPline特有的。维基和API没有提到SPline需要与其他路径区别对待...... SPline中是否存在我缺少的东西,或者这是LibGDX的错误?
我做了一个简单的程序来显示问题。它使用derivativeAt()方法绘制控制点(黄点),路径本身(浅灰色线)和切线(绿线),该方法应指向与路径相同的方向。
这是应该做的。 CatmulRomSpline工作正常,因为绿色切线指向与路径相同的方向:
以下是BSpline的作用。切线指向各种方向,而不是路径的方向:
这是我的代码。任何有助于使其正常工作的帮助将不胜感激。
public class Test extends Game {
private int width, height;
private Stage stage;
private Table mainTable;
private Texture texture;
private Image image;
private Pixmap pixmap;
private Path<Vector2> path;
private Vector2 point1=new Vector2(), point2=new Vector2();
private Vector2 derivative=new Vector2(), normal=new Vector2();
private float pathSegments=10000, derivativeSegments=40;
private int lineLength = 20;
private Vector2[] points = { new Vector2(400,700), new Vector2(100,600),
new Vector2(100,250), new Vector2(400,100), new Vector2(700,250),
new Vector2(700,600), new Vector2(400,700)
};
// TRUE = use BSpline
// FALSE = use CatmullRomSpline
private boolean USE_BSPLINE = true;
@Override
public void create () {
stage = new Stage();
stage.setViewport(new ScreenViewport(stage.getViewport().getCamera()));
Gdx.input.setInputProcessor(stage);
mainTable = new Table();
mainTable.setFillParent(true);
stage.addActor(mainTable);
width = Gdx.graphics.getWidth();
height = Gdx.graphics.getHeight();
pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888);
if (USE_BSPLINE){
path = new BSpline<Vector2>();
((BSpline<Vector2>)path).set(points, 3, false);
} else {
path = new CatmullRomSpline<Vector2>();
((CatmullRomSpline<Vector2>)path).set(points, false);
}
drawControlPoints();
drawPath();
drawDerivative();
texture = new Texture(pixmap);
image = new Image(texture);
mainTable.add(image).size(image.getWidth(), image.getHeight());
}
private void drawControlPoints(){
pixmap.setColor(Color.YELLOW);
for (int i=0; i<points.length; i++){
pixmap.fillCircle((int)points[i].x, (int)points[i].y, 6);
}
}
private void drawPath(){
pixmap.setColor(Color.LIGHT_GRAY);
float t;
for(int i=0; i<=pathSegments; i++){
t = i / pathSegments;
path.valueAt(point1, t);
pixmap.drawPixel((int)point1.x, (int)point1.y);
}
}
// << ERROR OCCURS HERE WHEN USING BSPLINE >>
private void drawDerivative(){
pixmap.setColor(Color.GREEN);
float t;
for(int i=0; i<=derivativeSegments; i++){
t = i / derivativeSegments;
path.valueAt(point1, t);
path.derivativeAt(derivative, t);
normal.set(derivative);
normal.nor();
point2.set((point1.x + normal.x*lineLength), (point1.y + normal.y*lineLength));
pixmap.drawLine((int)point1.x, (int)point1.y, (int)point2.x, (int)point2.y);
}
}
@Override
public void render () {
Gdx.gl.glClearColor(0.0f, 0.0f, 0.08f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
@Override
public void resize(int width, int height){
stage.getViewport().update(width, height, true);
}
@Override
public void dispose(){
pixmap.dispose();
texture.dispose();
stage.dispose();
super.dispose();
}
}