You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AR绘图应用OpenGL线程传递vector3f时Y轴数据异常排查

排查AR绘图应用中触摸Y坐标跳变的问题

结合你提供的日志和项目背景,我之前也碰到过类似的Android触摸与OpenGL坐标系交互的坑,大概率是这几个核心问题导致的:

1. Y轴坐标被重复转换(最可能的原因)

从你的日志看,1641和148的Y值明显是屏幕高度互补的关系——假设你的设备屏幕高度是1641+148=1789,那148正好是屏幕高度 - 1641的结果。这说明你的触摸坐标被执行了两次Y轴翻转:

  • Android触摸事件的Y轴原点在屏幕左上角,而OpenGL默认视口的Y轴原点在左下角,正常逻辑需要做一次y = 屏幕高度 - y的转换。
  • 如果这个转换逻辑同时出现在了onTouchEvent(UI线程记录坐标时)和update(GL线程处理坐标时),就会导致:第一次转换是正确的,第二次又把已经转换过的坐标再翻转一次,最终出现正确值和反向值交替的情况。

2. 多线程数据同步的竞态条件

触摸坐标在UI线程的onTouchEvent中更新,却在GLThread的onDrawFrame中读取使用,如果存储坐标的变量没有做线程同步:

  • 比如用了普通成员变量而非volatile修饰,或者没有通过原子类/锁来保证可见性,GLThread可能会交替读取到新的触摸值和旧的初始值(比如屏幕中心的148),表现为坐标跳变。

3. 触摸状态处理的逻辑错误

日志里每次touch move都是同一个坐标,但多次触发point added,且Y值交替,可能是:

  • update方法中处理触摸点时,错误地翻转了某个状态标记(比如isCoordinateConverted),导致每次处理要么用原始坐标,要么用错误的转换后坐标;
  • 触摸事件的重复回调被错误地重复处理,没有做“去重”判断,同时某个中间变量被意外重置为屏幕中心值。

具体排查与修复步骤

第一步:验证坐标转换逻辑

  • 找到项目中屏幕坐标转OpenGL坐标的代码块,检查是否在onTouchEvent和update方法中都执行了Y轴翻转。如果是,去掉其中一处(推荐在onTouchEvent中完成转换,再把最终坐标传递给GL线程)。
  • 直接打印设备屏幕高度:getResources().getDisplayMetrics().heightPixels,确认屏幕高度 - 1641是否等于148,这能直接验证重复转换的猜想。

第二步:修复线程同步问题

  • 把存储触摸坐标的变量加上volatile修饰,比如:
    private volatile float currentTouchX;
    private volatile float currentTouchY;
    
  • 在update方法中处理坐标时,先把当前值复制到局部变量,避免处理过程中被UI线程修改:
    float x = currentTouchX;
    float y = currentTouchY;
    // 用x和y来添加point,而不是直接访问成员变量
    

第三步:排查触摸状态逻辑

  • 检查onTouchEvent的ACTION_MOVE分支,确认每次回调都正确更新了坐标,没有在某些条件下意外重置Y值到屏幕中心;
  • 查看update方法中处理触摸点的逻辑,是否有错误的状态翻转(比如布尔变量每次处理都取反),导致交替使用不同的Y值。

内容的提问来源于stack exchange,提问作者Edik Neznanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:20:40