ARCore中根据屏幕坐标计算射线的算法
2017-09-07 12:03
471 查看
ARCore中提供了根据屏幕坐标、视口大小及view、 project矩阵计算从屏幕坐标发射一条射线的方法,此方法用于3D拾取。
原理:
一、世界坐标系的点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就代表投影空间中的坐标点。
然后根据(一)中的结论即可得到对应到世界坐标系的坐标点,根据两个点可得到射线方法,最终即可得到射线的起点和方向。
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就代表投影空间中的坐标点。
然后根据(一)中的结论即可得到对应到世界坐标系的坐标点,根据两个点可得到射线方法,最终即可得到射线的起点和方向。
相关文章推荐
- java根据经纬度坐标计算两点的距离算法
- 根据凸多边形顶点坐标来计算面积算法与实现
- java根据GPS经纬度坐标计算两点的距离算法
- java根据经纬度坐标计算两点的距离算法,与百度地图测距工具相符
- 根据两点经纬度坐标计算距离的算法
- java根据经纬度坐标计算两点的距离算法
- 8位色320*200分辨率下的屏幕坐标与VRAM地址计算
- 百度地图API二:根据标注点坐标范围计算显示缩放级别zoom自适应显示地图
- 【OpenCV】仿射变换 根据眼睛坐标进行人脸对齐 计算变换后对应坐标
- 【百度地图API】如何根据摩卡托坐标进行POI查询,和计算两点距离
- 屏幕坐标设置颜色变化(根据透视x坐标实现一个红色光带)
- 根据两点经纬坐标计算两点间的距离[JAVA](转载)
- 根据手机的分辨率和屏幕尺寸计算手机屏幕的PPI
- 根据年和月计算这个月有多少天的算法
- mysql函数-根据经纬度坐标计算距离
- Android平台根据分辨率计算屏幕尺寸,基于物理尺寸来验证手机和平板应用合并的可行性
- opencv中3D点根据相机参数投影成2D点+solvePnP函数计算相机姿态+2D坐标到3D+相机参数calibration(标定与配准,求得深度彩色相机的内参与外参,再进行配准)
- Android平台根据分辨率计算屏幕尺寸,基于物理尺寸来验证手机和平板应用合并的可行性
- 根据两个百度地图坐标计算两点的距离
- 算法回顾(冒泡排序,递归法,根据指定字符串与字符计算字符串中字符出现数)