首页 > 解决方案 > 如何将 2D 水平(Oxy)平面上的点渲染为 2D 垂直(电话)平面上的点?

问题描述

我正在尝试将(经度/纬度)位置转换为电话屏幕上的矩形。但是现在让我们假设它们是 Oxy 平面上的正常点。

假设相机站在点(X,Y),对应于手机屏幕的中心。它指向方向(vx,vy),具有 60 度视锥(顺时针 30 度和逆时针 30 度)。相机方向可以自由旋转,所以vx, vy in [-1 -> 1].

有一个Npoint列表(x[], y[]),每个代表一个位置。

在每一步,都会选择视锥内的所有点,将它们称为(px[], py[])。这一步很简单。接下来,我需要(px[], py[])在手机屏幕上绘图。最大的问题是相机+两点共线的时候。我对如何处理这个问题的想法为零。编辑:两个点都必须显示在屏幕上,所以也许添加一些随机偏移?

给定相机位置、相机观察方向和一个点px[i], py[i],它在屏幕上的像素坐标是多少?如果没有足够的信息,那么任何可以处理共线情况的方法都可以。

编辑:

在此处输入图像描述

在此处输入图像描述

图 1 显示了一个示例。给定点 + 相机位置/方向,点 1、2、3、4 在视野中。然后,它们会显示在屏幕上,如图 2 所示。

2D 的可能解决方案(屏幕上没有 3D 的错觉):

  1. 水平位置:使用与相机方向的角度来确定它是否在屏幕的左侧/右侧。使用最大角度标准化角度。归一化角度 (0->1) 用于确定该点向左/向右多远,这normAngle = 0意味着它在屏幕的中间,并且normAngle = 1意味着它在屏幕的最左边/最右边的像素处。

  2. 垂直位置:与上面相同,但使用与相机的标准化距离而不是与相机方向的角度。

有没有更好的办法?

标签: graphicscamerageometryviewportprojection

解决方案


您可以将值映射point_angle-central_angle-Pi/2..Pi/2 (-90..90)范围(假设零角度指向屏幕顶部),因此请使用带有一些失真的极坐标。

rho = (px - camx)^2 + (py - camy)^2
point_angle = atan2(py - camy, px - camx)
deviation = point_angle - cam_angle

screen_rho = somefunction(rho)  
//in simple case just coefficent C*rho to provide proper distance in screen limits
screen_angle = 3 * deviation   //-30 =>-90 

screen_x = screen_rho * cos(screen_angle)
screen_y = screen_rho * sin(screen_angle)

推荐阅读