Обнаружение столкновений между 2 линейно движущимися объектами в WGS84

[Полное повторное редактирование Spektre] на основе комментариев

У меня есть две начальные точки и векторы скорости в 3D (WGS84), как мне проверить, сталкиваются ли они в 3D в течение определенного времени?

Пример ввода:

// WGS84 objects positions
const double deg=M_PI/180.0;
double pos0[3]={17.76             *deg,48.780            *deg,6054.0}; // lon[rad],lat[rad],alt[m]
double pos1[3]={17.956532816382374*deg,48.768667387202690*deg,3840.0}; // lon[rad],lat[rad],alt[m]
// WGS84 speeds in [km/h] not in [deg/sec]!!!
double vel0[3]={- 29.346910862289782,  44.526061886823861,0.0}; // [km/h] lon,lat,alt
double vel1[3]={- 44.7              ,-188.0              ,0.0}; // [km/h] lon,lat,alt

И здесь правильно преобразованные позиции в декартовы (с использованием онлайн-конвертера, ссылка на который приведена ниже):

double pos0[3]={ 4013988.58505233,1285660.27718040,4779026.13957769 }; // [m]
double pos1[3]={ 4009069.35282446,1299263.86628867,4776529.76526759 }; // [m]

И это с использованием моего преобразования из связанного QA ниже (разница может быть вызвана разными ошибками эллипсоида и / или плавающей запятой):

double pos0[3] = { 3998801.90188399, 1280796.05923908, 4793000.78262020 }; // [m]
double pos1[3] = { 3993901.28864493, 1294348.18237911, 4790508.28581325 }; // [m]
double vel0[3] = { 11.6185787807449,  41.1080659685389, 0 }; // [km/h]
double vel1[3] = { 17.8265828114202,-173.3281435179590, 0 }; // [km/h]

Мой вопрос: Как определить, столкнутся ли объекты и когда?

Что мне действительно нужно, так это если столкновение произойдет в течение определенного времени, например _min_t.

Остерегайтесь скорости [km/h] в направлении локальных North,East,High/Up векторов! Для получения дополнительной информации о преобразовании таких скоростей в декартовы координаты см. Связанные:

Для проверки / проверки преобразований положения WGS84 вы можете использовать следующий онлайн-калькулятор:

Я бы хотел по возможности избегать использования мешей, примитивов или подобных вещей.


Это попытка Андре решить эту проблему (на основе моего ответа, но без преобразования скорости), оставшуюся из исходного сообщения:

bool collisionDetection()
{
    const double _min_t = 10.0; // min_time
    const double _max_d = 5000; // max_distance
    const double _max_t = 0.001; // max_time
    double dt;
    double x, y, z, d0, d1;

    VectorXYZd posObj1 = WGS84::ToCartesian(m_sPos1);
    VectorXYZd posObj2 = WGS84::ToCartesian(m_sPos2);

    const QList<QVariant> velocity;    
    if (velocity.size() == 3)
    {
        dt = _max_t;
        x = posObj1 .x - posObj2 .x;
        y = posObj1 .y - posObj2 .y;
        z = posObj1 .z - posObj2 .z;
        d0 = sqrt((x*x) + (y*y) + (z*z));
        x = posObj1 .x - posObj2 .x + (m_sVelAV.x - velocity.at(0).toDouble())*dt;
        y = posObj1 .y - posObj2 .y + (m_sVelAV.y - velocity.at(1).toDouble())*dt;
        z = posObj1 .z - posObj2 .z + (m_sVelAV.z - velocity.at(2).toDouble())*dt;
        d1 = sqrt((x*x) + (y*y) + (z*z));
        double t = (_max_d - d0)*dt / (d1 - d0);

        if (d0 <= _max_d)
        {
            return true;
        }

        if (d0 <= d1)
        {
            return false;
        }

        if (t < _min_t)
        {
          return true;
        }
    }
    return false;
}

Предполагается, что это действительные декартово преобразованные положения и скорости, но преобразованные неправильно из-за неправильного порядка x, y, z параметров. Приведенные выше данные в правильном порядке lon, lat, alt и x, y, z, это явно не так:

posObject2 = {x=1296200.8297778680 y=4769355.5802477235 z=4022514.8921807557 }
posObject1 = {x=1301865.2949957885 y=4779902.8263504291 z=4015541.3863254949 }
velocity object 2: x = -178, y = -50, z = 8
velocity object 1: x = 0, y = -88, z = 0; 

Не говоря уже о скоростях все еще не в декартовом пространстве ...

РЕДАКТИРОВАТЬ: НОВЫЙ ТЕСТОВЫЙ СЛУЧАЙ

m_sPosAV = {North=48.970020901863471 East=18.038928517158574 Altitude=550.00000000000000 }

m_position = {North=48.996515594886858 East=17.989637729707006 Altitude=550.00000000000000 }

