如何校准直观的指向机制

时间:2012-09-10 11:32:17

标签: c++ math 3d calibration

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

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

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()函数并校准系统?

2 个答案:

答案 0 :(得分:2)

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

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

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

  • 3D中的两条直线可以确定3D中的唯一点。

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

答案 1 :(得分: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&gt; 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)