Найти точку на пути в трехмерном пространстве, учитывая начальное и конечное положение и начальный вектор скорости - PullRequest
3 голосов
/ 01 июля 2011

Допустим, у меня есть объект в трехмерном пространстве, и я знаю его вектор положения (x, y, z) и вектор скорости (поэтому его ориентацию в пространстве).

Начиная с известной точки AI, необходимо достичь известной точки B в два этапа:

a) повернуть по круговой траектории с известным радиусом R до точки C

б) идти прямо из точки C в конечную точку B.

Скорость (скалярное значение) не важна.Скорость (вектор) известна, поэтому, я думаю, она должна определять плоскость, в которой находится окружность, касаясь ее, а также линию между А и В ...

Я хочу знать, как найтикоординаты (x, y, z) для C и вектор скорости сущности, находящейся там.

Ответы [ 3 ]

4 голосов
/ 01 июля 2011

Обновление: см. Рабочую демонстрацию!

Если я правильно понимаю, ваша ситуация (в плоскости, содержащей A, B и v ) такая, как показано на диаграмме ниже. Заданы точки A и B, а также вектор v и расстояние r . Вы хотите найти точку C.

enter image description here

Хорошо, пусть вектор w = (-v̂ y , v̂ x ) будет единичным вектором, перпендикулярным v . Тогда O = A + r w .

Теперь, | C - O | = r и (C - B) · (C - O) = 0 (где · - скалярное произведение). Объедините их, чтобы получить квадратное уравнение, которое вы можете решить, чтобы найти два возможных положения для C. Затем выберите одно с правильным знаком для (C - B) × (C - O).

(есть второй выбор для центра круга, O = A - r w , представляющий поворот по часовой стрелке вместо против часовой стрелки. Это дает вам еще одну возможность для C. I думаю, вам придется использовать эвристику, чтобы решить, какой из них вы предпочитаете: может, тот, который имеет наименьший OCAOC.)


St0rM просит помощи в выполнении этого в 3D (см. Комментарии). Это легко! Плоскость, содержащая A, B и v , имеет вектор нормали n = (A - B) × v . Пусть u = n × v будет вектором, перпендикулярным к n и v , и пусть w = û (единичный вектор в направлении u ).

Вам также нужно будет принять во внимание, что C лежит в той же плоскости, что и A: C · n = A. n и "правильный знак для (C - B) × (C - O) «становится» правильным знаком для (C - B) × (C - O) · n ».


Не можете решить эту систему уравнений?

Хорошо, если (C - B) · (C - O) = 0, то (C - O + O - B) · (C - O) = 0, поэтому (C - O) · (C - O ) + (O - B) · (C - O) = 0, поэтому C · (O - B) = O · (O - B) - r 2 .

Вы заметите, что это уравнение для плоскости, как и C · n = A. n . Пересечь эти две плоскости ( подробности см. В Википедии - вы можете использовать более простое решение, поскольку плоскости ортогональны и их легко можно сделать ортонормированными), чтобы получить уравнение прямой, на которой лежит C: C = H + λL, скажем, где L = n × (B - O). Затем используйте (C - O) · (C - O) = r 2 , чтобы превратить это в квадратное уравнение в λ. Вы обнаружите, что квадратное уравнение значительно упрощается, если переписать уравнение линии как C = H + λL + O, так что вхождения «- O» исчезают.

enter image description here

Вот реализация на Python, использующая numpy для создания векторной алгебры. Я уверен, что вы можете выяснить, как перевести это на язык по вашему выбору.

import math
from numpy import cross, dot
from numpy.linalg import norm

def unit(v):
    """Return a unit vector in the same direction as v."""
    return v / norm(v)

def turnpoints(A, B, v, r):
    """Generate possible turning instructions for a path from A to B
that starts out in direction v, turns through part of a circle of radius
r until it reaches a point C (to be determined), then heads straight for
B. Return each instruction in the form (sense, C) where sense is -1 for
clockwise and +1 for anticlockwise."""
    n = unit(cross(A - B, v))   # Unit normal to plane containing A, B, v.
    w = unit(cross(n, v))       # Unit normal to v lying in that plane.
    for sense in (-1, +1):      # Turn clockwise or anticlockwise?
        O = A + sense * r * w   # Centre of turning circle.
        BB = B - O
        m = unit(BB)
        # C lies on the line H + l*L + O
        H = dot(A, n) * n + (r**2 / norm(BB)) * m
        L = cross(n, m)
        # |C - O| = r**2 gives quadratic eqn in l with coefficients a=1, b=0, c.
        c = dot(H, H) - r**2
        disc = - 4 * c          # Discriminant of quadratic eqn.
        if disc < 0:
            continue            # No tangents (B inside circle).
        elif disc == 0:         # One tangent (B on circle).
            C = H + O
            yield (sense, C)
        else:                   # Two tangents (B outside circle)
            for sign in (-1, +1):
                l = sign * math.sqrt(disc) / 2
                C = H + l * L + O
                # Only one choice for C is correct (the other involves
                # reversing direction).
                if dot(cross(C - B, C - O), n) * sense > 0:
                    yield (sense, C)
1 голос
/ 05 июля 2011

Возможно, это более короткая версия.Вы можете вычислить C из:

H = O + (r ^ 2) / | BB |) * m

C = H + l * (sqrt (r ^ 2 - | HO |^ 2)) // это просто применяет Pytagora для определения величины HC

в качестве доказательства концепции:

   cml::vector3f A( 4, 3, 2);
   cml::vector3f B( 1, 5, 0);

   cml::vector3f v( 1, 0, 0);
   float r = 1.4142;

   cml::vector3f n = cml::cross((A-B),v);
   n.normalize();
   cout << "n: " << n << endl;

   cml::vector3f w = cml::cross(n,v);
   w.normalize();
   cout << "w: " << w << endl;

   cml::vector3f O = A + r*w;
   cout << "O: " << O << endl;

   cml::vector3f m = B-O;
   m.normalize();
   cout << "m: " << m << endl;

   cml::vector3f OB = B - O;
   cml::vector3f H = O + m * ( pow(r,2) / OB.length() );
   cout << "H: " << H << endl;

   cml::vector3f l = cml::cross(m,n);;
   l.normalize();
   cout << "l: " << l << endl;

   cml::vector3f OH = H - O;
   cml::vector3f C = H + l * ( sqrt( pow(r,2)-pow(OH.length(),2) ) );
   cout << "C: " << C << endl;
1 голос
/ 01 июля 2011

Ву, это интересно.

  1. Найдите плоскость, на которой существуют точки A, B и скорость объекта. Все будет происходить в этой плоскости, так что теперь вы можете думать о проблеме как о 2D, хотя математика все равно будет 3D.
  2. Найдите центральную точку круга, по которому сущность будет путешествовать по плоскости. Эта центральная точка будет перпендикулярна скорости объекта на расстоянии R. На самом деле будет 2 разных места, куда вы могли бы поместить круг, вам нужно будет выбрать, исходя из того, что ближе к B.
  3. Найдите две прямые из B, которые касательны к окружности. Точки, где эти линии касаются круга, - это две ваши возможности для C. Определите, какая точка позволит вашей сущности ударить по B, когда она достигнет ее и покинет круг (другая точка приведет сущность в совершенно противоположное направление).

Исходя из этого, вы должны иметь возможность получить положение C, и я вполне уверен, что, если сущность не меняет скорость, вектор должен быть просто единичным вектором от C до B, умноженным на величину исходный вектор скорости.

Любое или все это может быть ошибочным. Я просто вычисляю это по рисунку на листе бумаги.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...