d0 = 4654.6937995573062
d1 = 4648.3896597230259
t = 65.904213878080199
dt = 0.1
velocityPoi = {x=104.92401431817457 y=167.91352303897233 z=0.00000000000000000 }
m_sVelAV = {x=0.00000000000000000 y=0.00000000000000000 z=0.00000000000000000 }

ДРУГОЙ ТЕСТОВЫЙ ПРИМЕР:

    m_sPosAV = {North=49.008020930461598 East=17.920928503349856 Altitude=550.00000000000000 }
    m_position = {North=49.017421151053824 East=17.989399013104570 Altitude=550.00000000000000 }
    d0 = 144495.56021027692
    d1 = 144475.91709961568
    velocityPoi = {x=104.92401431817457 y=167.91352303897233 z=0.00000000000000000 }
    m_sVelAV = {x=0.89000000000000001 y=0.00000000000000000 z=0.

00000000000000000 }

    t = 733.05884538126884

ИСПЫТАТЕЛЬНЫЙ СЛУЧАЙ 3 ВРЕМЯ СОТЛЕНИЯ 0

m_sPosAV = {North=48.745020278145105 East=17.951529239281793 Altitude=4000.0000000000000 }
m_position = {North=48.734919749542570 East=17.943535418223373 Altitude=4000.0000000000000 }

v1 = {61.452929549676597, -58.567847120366054, 8.8118360639107198}
v0 = {0.00000000000000000, 0.00000000000000000, 0.00000000000000000}

pos0 = {0.85076109780503417, 0.31331329099350030, 4000.0000000000000}
pos1 = {0.85058481032472799, 0.31317377249621559, 3993.0000000000000}
d1 = 2262.4742373961790

ПОСЛЕДНИЙ ТЕСТОВЫЙ СЛУЧАЙ:

p0 = 0x001dc7c4 {3933272.5980855357, 4681348.9804422557, 1864104.1897091190}
p1 = 0x001dc7a4 {3927012.3039519843, 4673002.8791717924, 1856993.0651808924}
dt = 100;
n = 6;
v1 = 0x001dc764 {18.446446996578750, 214.19570794229870, -9.9777430316824578}
v0 = 0x001dc784 {0.00000000000000000, 0.00000000000000000, 0.00000000000000000}
const double _max_d = 2500; 
double _max_T = 120;

Последний тестовый случай:

m_sPosAV = {North=49.958099932390311 East=16.958899924978102 Altitude=9000.0000000000000 }
m_position = {North=49.956106045262935 East=16.928683918401916 Altitude=9000.0000000000000 }

p0 = 0x0038c434 {3931578.2438977188, 4678519.9203961492, 1851108.3449359399}
p1 = 0x0038c414 {3933132.4705292359, 4679955.4705412844, 1850478.2954359739}
vel0 = 0x0038c3b4 {0.00000000000000000, 0.00000000000000000, 0.00000000000000000}
vel1 = 0x0038c354 {-55.900000000000006, 185.69999999999999, -8.0000000000000000}
dt = 1;   // [sec] initial time step (accuracy = dt/10^(n-1)
n = 5;        // accuracy loops

ОКОНЧАТЕЛЬНЫЙ КОД:

const double _max_d = 2500; // max_distance m
    m_Time = 3600.0;
    int i, e, n;
    double t, dt;
    double x, y, z, d0, d1 = 0;
    double p0[3], p1[3], v0[3], v1[3];
    double vel0[3], pos0[3], pos1[3], vel1[3];

    vel0[0] = m_sVelAV.x;
    vel0[1] = m_sVelAV.y;
    vel0[2] = m_sVelAV.z;

    vel1[0] = velocityPoi.x;
    vel1[1] = velocityPoi.y;
    vel1[2] = velocityPoi.z;


    pos0[0] = (m_sPosAV.GetLatitude()*pi) / 180;
    pos0[1] = (m_sPosAV.GetLongitude()*pi) / 180;
    pos0[2] = m_sPosAV.GetAltitude();

    pos1[0] = (poi.Position().GetLatitude()*pi) / 180;
    pos1[1] = (poi.Position().GetLongitude()*pi) / 180;
    pos1[2] = poi.Position().GetAltitude();


    WGS84toXYZ_posvel(p0, v0, pos0, vel0);
    WGS84toXYZ_posvel(p1, v1, pos1, vel1);
    dt = 1;   // [sec] initial time step (accuracy = dt/10^(n-1)
    n = 5;        // accuracy loops
    for (t = 0.0, i = 0; i<n; i++)
        for (e = 1; t <= m_Time; t += dt)
        {
            d0 = d1;
            // d1 = relative distance in time t
            x = p0[0] - p1[0] + (v0[0] - v1[0])*t;
            y = p0[1] - p1[1] + (v0[1] - v1[1])*t;
            z = p0[2] - p1[2] + (v0[2] - v1[2])*t;
            d1 = sqrt((x*x) + (y*y) + (z*z));
            if (e) { e = 0; continue; }
            // if bigger then last step stop (and search with 10x smaller time step)
            if (d0<d1) { d1 = d0; t -= dt + dt; dt *= 0.1; if (t<0.0) t = 0.0; break; }
        }
    // handle big distance as no collision
    if (d1 > _max_d) return false;
    if (t >= m_Time) return false;

    qDebug() << "Collision at time t= " << t;

