BSpline derivativeAt() method does not return correct value

会有一股神秘感。 提交于 2019-12-12 01:38:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!