缩放和平移后如何获得相对于画布的触摸坐标?

2023-11-26

在移动和缩放画布后,我需要获得相对于画布的 x 和 y 触摸,以检查碰撞和类似的情况。

每当我平移画布或围绕原点 (0,0) 缩放画布时,我已经设法通过使用以下代码获取触摸坐标:

private float convertToCanvasCoordinate(float touchx, float touchy) {
    float newX=touchx/scale-translatex;
    float newY=touchy/scale-translatey
}

但是如果我围绕另一个点缩放画布,例如canvas.scale(scale,scale,50,50),这不起作用。

我知道它不应该工作,但我只是不知道如何解决它。我已经看过其他问题,但没有一个答案谈到如果我根据特定点缩放如何获取坐标。


在 Android 中正确制作场景的最基本方法是使用矩阵来修改视图,并使用该矩阵的逆来修改触摸。这是一个简化的答案。保持很短。

public class SceneView extends View {
    Matrix viewMatrix = new Matrix(), invertMatrix = new Matrix();
    Paint paint = new Paint();
    ArrayList<RectF> rectangles = new ArrayList<>();
    RectF moving = null;

    public SceneView(Context context) { super(context); }
    public SceneView(Context context, AttributeSet attrs) { super(context, attrs); }
    public SceneView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //transform touch. (inverted matrix)
        event.transform(invertMatrix);
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                moving = null;
                //collision detection
                for (RectF f : rectangles) {
                    if (f.contains(event.getX(), event.getY())) {
                        moving = f;
                        return true;
                    }
                }
                // adding arbitrary transforms.
                viewMatrix.postTranslate(50,50);
                viewMatrix.postScale(.99f,.99f);
                viewMatrix.postRotate(5);
                // inverse matrix is needed for touches.
                invertMatrix = new Matrix(viewMatrix);
                invertMatrix.invert(invertMatrix);
                break;
            case MotionEvent.ACTION_MOVE:
                if (moving != null) {
                    moving.set(event.getX() - 50, event.getY() - 50, event.getX() + 50, event.getY() + 50);
                }
                break;
            case MotionEvent.ACTION_UP:
                if (moving == null) {
                    rectangles.add(new RectF(event.getX() - 50, event.getY() - 50, event.getX() + 50, event.getY() + 50));
                }
                break;
        }
        invalidate();
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // transform the view by the matrix.
        canvas.concat(viewMatrix);
        // draw objects
        for (RectF f : rectangles) {
            canvas.drawRect(f,paint);
        }
    }

这是相当简约的,但它显示了所有相关方面。

  1. 移动视图
  2. 触摸修改
  3. 碰撞检测。

每次触摸屏幕时,它都会对角移动、缩小和旋转(基本上呈螺旋形移动),并创建一个黑色矩形。如果您触摸矩形,您可以根据自己的喜好移动它们。当您单击背景时,视图会更加螺旋化,并删除黑色矩形。

See: https://youtu.be/-XSjanaAdWA


另一种方法行不通。理论上,您可以获取我们想要的场景并通过 View 类而不是在画布中进行转换。这将使触摸事件发生在与屏幕相同的空间中。但是 Android 会取消在视图之外发生的触摸事件,因此在视图的原始剪切部分之外开始的 MotionEvent 将被丢弃。所以这是不可能的。您想要变换画布,并对 MotionEvents 进行反变换。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

缩放和平移后如何获得相对于画布的触摸坐标? 的相关文章