person andre    schedule 12.12.2016    source источник
comment
Уточните пожалуйста свой вопрос. Что вы имеете в виду под столкновением векторов? Вы имеете в виду, что вам даны начальные точки в дополнение к векторам скорости, и вы хотите знать, будут ли объекты с этими начальными точками и постоянными векторами скорости сталкиваться в будущем? Что вы имеете в виду под ограничивающей сферой: в обычном методе решения проблемы, которую я описываю, такая вещь не используется. И да, время также можно рассчитать, но сначала подтвердите, действительно ли это ваша проблема. Вы также можете спросить, пересекаются ли пути объекта без столкновения самих объектов.   -  person Rory Daulton    schedule 12.12.2016
comment
Я даю вектор положения для двух объектов, и у меня есть их векторы скорости. Я хотел бы знать, будут ли сталкиваться объекты с этими начальными точками и векторами постоянной скорости   -  person andre    schedule 12.12.2016
comment
Это во многом зависит от формы объектов.   -  person Nico Schertler    schedule 12.12.2016
comment
@NicoSchertler Нет формы объектов, объекты представляют собой только две точки с двумя векторами скорости   -  person andre    schedule 12.12.2016
comment
Тогда маловероятно, что они когда-либо столкнутся. Просто решите start1 + t v1 = start2 + t v2.   -  person Nico Schertler    schedule 12.12.2016
comment
@NicoSchertler Что делать, если у меня есть две точки, которые движутся с использованием вектора скорости, и я хочу проверить наличие столкновений?   -  person andre    schedule 13.12.2016
comment
@andre, вы получили ответ в последнем комментарии Нико Шертлера. решить линейное уравнение (выбрать одну нетривиальную ось) решитьt, если решение найдено, то линии пересекаются. Проблема в том, что вам потребуется перпендикулярное расстояние между бесконечными линиями ... это ближайшая точка на двух путях, если они происходят примерно в одно и то же время, только тогда объекты действительно сталкиваются ... поэтому вам нужно найти t1,t2 таких |start1 + t1.v1 - start2 - t2.v2|<=min_distance И |t1-t2|<min_time, которые это основы математики ...   -  person Spektre    schedule 13.12.2016
comment
@andre v1,v2 - это ваши 3D-векторы скорости, start1,start2 - это фактические 3D-положения, а t1,t2 - это параметры скалярного времени для поиска. min_distance и min_time - это скалярные константы порогового значения поиска, которые влияют на размер области, рассматриваемой для столкновения.   -  person Spektre    schedule 13.12.2016
comment
@Spektre Я очень давно ждал вашего ответа. Я знаю, что вы знаете об этих проблемах :)   -  person andre    schedule 13.12.2016
comment
@Spektre Не могли бы вы опубликовать это в качестве ответа и, пожалуйста, показать какой-нибудь псевдокод?   -  person andre    schedule 13.12.2016
comment
@andre ваши векторы скорости подозрительны, также должен быть z компонент, если они декартовы (вероятность того, что вы движетесь параллельно экватору, неясна), поэтому более вероятно, что он все еще находится в сферических координатах, в которых единицы еще более подозрительны, ни [deg/s] ни [rad/s]. В случае Cartessian скорость obj1 составляет ~ 191 км / ч, это нормально, но для сферического случая может быть какая-то безумная доля угла в час, которую трудно сказать, вам следует проверить документ, откуда вы их взяли ...   -  person Spektre    schedule 14.12.2016
comment
@andre полностью отредактировал ваш вопрос. пожалуйста, не удаляйте соответствующие данные, ... вы можете заменить / исправить недействительный и добавить новый, но если вы удалите основу своего вопроса, как вы можете ожидать, что кто-то другой ответит или даже воспользуется вашим вопросом?   -  person Spektre    schedule 16.12.2016
comment
@Spektre Коллизия теперь работает нормально. Я обнаружил, что координаты и скорости указаны в километрах / ч. Теперь есть проблема, время t увеличивается, пока не достигнет min_time. Я хочу, чтобы он уменьшался, пока не достигнет максимального времени. поэтому я предполагаю, что столкновение произойдет через 10 секунд   -  person andre    schedule 16.12.2016
comment
@andre, который не имеет никакого смысла, t не увеличивается и не уменьшается, это время столкновения. Если вы анимируете, то да, оно уменьшается, если вы снова что-то не напортачите. Надеюсь, вы преобразовали km/h в m/s ...   -  person Spektre    schedule 16.12.2016
comment
@andre (неправильное преобразование должно делиться на 3,6 вместо умножения :)) t=261sec добавили edit3 с обновленным кодом, включая преобразование скорости ...   -  person Spektre    schedule 16.12.2016
comment
@Spektre Хотел бы я проголосовать за ваши комментарии :). Я обнаружил, что двойной vel1 [3] = {- 44,7, -188,0, 0,0}; // [км / ч] долгота, широта, высота сейчас в м / с, км / ч   -  person andre    schedule 16.12.2016
comment
@andre Я использую SI, поэтому все находится в [m],[m/s], поэтому входные значения умножаются на kmh=1.0/3.6 см. мой ответ .... во входных данных четко указано, что это км / ч, а не м / с   -  person Spektre    schedule 16.12.2016
comment
Я имел в виду vel1, это в м / с не в км / ч, а для объекта 2 - в км / ч   -  person andre    schedule 16.12.2016
comment
@andre, это настоящий беспорядок ... может быть, было бы разумно написать все с нуля, если оно содержит такие несоответствия, или вы можете потратить вечность на отладку ...   -  person Spektre    schedule 17.12.2016


