5

キャンバスの座標系を変更する方法についての情報を見つけようとしています。円や線などを使用してキャンバスに描画したいベクターデータがいくつかありますが、データの座標系がキャンバスの座標系と一致していません。

使用している単位を画面の単位にマッピングする方法はありますか?

ディスプレイ全体を占めていないImageViewに描画しています。

各描画呼び出しの前に独自の計算を行う必要がある場合、ImageViewの幅と高さを見つけるにはどうすればよいですか?

私が試したgetWidth()とgetHeight()の呼び出しは、ImageViewのサイズではなく、キャンバス全体のサイズを返しているようです。これは役に立ちません。

私はいくつかのマトリックスのものを見ます、それは私のために働く何かですか?

「publicvoidscale(float sx、float sy)」を使ってみましたが、各ピクセルを拡大することで、ベクトルスケール関数というよりは、ピクセルレベルのズームのように機能します。これは、画面に合わせて寸法を大きくすると、線の太さも大きくなることを意味します。


アップデート:

いくつかの調査の後、私は座標系を他のものに変更する方法はないと考え始めています。すべての座標を画面のピクセル座標にマッピングし、各ベクトルを変更してマッピングする必要があります。getWidth()とgetHeight()は、今ではうまく機能しているようです。何が悪かったのかは言えますが、コンストラクター内ではこれらのメソッドを使用できないのではないかと思います。

4

3 に答える 3

2

返信いただきありがとうございます。私は、これを自分が思うように機能させることをほとんどあきらめました。もちろん、物事が起こるべきだと私が考える方法は、実際に起こる方法ではありません。:)

これは基本的にどのように機能するかですが、場合によってはピクセル単位でずれているように見え、まだ把握していない境界条件に到達すると、円はセクションが欠落しているように見えます. 個人的には、これがアプリケーション コード内にあることは受け入れられず、Android ライブラリにある必要があると思います。:)

private class LinearMapCanvas
{
    private final Canvas canvas_; // hold a wrapper to the actual canvas.

    // scaling and translating values:
    private double scale_;

    private int translateX_;
    private int translateY_;

// linear mapping from my coordinate system to the display's:
    private double mapX(final double x)
    {
    final double result = translateX_ + scale_*x;
    return result;
    }

    private double mapY(final double y)
    {
        final double result = translateY_ - scale_*y;
        return result;
    }

    public LinearMapCanvas(final Canvas canvas)
    {
        canvas_ = canvas;

// Find the extents of your drawing coordinates:
        final double minX = extentArray_[0];
    final double minY = extentArray_[1];
    final double maxX = extentArray_[2];
    final double maxY = extentArray_[3];

// deltas:
    final double dx = maxX - minX;
    final double dy = maxY - minY;

// The display's available pixels, accounting for margins and pen stroke width:
    final int width = width_ - strokeWidth_ - 2*margin_;
    final int height = height_ - strokeWidth_ - 2*margin_;

    final double scaleX = width / dx;
    final double scaleY = height / dy;

    scale_ = Math.min(scaleX , scaleY); // Pick the worst case, so the drawing fits

// Translate so the image is centered:
        translateX_ = (int)((width_ - (int)(scale_*dx))/2.0 - scale_*minX);
        translateY_ = (int)((height_ - (int)(scale_*dy))/2.0 + scale_*maxY);
    }

// wrappers around the canvas functions you use.  These are only two of many that would need to be wrapped.  Annoying and error prone, but beats any alternative I can find.
    public void drawCircle(final float cx, final float cy, final float radius, final Paint paint)
    {
    canvas_.drawCircle((float)mapX(cx), (float)mapY(cy), (float)(scale_*radius), paint);
    }

    public void drawLine(final float startX, final float startY, final float stopX, final float stopY, final Paint paint)
    {
    canvas_.drawLine((float)mapX(startX), (float)mapY(startY), (float)mapX(stopX), (float)mapY(stopY), paint);
    }
...
}
于 2010-06-13T00:46:39.050 に答える
1

preScale()キャンバスのマトリックスの方法を使用して、キャンバス座標を独自の単位にスケーリングできます。ただし、これは Paint のストローク幅もスケーリングするため、希望どおりにならない可能性があることに注意してください。

于 2011-04-16T11:31:51.207 に答える
0

Android でその場でカスタム ベクター グラフィックスを実行する唯一の方法は、すべてを画像ファイルに描画してから、ImageView. あなたが求めていることを正確に理解しているかどうかはわかりませんが、唯一の問題がスケーリングである場合、ImageView はandroid:scaleType="center"、のプロパティとして使用して、指定された画像を独自のサイズにスケーリングしImageViewます。

座標系を変更する限り、それが可能であるとは思えません (調査はしていませんが)。ただし、データのシステムを標準の Android 座標系にマップする関数を作成するのはかなり簡単かもしれません。

于 2010-06-11T17:34:31.897 に答える