随机推荐

  • 用户定义的支持加法的int类

    我想创建一个类来包装int并允许一些通常不允许的事情int类型 这是我的代码 class tInt int def add self other if type other str return str self str other eli
  • 使用 \==/2 或 diff/2

    如果我想确保两个变量不会实例化为同一个术语 首选的方法是什么 假设我需要在图中找到有向边 并且节点本身不能有边 node a x y node b z x node c y y 这里的边是 a gt c b gt a 但是notc gt c
  • 将 UIView 从底部移动到顶部

    如何在代码中将视图从底部移动到顶部 colorView hidden NO colorView UIView alloc init colorView frame CGRectMake 0 480 320 480 colorView bou
  • 从 Python 调用 PHP

    是否可以使用 python 运行 PHP 脚本 您可以查看subprocess类 更具体地说 subprocess call subprocess call popenargs kwargs subprocess call php path
  • Moq DbSet NotImplementedException

    我有一个 Moq DbSet 直到最近一直在工作 但是自从上次更新依赖项以来 它一直抛出NotImplementedException on IQueryable Provider 使用的代码如下 var mockSet new Mock
  • 如何使用Application Verifier查找内存泄漏

    我想使用标准实用程序查找应用程序中的内存泄漏 以前我使用自己的内存分配器 但其他人 是的 你 AlienFluid 建议使用微软的应用程序验证器 但我似乎无法让它报告我的泄漏 我有以下简单的应用程序 include
  • 输入/输出流:流结束?

    我一直想知道 流的结尾是什么 在 java io 包中大多数 readLine 方法的 javadoc 中 您可以读到 如果到达流末尾 则返回 null 尽管我实际上从未得到 null 因为大多数流 在网络的情况下 我最常使用的流 只是阻止
  • DOM 改变元素内容

    如何使用 PHP DOM 函数更改元素内容 深入 我已经查询了我的元素 修改了属性 现在想要更改它的内容 我该怎么做 Set the nodeValue属性如果你想设置元素的文本内容 el dom gt getElementById foo
  • 非词法生命周期借用检查器会提前释放锁吗?

    我读了什么是非词汇生命周期 使用非词法借用检查器 可以编译以下代码 fn main let mut scores vec 1 2 3 let score scores 0 borrows scores but never used its
  • 将 pandas 数据框中的浮点数转换为字符串

    我在 pandas 中有一个包含日期时间和浮点数据的数据框 time price1 price2 2018 02 01T00 00 00 000Z 1 4526547885 1 654775563 我需要将列转换为字符串格式 以便price
  • 如何在 Perl 中进行 64 位算术?

    我是一个 Perl 新手 我可以在 Perl 中简单地使用 64 位算术吗 例如 operand1 0xFFFFFFFFFFFF 48 bit value operand2 0xFFFFFFFFFFFF 48 bit value Resul
  • 删除powershell中的子目录,包括符号链接

    目前遇到问题 我目前正在这样做 Get ChildItem PATH Recurse ErrorAction SilentlyContinue Where Object Attributes notmatch Directory and L
  • 使用 lambda 而不是字符串属性名称选择模型属性

    我正在构建一个类型的属性列表 以包含在该类型的集合的导出中 我想在不使用属性名称字符串的情况下执行此操作 列表中仅包含该类型的某些属性 我想做这样的事情 exportPropertyList
  • Go - HTML 注释未呈现

    我正在构建 Go Web 应用程序 我在渲染的 html 页面上发现了一些异常 我所有的 html 评论突然没有被渲染 我猜是因为我使用的go版本 刚刚更新到更高版本 因为在我更新之前它是好的 这是我的代码 ul class breadcr
  • Java 8、类型注释和 JSR 308

    我已经安装了最新的 JDK 8 b116 但我注意到我无法使用类型注释 例如 阅读 Java 教程 如果我写 String str null String myString NonNull String str or TEST st new
  • 如何在c#中检索字符串formData js

    我必须在 net 的 Web api 中检索 idPerson 的值 我已经检索到文件 UploadedImage 但我无法检索 idPerson 的值 有人有解决办法吗 Thx 我的js函数 Upload de l image de pr
  • 零长度位域的实际使用

    我对 C 不太确定 但 C 允许长度为 0 的未命名位字段 例如 struct X int 0 问题一 这个可以有什么实际用途you考虑到 问题二 您知道哪些实际用途 如果有 Edited 您使用零长度位字段作为一种黑客方法 让编译器布局一
  • UIWebView stringByEvaluatingJavaScriptFromString

    我一直致力于让一些非常基本的 JS 在我的 UIWebView 中运行 在网络视图的委托中 我有 void webViewDidFinishLoad UIWebView wView NSString someHTML wView strin
  • 删除子图

    我正在尝试找出一种删除 动态 matplotlib 中的子图的方法 我看到他们有一个remove方法 但我收到错误 NotImplementedError cannot remove artist 我很惊讶我在任何地方都找不到这个 有谁知道
  • 缩放和平移后如何获得相对于画布的触摸坐标?

    在移动和缩放画布后 我需要获得相对于画布的 x 和 y 触摸 以检查碰撞和类似的情况 每当我平移画布或围绕原点 0 0 缩放画布时 我已经设法通过使用以下代码获取触摸坐标 private float convertToCanvasCoord