Ответы (2)


[Edit5] Завершите повторное редактирование, если вам нужны старые источники, посмотрите историю изменений

Как отметил Нико Шертлер, проверка пересечения линии с линией - безумие, поскольку вероятность пересечения двух траекторий в одном и том же положении и времени почти равна нулю (даже с учетом перекрытий точности округления). Вместо этого вы должны найти место на каждой траектории, которое достаточно близко (чтобы столкнуться), и оба объекта находятся там относительно в одно и то же время. Другая проблема в том, что ваши траектории вообще не линейны. Да, они могут казаться линейными в течение короткого времени в кабине WGS84 и декартовыми, но с увеличением времени траектория изгибается вокруг Земли. Кроме того, ваши единицы входных значений для скорости делают это немного сложнее, поэтому позвольте мне резюмировать нормализованные значения, с которыми я буду иметь дело с этого момента:

  1. Ввод

    состоит из двух предметов. Для каждого из них известно его фактическое положение (в WGS84 [rad]) и фактическая скорость [m/s], но не в декартовом пространстве, а в локальных осях WGS84. Например что-то вроде этого:

    const double kmh=1.0/3.6;
    const double deg=M_PI/180.0;
    const double rad=180.0/M_PI;
    //                      lon            lat      alt
    double pos0[3]={  23.000000*deg, 48.000000*deg,2500.000000 };
    double pos1[3]={  23.000000*deg, 35.000000*deg,2500.000000 };
    double vel0[3]={ 100.000000*kmh,-20.000000*kmh,   0.000000*kmh };
    double vel1[3]={ 100.000000*kmh, 20.000000*kmh,   0.000000*kmh };
    

    Осторожно, координаты мин указаны в Long,Lat,Alt порядке / условных обозначениях !!!

  2. вывод

    Вам необходимо вычислить время, в течение которого два объекта "сталкиваются". Дополнительные ограничения к решению могут быть добавлены позже. Как упоминалось ранее, мы ищем не пересечение, а «ближайший» подход, который удовлетворяет условиям столкновения (например, расстояние меньше некоторого порога).

После некоторого обучения и тестирования я решил использовать итеративный подход в пространстве WGS84. Это вызывает некоторые проблемы, например, как преобразовать скорость из [m/s] в пространстве WGS84 в [rad/s] в пространстве WGS84. Это соотношение меняется с высотой и широтой объекта. На самом деле нам нужно вычислить изменение угла по осям long и lat, которые "точно" равны 1m пройденному расстоянию, а затем умножить на него скорости. Это можно аппроксимировать уравнением длины дуги:

l = dang.R

Где R - фактический радиус углового перемещения, ang - изменение угла, а l - пройденное расстояние, поэтому, когда l=1.0 тогда:

dang = 1.0/R

Если у нас есть декартово положение x,y,z (z - ось вращения Земли), то:

Rlon = sqrt (x*x + y*y)
Rlat = sqrt (x*x + y*y + z*z)

Теперь мы можем перебирать позиции с течением времени, что может быть использовано для приблизительного определения времени ближайшего сближения. Однако нам нужно ограничить максимальный временной шаг, чтобы не упустить большую часть кривизны Земли. Этот предел зависит от используемой скорости и точности цели. Итак, вот алгоритм поиска подхода:

  1. инициализация

    установите начальный временной шаг на верхний предел, например dt=1000.0, и вычислите фактическое положение объектов кабины в декартовом пространстве. На основании этого вычислите их расстояние d1.

  2. итерация

    установите d0=d1, затем вычислите фактические скорости в WGS84 для фактических позиций и добавьте speed*dt к каждому фактическому WGS84 положению объекта. Теперь просто вычислите фактические положения в декартовом пространстве и вычислите расстояние до них d1

    если d0>d1, значит, мы приближаемся к ближайшему подходу, поэтому снова перейдите к # 2.
    В случае d0==d1 траектории параллельны, поэтому верните время подхода t=0.0
    В случае d0<d1 мы уже пересекли ближайший подход, поэтому установите dt = -0.1*dt, а если dt>=desired_accuracy перейти к # 2, в противном случае остановитесь.

  3. восстановить лучший t

    После итерации в # 2 мы должны восстановить лучшее время назад, поэтому верните t+10.0*dt;

