Android 画布坐标系

发布于 2024-09-03 17:28:41 字数 618 浏览 1 评论 0原文

我正在尝试查找有关如何更改画布坐标系的信息。我有一些矢量数据,想使用圆形和线条等绘制到画布上,但数据的坐标系与画布坐标系不匹配。

有没有办法将我正在使用的单位映射到屏幕的单位?

我正在绘制一个不占用整个显示屏的 ImageView。

如果我必须在每次绘图调用之前进行自己的计算,如何找到 ImageView 的宽度和高度?

我尝试的 getWidth() 和 getHeight() 调用似乎返回整个画布大小而不是 ImageView 的大小,这没有帮助。

我看到一些矩阵的东西,这对我有用吗?

我尝试使用“public void scale(float sx, float sy)”,但这更像是像素级缩放而不是与通过扩展每个像素的矢量缩放函数相比。这意味着如果增加尺寸以适应屏幕,则线条粗细也会增加。


更新:

经过一些研究,我开始认为没有办法将坐标系更改为其他坐标系。我需要将所有坐标映射到屏幕的像素坐标,并通过修改每个向量来实现。 getWidth() 和 getHeight() 现在似乎对我来说效果更好。我可以说出了什么问题,但我怀疑我不能在构造函数中使用这些方法。

I'm trying to find information on how to change the coordinate system for the canvas. I have some vector data I'd like to draw to a canvas using things like circles and lines, but the data's coordinate system doesn't match the canvas coordinate system.

Is there a way to map the units I'm using to the screen's units?

I'm drawing to an ImageView which isn't taking up the entire display.

If I have to do my own calculations prior to each drawing call, how to I find the width and height of my ImageView?

The getWidth() and getHeight() calls I tried seem to be returning the entire canvas size and not the size of the ImageView which isn't helpful.

I see some matrix stuff, is that something that will work for me?

I tried to use the "public void scale(float sx, float sy)", but that works more like a pixel level zoom rather than a vector scale function by expanding each pixel. This means if the dimensions are increased to fit the screen, the line thickness is also increased.


Update:

After some research I'm starting to think there's no way to change coordinate systems to something else. I'll need to map all my coordinates to the screen's pixel coordinates and do so by modifying each vector. The getWidth() and getHeight() seem to be working better for me now. I can say what was wrong, but I suspect I can't use these methods inside the constructor.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

固执像三岁 2024-09-10 17:28:41

感谢您的回复。我几乎已经放弃了让它按照我认为应该的方式工作。当然,我认为事情应该如何发生并不代表事情确实如此发生。 :)

这基本上是它的工作原理,但在某些情况下它似乎会偏离一个像素,并且当物体落在我尚未弄清楚的某些边界条件上时,圆圈似乎会丢失部分。就我个人而言,我认为这在应用程序代码内部是不可接受的,应该在 Android 库中......眨眨眼,如果你在 Google 工作,请轻推。 :)

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);
    }
...
}

Thanks for the reply. I have pretty much given up on getting this to work in the way I think it should. Of course how I think things should happen isn't how they do happen. :)

Here's basically how it works, but it seems to be off by a pixel in some cases and the circles seem to be missing sections when things land on some boundary conditions I have yet to figure out. Personally I think this is unacceptable to be inside application code and should be in the Android libraries... wink wink, nudge nudge if you work for Google. :)

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);
    }
...
}
楠木可依 2024-09-10 17:28:41

您可以使用画布矩阵的 preScale() 方法将画布坐标缩放为您自己的单位。但请注意,这也会缩放 Paint 的描边宽度,这可能不是您想要的。

You can scale the canvas co-ordinates to your own units using the preScale() method of the canvas' matrix. Be aware though that this also scales the Paint's stroke width, which may not be what you want.

烂柯人 2024-09-10 17:28:41

据我所知,在 Android 中动态执行自定义矢量图形的唯一方法是将所有内容绘制到图像文件中,然后将其放入 ImageView 中。我不确定我是否完全理解您的要求,但如果唯一的问题是缩放,则 ImageView 将使用 android:scaleType="center" 将其指定的任何图像缩放为其自己的大小ImageView 的属性。

至于改变坐标系,我怀疑这是可能的(尽管我还没有研究过)。不过,编写一个将数据系统映射到标准 Android 坐标系的函数可能相当简单。

The only way I know of to do custom vector graphics on the fly in Android is to draw everything into an image file and then put that into an ImageView. I'm not sure I understand exactly what you are asking, but if the only issue is scaling, the ImageView will scale whatever image it is given to its own size using android:scaleType="center" as a property of the ImageView.

As far as changing the coordinate system, I doubt that is possible (although I haven't researched it). It might be fairly trivial to write a function that would map your data's system to the standard Android coordinate system, though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文