问题
I am having problems with the derivativeAt() method when using the BSpline path because it is not returning the correct values, however the derivativeAt() method works find for the CatmullRomSpline path so this is something specific to SPline. The wiki and API do not mention that the SPline needs to be treated differently from other paths...is there something that I’m missing with SPline, or is this a bug with LibGDX?
I made a simple program to show the problem. It draws the control points (yellow dots), the path itself (light gray lines), and tangent lines (green lines) using the derivativeAt() method which should point in the same direction as the path.
Here is what it should be doing. The CatmulRomSpline works fine as the green tangent lines point in the same direction as the path:
Here is what the BSpline does. The tangent lines point in a variety of directions which are not the direction of the path:
Here is my code. Any help getting this to work properly will be greatly appreciated.
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();
}
}
来源:https://stackoverflow.com/questions/36257511/bspline-derivativeat-method-does-not-return-correct-value