Теперь у нас есть время наибольшего сближения t. Остерегайтесь: он может быть отрицательным (если предметы удаляются друг от друга). Теперь вы можете добавить свои ограничения, например

if (d0<_max_d)
 if ((t>=0.0)&&(t<=_max_T))
  return collision ...

Вот источник C ++ для этого:

//---------------------------------------------------------------------------
#include <math.h>
//---------------------------------------------------------------------------
const double kmh=1.0/3.6;
const double deg=M_PI/180.0;
const double rad=180.0/M_PI;
const double  _earth_a=6378137.00000;   // [m] WGS84 equator radius
const double  _earth_b=6356752.31414;   // [m] WGS84 epolar radius
const double  _earth_e=8.1819190842622e-2; //  WGS84 eccentricity
const double  _earth_ee=_earth_e*_earth_e;
//--------------------------------------------------------------------------
const double _max_d=2500.0;         // [m] collision gap
const double _max_T=3600000.0;      // [s] max collision time
const double _max_dt=1000.0;        // [s] max iteration time step (for preserving accuracy)
//--------------------------------------------------------------------------
//                      lon            lat      alt
double pos0[3]={  23.000000*deg, 48.000000*deg,2500.000000 }; // [rad,rad,m]
double pos1[3]={  23.000000*deg, 35.000000*deg,2500.000000 }; // [rad,rad,m]
double vel0[3]={ 100.000000*kmh,-20.000000*kmh,   0.000000*kmh }; // [m/s,m/s,m/s]
double vel1[3]={ 100.000000*kmh,+20.000000*kmh,   0.000000*kmh }; // [m/s,m/s,m/s]
//---------------------------------------------------------------------------
double divide(double x,double y)
        {
        if ((y>=-1e-30)&&(y<=+1e-30)) return 0.0;
        return x/y;
        }
void  vector_copy(double *c,double *a)         { for(int i=0;i<3;i++) c[i]=a[i];       }
double vector_len(double *a) { return sqrt((a[0]*a[0])+(a[1]*a[1])+(a[2]*a[2])); }
void  vector_len(double *c,double *a,double l)
        {
        l=divide(l,sqrt((a[0]*a[0])+(a[1]*a[1])+(a[2]*a[2])));
        c[0]=a[0]*l;
        c[1]=a[1]*l;
        c[2]=a[2]*l;
        }
void  vector_sub(double *c,double *a,double *b) { for(int i=0;i<3;i++) c[i]=a[i]-b[i]; }
//---------------------------------------------------------------------------
void WGS84toXYZ(double *xyz,double *abh)
    {
    double  a,b,h,l,c,s;
    a=abh[0];
    b=abh[1];
    h=abh[2];
    c=cos(b);
    s=sin(b);
    // WGS84 from eccentricity
    l=_earth_a/sqrt(1.0-(_earth_ee*s*s));
    xyz[0]=(l+h)*c*cos(a);
    xyz[1]=(l+h)*c*sin(a);
    xyz[2]=(((1.0-_earth_ee)*l)+h)*s;
    }
//---------------------------------------------------------------------------
void WGS84_m2rad(double &da,double &db,double *abh)
    {
    // WGS84 from eccentricity
    double p[3],rr;
    WGS84toXYZ(p,abh);
    rr=(p[0]*p[0])+(p[1]*p[1]);
    da=divide(1.0,sqrt(rr));
    rr+=p[2]*p[2];
    db=divide(1.0,sqrt(rr));
    }
//---------------------------------------------------------------------------
double collision(double *pos0,double *vel0,double *pos1,double *vel1)
    {
    int e,i,n;
    double p0[3],p1[3],q0[3],q1[3],da,db,dt,t,d0,d1,x,y,z;
    vector_copy(p0,pos0);
    vector_copy(p1,pos1);
    // find closest d1[m] approach in time t[sec]
    dt=_max_dt; // [sec] initial time step (accuracy = dt/10^(n-1)
    n=6;        // acuracy loops
    for (t=0.0,i=0;i<n;i++)
     for (e=0;;e=1)
        {
        d0=d1;
        // compute xyz distance
        WGS84toXYZ(q0,p0);
        WGS84toXYZ(q1,p1);
        vector_sub(q0,q0,q1);
        d1=vector_len(q0);
        // nearest approach crossed?
        if (e)
            {
            if (d0<d1){ dt*=-0.1; break; }                  // crossing trajectories
            if (fabs(d0-d1)<=1e-10) { i=n; t=0.0; break; }  // parallel trajectories
            }
        // apply time step
        t+=dt;
        WGS84_m2rad(da,db,p0);
        p0[0]+=vel0[0]*dt*da;
        p0[1]+=vel0[1]*dt*db;
        p0[2]+=vel0[2]*dt;
        WGS84_m2rad(da,db,p1);
        p1[0]+=vel1[0]*dt*da;
        p1[1]+=vel1[1]*dt*db;
        p1[2]+=vel1[2]*dt;
        }
    t+=10.0*dt; // recover original t
//  if ((d0<_max_d)&&(t>=0.0)&&(t<=_max_T)) return collision; else return no_collision;
    return t;
    }
