crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Помогите, пожалуйста, с алгоритмом попадания в точку, определение значка аэропорта.
AD
  опции профиля:
сообщение 19.12.2008, 12:22
Сообщение #1


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


На карте есть значок определения аэропорта. При нажатии правой клавиши мыши появляется меню, приведенное на картинке. Так в этом меню есть подменю "Object", которое должно быть видимым если мы попали в значок аэропорта. Это получается только при больших масштабах или же еще в каком-то таком странном случае. Помогите пожалуйста, вот код определения экранного расстояния, при котором я считаю, что необходимо показывать подменю. У кого есть какие идеи?
/// Проверка на то, есть в данной точке объект
bool QTrackWidget::isObject(const QPoint& cur_pos)
{
    for(QVector<APTINFO*>::iterator iter=apt_vec.begin(); iter!=apt_vec.end(); ++iter)
    {
        GPOINT apt_geo_coord((*iter) -> apt_coord); // выбор гео-точки аэропорта
        SPOINT apt_scr_coord(pSahara -> GeoToScr(apt_geo_coord)),  current_pos(cur_pos.x(), cur_pos.y()); // перевод в экранные координаты гео-точки аэропорта и точки мыши на карте
        double dx = apt_scr_coord.x - current_pos.x, dy = apt_scr_coord.y - current_pos.y;
        int dst = floor(sqrt(pow(dx, 2.0) + pow(dy, 2.0)));  // рассчет расстояния по теореме Пифагора
        if(dst <= 10)
        {
            apt = (*iter);
            return true;
        }
    }
    return false;
}


Вот рисунок:
[attachment=341:apt_defining.JPG]
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 19.12.2008, 13:22
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Вот алгоритм проверки расстояния в географических координатах (наоборот, работает при очень малых масштабах)
/// Проверка на то, есть в данной точке объект
bool QTrackWidget::isObject(const QPoint& cur_pos)
{
    CurrentCoords coords;
    coords.setOffset(offset);
    for(QVector<APTINFO*>::iterator iter=apt_vec.begin(); iter!=apt_vec.end(); ++iter)
    {
        GPOINT apt_geo_coord((*iter) -> apt_coord);
        GPOINT current_pos(coords.toGPointCur(cur_pos)); // перевод из QPoint в географическую координату (сотые доли секунды)
        double lat1 = q_calc.UseUnToRad(apt_geo_coord.lat, QCalculation::M_CRDGP),
               lon1 = q_calc.UseUnToRad(apt_geo_coord.lon, QCalculation::M_CRDGP),
               lat2 = q_calc.UseUnToRad(current_pos.lat, QCalculation::M_CRDGP),
               lon2 = q_calc.UseUnToRad(current_pos.lon, QCalculation::M_CRDGP); // перевод в радианы
        double dst = q_calc.Rng(lat1, lon1, lat2, lon2) * R / 1000.;   // вычисление расстояния между двумя точками на сфере (Земля принимается за сферу)
        if(dst <= 5.)/// если расстояние меньше 5км, то делаем что-то
        {
            apt = (*iter);
            return true;
        }
    }
    return false;
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 19.12.2008, 15:08
Сообщение #3


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Для точечных объектов (или объектов видимых на данном масштабе как точечные, нужно проверять не совпадение координат объекта и указателя, а попадение объекта в курсорную область.
Курсорная область - обычно квадрат вокруг указателя, размером в 2-4 пиксела (лучше дать возможность настроить).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 19.12.2008, 15:28
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Цитата(Tonal @ 19.12.2008, 15:08) *
Для точечных объектов (или объектов видимых на данном масштабе как точечные, нужно проверять не совпадение координат объекта и указателя, а попадение объекта в курсорную область.
Курсорная область - обычно квадрат вокруг указателя, размером в 2-4 пиксела (лучше дать возможность настроить).

А разве первый метод подобную вещь не делает? Если нет. То как это сделать? Помоги пожалуйста!
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AD
  опции профиля:
сообщение 19.12.2008, 17:28
Сообщение #5


Профессионал
*****

Группа: Участник
Сообщений: 2003
Регистрация: 4.2.2008
Из: S-Petersburg
Пользователь №: 84

Спасибо сказали: 70 раз(а)




Репутация:   17  


Tonal натолкнул на хорошую мысль. Реализовал так: :)
/// Проверка на то, есть в данной точке объект
bool QTrackWidget::isObject(QPoint cur_pos)
{
    cur_pos.setY(cur_pos.y() + dy);
    for(QVector<APTINFO*>::iterator iter=apt_vec.begin(); iter!=apt_vec.end(); ++iter)
    {
        GPOINT apt_geo_coord((*iter) -> apt_coord);
        SPOINT apt_scr_coord(pSahara -> GeoToScr(apt_geo_coord));
        QPoint apt_point(apt_scr_coord.x, apt_scr_coord.y);
        QRect cursory_region(apt_point.x() - 8, apt_point.y() - 8, 16, 16); // регион, в который должен попасть курсор
        if(cursory_region.contains(cur_pos))
        {
            apt = (*iter);
            return true;
        }
    }
    return false;
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Tonal
  опции профиля:
сообщение 19.12.2008, 18:48
Сообщение #6


Активный участник
***

Группа: Участник
Сообщений: 452
Регистрация: 6.12.2007
Из: Новосибирск
Пользователь №: 34

Спасибо сказали: 69 раз(а)




Репутация:   17  


Да, примерно так. Ну и константу 8 лучше таки меть настраивать - оптимальное значение зависит от разрешения монитора и дрожжания рук пользователя. :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Ответить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 13.11.2018, 6:28