2

我正在尝试实现一种直观的指向机制,用户可以用手直接指向屏幕上的对象。我已经准备好了大部分,除了我不确定如何写最后一部分。

基本上,我有一个校准点列表,如下所示:

typdef struct {
    Point2D pointOnScreen, // gives an x/y pixel screen position
    Point3D pointingFinger, // gives the position of the user's pointing finger, in space
    Point3D usersEyes // gives the position of the user's eyes, in space
} CalibrationPoint;

std::vector<CalibrationPoint> calibrationPoints;

现在,我的想法是我可以使用这些calibrationPoints来编写一个看起来像这样的函数:

Point2D whereIsTheUserPointing(Point3D pointingFinger, Point3D usersEyes) {
     return the corresponding point on screen; // this would need to be calibrated
                                               // somehow using the calibrationPoints
}

但我很难弄清楚如何做到这一点。基本思想是,当您指向时,您将手指对齐,以便your eyes- finger-object you're pointing at对齐在一条直线上。但是,由于我没有 3D 屏幕的位置,我想我可以获取校准点并从中推断出用户指向的位置。我将如何编写whereIsTheUserPointing()函数和校准系统?

4

2 回答 2

2

我正在理想化,但也许这将是一个开始:

  • 我假设您可以获得眼睛和指尖的通用 3D 坐标。

  • 3D 空间中的三个点跨越一个平面。如果我们可以确定屏幕上的三个点,我们就可以在 3D 空间中定位屏幕平面。为了安全起见,让我们定位所有四个角,这样我们不仅知道平面,还知道它的边界。

  • 相交的两条 3D 直线确定 3D 中的唯一点。

因此,为了找到屏幕的四个角,产生四对直线,两条线穿过每个角。这可以通过要求用户指向四个角,移动,然后再次指向四个角来完成。

于 2012-09-10T11:42:00.740 回答
0

设眼睛的坐标为 (a,b,c),手指末端的坐标为 (x,y,z)。您可以轻松地在 3D 中可视化连接线。您现在需要做的就是延长线直到它与屏幕的“平面”相交。

在您的情况下,线的参数坐标将是:

(a + T(x-a), b + T(y-b), c + T(z-c))

with:

eye at (a,b,c) and finger at (x,y,z).

当 T = 0 时,您将获得眼睛的坐标。使用 T=1,您将获得手指末端的坐标。你可以用 T>1 来“扩展”这条线。

假设您有屏幕平面的 z 坐标,您可以T使用以下公式轻松获得 的值:

T = (Z_VALUE_OF_PLANE-c)/(z-c)

代入此 T 值以获得其他两个坐标 (x,y)。

2D 平面上的最终坐标为:

X = a + ((Z_VALUE_OF_PLANE-c)/(z-c))*(x-a)
Y = b + ((Z_VALUE_OF_PLANE-c)/(z-c))*(y-b)
于 2012-09-10T11:47:04.517 回答