//---------------------------------------------------------------------------

Вот обзор примера:

обзор

Красный - это объект0, а зеленый - это объект1. Белые квадраты представляют положение при вычисленном столкновении в момент времени t_coll [s] с расстоянием d_coll [m]. Желтые квадраты - это позиции в определенное пользователем время t_anim [s] с расстоянием d_anim [m], которое контролируется пользователем в целях отладки. Как видите, этот подход работает и в течение 36 часов ...

Надеюсь, я не забыл скопировать что-то (если да, прокомментируйте меня, и я добавлю)

person Spektre    schedule 13.12.2016
comment
Комментарии не подлежат расширенному обсуждению; этот разговор был перешел в чат. - person Bhargav Rao; 14.12.2016
comment
что такое dalt, dlat, dlon, это вектор скорости высоты, долготы, широты? или скорость в alt, lon, lat - person andre; 15.12.2016
comment
@andre скорость грубой в ([rad/s],[rad/s],[m/s]) или ([deg/s],[deg/s],[m/s]), что должно быть очевидно, поскольку это физика начальной школы .... pos1 = pos0 + vel*time и vel=(pos1-pos0)/time Грубо, если вы хотите более точное преобразование, вам нужно использовать WGS84 вместо сферы .... - person Spektre; 15.12.2016
comment
У меня вообще нет скорости dalt, dlat, lon, у меня есть вектор скорости в этих координатах. - person andre; 15.12.2016
comment
метр в секунду - person andre; 15.12.2016
comment
@andre, если он находится в [m/s], то это в сферической системе координат? если да, то вам нужно преобразовать его по-другому - person Spektre; 15.12.2016
comment
да его в формате WGS84, как бы я его конвертировал. Не могли бы вы проверить обновленный код - person andre; 15.12.2016
comment
@andre узнает, что ваша трансформация lat,lon,alt, а не lon,lat,alt, так что ваши очки lon,lat,alt или нет? если да, то вы вводите данные в преобразование в неправильном порядке ... Если нет, то ваше исходное описание данных было неправильным, следовательно, разные результаты .... - person Spektre; 15.12.2016
comment
@Spektre m_sPosAV = {North = 89.999999958090484 East = 80.477831559478233 Altitude = 7306.0200000000004} Ваша функция возвращает неверный результат, я использовал apsalin.com/convert-geodetic-to-cartesian.aspx Чтобы проверить результат, его неверный - person andre; 15.12.2016
comment
@andre argh искал неправильную переменную ... Если я введу координаты в правильном порядке, мое преобразование вернет 0.000770081333182288, 0.00459091200205796, 6364061.02, что довольно близко (разница менее 3 м) к той ссылке, которую вы указали. Разница могла быть из-за точности double ... но трудно сказать, какая из них лучше. Проблема в том, что _earth_a*_earth_a действительно огромное число и float не в состоянии точно его вместить. Даже double расширяет свои пределы, поскольку ему требуется 16 цифр информации, что действительно близко к двойному пределу, и мы выполняем вычисления поверх этого - person Spektre; 15.12.2016
comment
@Spektre Привет. Коллизия теперь работает нормально. Проблема в том, что я хочу сделать из объекта сферу и проверить наличие столкновений. Я знаю, что столкновение двух сфер происходит с помощью проверки общего радиуса. Но как мне определить сферу по декартовым координатам, которые преобразованы из сферических? - person andre; 21.12.2016
comment
Я также хочу после столкновения ограничивающей сферы получить время столкновения, поэтому я бы использовал тот же код выше, правильно? - person andre; 21.12.2016
comment
@Spektre Привет, я обнаружил, что объекты нелинейны, как бы решить эту проблему? - person andre; 28.12.2016
comment
@andre hi какое-то время был в русле ... для этого вам нужно указать дополнительную информацию ... какая нелинейность (уравнение, константы ...) в противном случае ваш вопрос не имеет ответа .... решение такое же, как и у вас может либо выполнять итерацию с небольшим шагом по времени, либо решать систему уравнений для относительного расстояния, чтобы оно было меньше некоторого порогового расстояния столкновения ... - person Spektre; 28.12.2016
comment
Что я должен прочитать об этих вещах? какие-нибудь книжные рекомендации? Нелинейность заключается в том, что корабль имеет разную высоту и разную скорость с течением времени, поэтому иногда он движется по кривой, а иногда по линейной линии. - person andre; 28.12.2016
comment
@andre Я понятия не имею на английском языке, но любой школьный учебник по физике и / или динамике, охватывающий уравнения движения, должен подойти ... особенно Д'Ламберта и ньютоновского движения для нерелятивистских скоростей. Вы должны написать уравнение для каждого объекта как функцию времени и решить их систему (для каждого объекта), которая минимизирует расстояние за относительно одно и то же время .... (численно, алгебраически или итеративно) - person Spektre; 29.12.2016
comment
@Spektre Привет. Сегодня я протестировал столкновение, и он отлично работает только для вертикальной скорости. но когда и полет, и корабль находятся в корпусе, показанном на рисунке, время столкновения настолько велико, что составляет 700 секунд. Как я могу это решить? - person andre; 29.12.2016
comment
@andre Я не вижу ни соответствующей цифры в вашем вопросе, ни каких-либо подробностей о передвижениях. Ваше изображение - это просто зелень с каким-то маркером, который без дополнительной информации не добавляет информации ... - person Spektre; 29.12.2016
comment
Синяя стрелка - это полет, а другая стрелка - это корабль. Вы видите, что самолет столкнется с кораблями, но скорость полета вертикальна по оси y. Я измерил время и его 700 секунд. но когда полет идет снизу вверх и сталкивается с кораблем, это работает идеально. Серая стрелка - это корабль, который собирается столкнуться с синей стрелкой - это полет. Когда корабль падает, и рейс тоже, время настолько велико, что 700 секунд. Отлично работает другой способ, когда полет движется вверх, а корабль движется вниз. - person andre; 29.12.2016
comment
@andre, не зная координат и скорости, сложно сказать .... держу пари, вы где-то напортачили, и случаи, которые работают, просто совпадение ... - person Spektre; 29.12.2016
comment
можно ли предсказать время столкновения в минутах? это возможно ? что я должен изменить, чтобы он заработал за считанные минуты? влияет ли высота на столкновение, так что корабль и полет должны иметь одинаковую высоту? - person andre; 29.12.2016
comment
@andre легко преобразовать время из секунд в минуты, разделив на 60 .... например: min=floor(t/60.0); sec=t-60.0*min; - person Spektre; 29.12.2016
comment
@andre (пропустил раньше) да, высота влияет на столкновение, потому что она включена в декартово расстояние. Оды Altittudes не обязательно должны быть одинаковыми, но близкими (во время столкновения). - person Spektre; 30.12.2016
comment
d1 не инициализирован - person andre; 30.12.2016
comment
@andre он в цикле ... поэтому e переключает первый проход без сравнения, поскольку d0 еще не в порядке - person Spektre; 30.12.2016
comment
@andre начальная установка dt - это временной шаг, который я назвал _max_t _max_T - это временной интервал, в котором этот поиск наиболее близкого подхода ... поэтому, если вы хотите другой временной шаг точности, измените dt=100.0 на то, что когда-либо, просто помните, что точность для dt=100.0,n=6 это 0.001 [sec], чего, я думаю, достаточно. Кроме того, чем ниже dt и выше _max_T, тем больше итераций потребуется для вычисления ... - person Spektre; 30.12.2016
comment
Да, я знаю это. Но я хочу иметь минимальное время для столкновения. как минимальное время, когда столкновение происходит в 10 или 20 секунд - person andre; 30.12.2016
comment
@ что именно он делает? если вы хотите игнорировать столкновения после этого времени, то это _max_T, если вы хотите игнорировать столкновения до этого времени, вместо этого измените t=0.0 на t=_min_t и if (t<0.0) t=0.0; на if (t<_min_t) t=_min_t; ... если вы хотите другое поведение, вам нужно сначала описать его - person Spektre; 30.12.2016
comment
Я должен предсказать столкновение, например, если оно произойдет через 10 секунд с этого момента и далее. - person andre; 30.12.2016
comment
@andre, тогда _max_T - это константа, которую вы хотите установить ... также измените dt на ее долю ... поэтому, если _max_T=10;, используйте, например, dt=1.0; n=5; - person Spektre; 30.12.2016
comment
@andre t=0 означает, что либо ближайший подход находится в t=0, либо объекты удаляются друг от друга, поэтому ближайший подход находится в t<0, который не ищется ... какой из них определяется из состояния d1 .... если вы хотите установить dt с помощью некоторого уравнения, затем сделайте это (это указано в коде), например, dt=precision*10^(n-1), но должно быть меньше, чем _max_T, чтобы вы могли добавить if, чтобы зафиксировать его ... или использовать что-то вроде dt=_max_T*0.001 и вычислить n с точностью или что угодно .... вы также можете игнорировать n и остановить основной цикл, когда dt<accuracy вместо этого - person Spektre; 30.12.2016
comment
так это не ошибка? Столкновение работает отлично, большое спасибо и с Новым годом. - person andre; 30.12.2016
comment
@andre нет, это не ошибка ... итерация более точна, как я уже упоминал ранее ... но она медленнее вычисляется ... в течение огромного времени вы можете вместо этого обновить сферическое положение, а затем преобразовать его в декартово внутри петля для учета кривизны Земли - person Spektre; 30.12.2016
comment
не могли бы вы подробнее объяснить итеративный подход, мне нужно больше узнать об этом, вместо того, чтобы копировать и вставлять код, если вы тоже можете опубликовать рисунок. Большое спасибо ! - person andre; 30.12.2016
comment
@andre какая фигура? Он просто вычисляет расстояние в разы 0,1dt, 2dt, 3dt ... и запоминает наименьшее, после чего делает это снова из ближайшего времени с меньшим шагом, чтобы повысить точность, вот и все, аналогично этому Как работает приближенный поиск, но он проще и менее сложен (чтобы его было легче понять) - person Spektre; 31.12.2016
comment
Я добавил тестовый пример, который вообще не работает. Большое спасибо spketre и с новым годом - person andre; 03.01.2017
comment
@andre последний случай работает для меня ... ближайший подход на 39.371s расстоянии 1089.631m выглядит так, будто вы облажались, преобразование в декартово мое: p0={ 3938182.67192947, 1200934.91108298, 4866682.19592028 } и p1 = { 3938978.11607673, 1198907.37719864, 4866539.31204547 }, скорее всего, вы перепутали порядок операндов и / или забыли преобразовать [deg] в [rad] и или все еще использую старое нелинейное преобразование. Так что сначала ОТЛАДИТЕ !!! - person Spektre; 03.01.2017
comment
Спасибо за ваш комментарий. Я добавил полный код. вроде правильно я ничего не перепутал - person andre; 03.01.2017
comment
@andre, если вы используете мой WGS84toXYZ_posvel, тогда да, вы это сделали, поскольку мой порядок операндов lon,lat,alt вместо вашего lat,lon,alt, о котором я предупреждал вас уже несколько раз ... - person Spektre; 03.01.2017
comment
@Spektre Я заметил проблему. У некоторых объектов d0 ‹= d1. но разница очень мала, с точностью до 0,1 или 0,01. Два объекта находятся близко друг к другу, но столкновения нет из-за d0 ‹d = 1. Вам нужен тестовый пример? пожалуйста, дайте мне знать, если вам нужна дополнительная информация - person andre; 16.01.2017
comment
@Spektre Большое спасибо. Обратите внимание, что мне не нужны сферические координаты в декартовы, теперь я получаю координаты скорости и положения в декартовых координатах. - person andre; 17.01.2017
comment
@andre Вы должны удалить все устаревшие комментарии, это нечитаемый беспорядок ... (нажмите кнопку x после edit) - person Spektre; 17.01.2017

