0

BSpline パスを使用する場合、正しい値が返されないため、derivativeAt() メソッドに問題がありますが、derivativeAt() メソッドは CatmullRomSpline パスを検索するため、これは SPline に固有のものです。ウィキと API では、SPline を他のパスとは異なる方法で処理する必要があるとは言及されていません。

問題を示す簡単なプログラムを作成しました。コントロール ポイント (黄色の点)、パス自体 (ライト グレーの線)、およびパスと同じ方向を指している必要がある 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();
    }
}
4

0 に答える 0