Я пытаюсь реализовать интуитивно понятный механизм наведения, при котором пользователь будет использовать свои руки, чтобы просто указывать на объект на экране. У меня большая часть готова, но я не знаю, как написать финальную часть.
По сути, у меня есть список точек калибровки, например:
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()
функционировать и калибровать систему?
Я идеализирую, но, возможно, это будет началом:
Я предполагаю, что вы можете получить универсальные трехмерные координаты для глаз и кончика пальца.
Три точки в трехмерном пространстве охватывают плоскость. Если бы мы могли определить три точки на вашем экране, мы могли бы найти плоскость экрана в трехмерном пространстве. Чтобы быть в безопасности, давайте определим все четыре угла, чтобы мы знали не только самолет, но и его границы.
Две прямые линии в 3D, которые встречаются, определяют уникальную точку в 3D.
Таким образом, чтобы найти четыре угла экрана, создайте четыре пары прямых линий, по две линии через каждый угол. Это можно сделать, попросив пользователя указать четыре угла, переместиться, а затем снова указать четыре угла.
Пусть координаты глаз (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)