Вы не показываете никакого кода, поэтому я просто изложу основные идеи, а код оставлю вам. Вернитесь, если вы попробуете какой-то код и застрянете, но покажите свои усилия и свой код до сих пор.

Есть несколько способов решить вашу проблему. Один из способов - задать параметрические уравнения для каждого объекта, задав ваши две функции во времени t. Установите одинаковые результаты этих функций и решите на время. Для трехмерных координат это дает вам три вопроса, по одному для каждой координаты, и очень маловероятно, что значения t будут одинаковыми для всех трех уравнений. Если они совпадают, это время вашего столкновения.

Другой способ, который допускает некоторые ошибки округления с плавающей запятой, - это изменить систему отсчета на систему координат одного из объектов. Вы вычитаете два вектора скорости, скажем v2-v1, и теперь у вас есть скорость второго объекта относительно первого объекта. Теперь найдите расстояние от теперь уже неподвижного первого объекта до линии движущегося второго объекта. Если вы не знаете, как это сделать, поищите «расстояние от точки до линии» в своей любимой поисковой системе. Затем вы видите, достаточно ли это расстояние, чтобы рассматривать его как столкновение - вы вряд ли получите идеальное столкновение, нулевое расстояние, учитывая ошибки округления с плавающей запятой. Если он достаточно мал, вы увидите, произойдет ли это столкновение в будущем или было достигнуто в прошлом. Вы можете найти проекцию точки на линии в качестве промежуточного значения для этого последнего вычисления.

Это ясно?

person Rory Daulton    schedule 12.12.2016
comment
Я так далеко выложил код, не могли бы вы его проверить? - person andre; 12.12.2016
comment
@andre: Моя Java (или то, что вы использовали) не очень хороша, и вы не определяете свои методы Position(), GetLongitude() или qDebug(), поэтому я не могу сказать много. - person Rory Daulton; 12.12.2016