ARCore中根据屏幕坐标计算射线的算法

ARCore中提供了根据屏幕坐标、视口大小及view、 project矩阵计算从屏幕坐标发射一条射线的方法,此方法用于3D拾取。

 1 class Ray {
 2
 3     public final Vector3f origin;//射线起点
 4     public final Vector3f direction;//射线方向
 5
 6     public Ray(Vector3f origin, Vector3f direction) {
 7         this.origin = origin;
 8         this.direction = direction;
 9     }
10
11     //根据屏幕坐标计算射线——3D拾取
12     public static Ray screenPointToRay(Vector2f point, Vector2f viewportSize, float[] viewProjMtx) {
13         point.y = viewportSize.y - point.y;//转化为左下角为原点
14         float x = point.x * 2.0F / viewportSize.x - 1.0F;//转换到[-1,1]
15         float y = point.y * 2.0F / viewportSize.y - 1.0F;//转换到[-1,1]
16
17         float[] farScreenPoint = new float[]{x, y, 1.0F, 1.0F};//远平面上的坐标透视除法之后的值
18         float[] nearScreenPoint = new float[]{x, y, -1.0F, 1.0F};//近平面上的坐标透视除法之后的值
19
20         float[] nearPlanePoint = new float[4];//用于记录世界坐标系下,近平面上的点
21         float[] farPlanePoint = new float[4];//用于记录世界坐标系下,远平面上的点
22
23         float[] invertedProjectionMatrix = new float[16];
24         Matrix.setIdentityM(invertedProjectionMatrix, 0);
25         Matrix.invertM(invertedProjectionMatrix, 0, viewProjMtx, 0);//计算逆矩阵
26
27         Matrix.multiplyMV(nearPlanePoint, 0, invertedProjectionMatrix, 0, nearScreenPoint, 0);//计算世界坐标系中,对应到近平面的坐标
28         Matrix.multiplyMV(farPlanePoint, 0, invertedProjectionMatrix, 0, farScreenPoint, 0);
29
30         Vector3f direction = new Vector3f(farPlanePoint[0] / farPlanePoint[3], farPlanePoint[1] / farPlanePoint[3], farPlanePoint[2] / farPlanePoint[3]);
31         Vector3f origin = new Vector3f(new Vector3f(nearPlanePoint[0] / nearPlanePoint[3], nearPlanePoint[1] / nearPlanePoint[3], nearPlanePoint[2] / nearPlanePoint[3]));
32         direction.sub(origin);
33         direction.normalize();
34         return new Ray(origin, direction);
35     }
36 }

原理:

一、世界坐标系的点P1转化到投影空间得到点P2的公式是:P2 = P1 * viewMatrix * projectMatrix = P1 * viewProjMatrix;

在渲染管线中,投影空间的点还需要经过透视除法,转化到x , y , z值均为[-1,1]区间内,是一个单位立方体。公式是:point_clip = P2/P2.w;

那么将点从单位立方体坐标系转化到世界坐标系的公式跟上述情况是逆过程,公式:

P2 = point_clip * wValue;
P1 = P2 * viewProjMatrix_invert;

其中wValue代表给定的w值,在ARCore中此值为1,所以并未体现在代码中。

二、上面代码片段,是将屏幕上的点的x,y坐标值均转化到[-1,1],给定近裁剪平面的点的z为-1,远裁剪平面上的点的z为1,其w值均为1,这种方法得到透视除法后单位立方体中的坐标。

因为wValue为1,所以此时farScreenPoint和nearScreenPoint就代表投影空间中的坐标点。

然后根据(一)中的结论即可得到对应到世界坐标系的坐标点,根据两个点可得到射线方法,最终即可得到射线的起点和方向。

时间: 2024-08-19 13:02:13

ARCore中根据屏幕坐标计算射线的算法的相关文章

ARCore中Pose类变换点的算法实现

ARCore中Pose类变换点的算法实现,主要分为两步,分别是平移和旋转. 1. 旋转向量:通过四元数计算旋转后的向量 参数列表:q表示四元数, v是长度为4的float数组,表示待旋转的向量,   offsetIn表示第一个坐标值的起始索引, out代表结果向量, offsetOut表示结果向量的三个坐标值在out数组中的起始索引. 1 public static void rotateVector(Quaternion q, float[] v, int offsetIn, float[]

[笔记] Node-Link可视化图中移动Node后自动布局调整算法

Node-Link可视化图中移动Node后自动布局调整算法 如果按工程来说,HyperGraph的可视化,用Node-Link可以说已经比成熟了,不论是D3.js还是各种其他JavaScript库诸如sigma.js等.不过大部分的库还是SVG的,可能一方面是SVG比较方便绑定事件,另一方面SVG也便于定义CSS去扩展样式.基于Canvas的实现也不少,感觉目前比较好看点的是GoJS,虽然free但是不是那么开源的至少js文件uglify过,开源的很好的是VIS.js.不过最喜欢的还是Tenso

计算机科学中最重要的32个算法

奥地利符号计算研究所(Research Institute for Symbolic Computation,简称RISC)的Christoph Koutschan博士在自己的页面上发布了一篇文章,提到他做了一个调查,参与者大多数是计算机科学家,他请这些科学家投票选出最重要的算法,以下是这次调查的结果,按照英文名称字母顺序排序. A* 搜索算法——图形搜索算法,从给定起点到给定终点计算出路径.其中使用了一种启发式的估算,为每个节点估算通过该节点的最佳路径,并以之为各个地点排定次序.算法以得到的次

余弦方法计算相似度算法实现

http://blog.csdn.net/cscmaker/article/details/7990600 余弦方法计算相似度算法实现 (1)余弦相似性 通过测量两个向量之间的角的余弦值来度量它们之间的相似性.0度角的余弦值是1,而其他任何角度的余弦值都不大于1;并且其最小值是-1.从而两个向量之间的角度的余弦值确定两个向量是否大致指向相同的方向.所以,它通常用于文件比较. 详见百科介绍(点击打开链接) (2)算法实现的中未使用权重(IDF ---逆文档频率),使用词项的出现次数作为向量空间的值

java文本相似度计算(Levenshtein Distance算法(中文翻译:编辑距离算法))----代码和详解

算法代码实现: package com.util; public class SimFeatureUtil { private static int min(int one, int two, int three) { int min = one; if (two < min) { min = two; } if (three < min) { min = three; } return min; } public static int ld(String str1, String str2)

两种计算自然对数的算法比較

引言 前一段时间.我写了两篇计算自然对数的算法的随笔,分别使用椭圆θ函数-算术几何平均法和泰勒级数展开式来计算. 那么这两种算法的性能怎样呢?在參考资料[3]中有下面说法:   上面的 elliptic method 就是椭圆θ函数-算术几何平均法.Taylor's method 2 就是我使用的泰勒级数展开式.能够看出,elliptic method 在计算精度大时占绝对优势.但在计算精度小时并不占优.而在我们的应用中,要计算的 decimal 数据类型的精度仅仅有 28 位有效数字,即上面的

NMath Stats 统计计算和生物统计学算法库使用方法及下载地址

NMath Stats提供了统计计算和生物统计学领域的处理功能,包括描述统计.概率分布.组合功能.多重线型回归.假设检验.方差分析计算和多元统计. 具体功能: 提供了一个数据架构类来保证多种不同的数据类型(数值型.字符串型.时间数据型和通配符型),并提供了多种操作方法设置.插入.移除.排序和改变行和列 提供了描述统计的功能,包括求平均值.求方差.求标准差.求百分率.求中值.求四分点值.求几何平均数.求调和平均值.求均方根值.求峰值.求偏斜度等 提供了专门的处理功能,比如阶乘.对数阶乘.二项式系数

TCP协议中RTO的计算

说明:  本文仅供学习交流,转载请标明出处,欢迎转载! 本文是以下文献相关内容的总结 [1] <TCP/IP详解 卷1:协议> [2] <TCP/IP协议族 第4版> [3] <计算机网络 第5版> TCP协议中经常会发生超时重传的情况,我们知道超时重传中的"时"是即RTO.RTO是Retransmission Time-OutD的缩写,该时间决定了发送方在发送数据后,在多长时间内如果没有收到ACK,就重置重传计时器,并重传上次发送失败的报文.那么R

ARCore中四元数的插值算法实现

ARCore中四元数差值算法: 其中t的取值范围为[0, 1],当 t = 0 时,结果为a:当t = 1 时,结果为b. 1 public static Quaternion makeInterpolated(Quaternion a, Quaternion b, float t) { 2 Quaternion out = new Quaternion(); 3 float cosHalfTheta = a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w