Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Access&ADO: определение нахождения точки, внутри многоугольника, средствами SQL 
:(
    Опции темы
KateL
Дата 7.10.2010, 13:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 9.8.2007
Где: Новосибирск

Репутация: нет
Всего: нет



Программа реализована на C++ Builder + MS Access + ADO.

Имеется таблица, два поля которой - коодинаты X, Y.
Надо получить набор данных в ADOQuery, в которых точка (X,Y) попадает в многоугольник, заданный точками (P[0].x, P[0].y)...(P[n].x, P[n].y).

В обычном случае, алгоритм попадания точки в многоугольник выглядит так:

Код

// Вычисляет попадание точки в полигон. Возвращает true, если точка внутри
bool clMap::point_in_poly(point_k *P, int Num_pt, point_k a)
{
int x,y, Count = 0;
  for(int i=0;i<Num_pt;i++)
  {
    if(P[i].y == P[i+1].y) continue; // оператор continue прерывает текущую итерацию цикла
    if(P[i].y > a.y && P[i+1].y > a.y) continue;
    if(P[i].y < a.y && P[i+1].y < a.y) continue;
    if( P[i].y > P[i+1].y) {y=P[i].y; x=P[i].x;} else {y=P[i+1].y; x=P[i+1].x;} 
    if( y==a.y && x >= a.x) Count++;                                            
    else
      if( min(P[i].y,P[i+1].y)==a.y) continue;
    else
    {
       double t = (double)(a.y - P[i].y)/(P[i+1].y - P[i].y);
       if(t>0 && t<1 && P[i].x + t*(P[i+1].x-P[i].x) >= a.x) Count++;
    }
  }
  return Count & 1;
}


Я не могу придумать, как мне эту функцию засунуть в запрос. Может надо использовать хранимые процедуры? Но я с ними не работала.
Это вообще возможно реализовать?
Помогите, пожалуйста.
 
PM   Вверх
Frees
Дата 7.10.2010, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2233
Регистрация: 2.12.2005
Где: Екатеринбург

Репутация: 2
Всего: 54



Код

SELECT P.*
FROM POINTS_TABLE P
WHERE
(P.X >=:LEFT) AND (P.X < :RIGHT) AND (P.Y >= :TOP)  AND (P.Y < :BUTTOM);



Добавлено через 3 минуты и 2 секунды
чет я седне не внимательный... многоугольник с прямоугольником перепутал..


--------------------
Кольцов Виктор Владимирович
PM MAIL ICQ   Вверх
Akina
Дата 7.10.2010, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 453



Цитата(KateL @  7.10.2010,  14:35 Найти цитируемый пост)
В обычном случае, алгоритм попадания точки в многоугольник выглядит так

А вербально описать можете?


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Zloxa
Дата 7.10.2010, 15:12 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3470
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Akina, пускает луч из точки, считает пересечение с отрезками полигона, если нечетное, значит внутри.

задачка простенькая, вспомить бы школьную математику. йеххх.

Это сообщение отредактировал(а) Zloxa - 7.10.2010, 15:13


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Zloxa
Дата 7.10.2010, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3470
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



В общем както так, если не накосячил в формулах координат пересечения отрезков
Код

SQL> with poly as ( select 2 x1,4 y1,5 x2,3 y2 from dual
  2       union all select 5,3,7,5 from dual
  3       union all select 7,5,4,7 from dual
  4       union all select 4,7,2,4 from dual
  5  )
  6     ,point as (select 3 x,2 y from dual
  7      union all select 4 x,5 y from dual
  8      union all select 4 x,7 y from dual
  9      union all select 6 x,7 y from dual
 10      )
 11  select x,y
 12  from (
 13    select
 14     s.*
 15     ,y*xp/x yp
 16    from (
 17      select poly.*
 18             ,point.*
 19             ,((x1*y2-x2*y1)*x)/((y2-y1)*x-y*(x2-x1)) xp
 20      from poly,point
 21     )s
 22  )
 23  where xp<=greatest(0,x) and xp>=least(0,x)
 24        and xp<=greatest(x1,x2) and xp >= least(x1,x2)
 25        and yp<=greatest(0,y) and yp>=least(0,y)
 26        and yp<=greatest(y1,y2) and yp >= least(y1,y2)
 27  group by x,y
 28  having mod(count(*),2) = 1
 29  ;
 
         X          Y
---------- ----------
         4          5
         4          7


здесь poly - иммитирует таблицу отрезков многоугольника
,point - иммитирует таблицу точек, которые мы хотим проверить.

Луч пускаю в сторону точки (0,0). Потому ограничение - точка не может быть в начале координат
Соответственно длинна отрезка тоже не должна быть равной нулю и параллельно лучу, будет деление на ноль.

Перевести на акцесс, думаю вполне возможно.
если решите взятьза основу - Тестировать тщательно. Таки переживаю что накосячил в расчете.

Это сообщение отредактировал(а) Zloxa - 7.10.2010, 16:44


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
KateL
  Дата 7.10.2010, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 9.8.2007
Где: Новосибирск

Репутация: нет
Всего: нет



Прямо не ожидала, что так быстро ответят.
Спасибо большое  smile 
Завтра буду пробовать применить. 
PM   Вверх
Zloxa
Дата 7.10.2010, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3470
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



KateL, для акцесса этот запрос надо будет несколько переработать. 


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
Akina
Дата 7.10.2010, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20570
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 45
Всего: 453



Цитата(Zloxa @  7.10.2010,  17:23 Найти цитируемый пост)
для акцесса этот запрос надо будет несколько переработать.  

greatest(val1,val2) => IIF(val1>val2;val1;val2)
least(val1,val2) => IIF(val1<val2;val1;val2)
mod(count(*),2) = 1 => (count(*) MOD 2) = 1

остальное вроде совместимо.

Это сообщение отредактировал(а) Akina - 7.10.2010, 16:41


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
Zloxa
Дата 7.10.2010, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3470
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(Zloxa @  7.10.2010,  15:43 Найти цитируемый пост)
xp<=greatest(0,x) and xp>=least(0,x)

Здесь я малость перестарался. Мы ведь луч пускаем, нужно его с одной стороны ограничивать....
причем, главно сразу правильно сделал, а потом подумал и переделал. Надо было больше думать.

заменить на xp<=x
тоже и для y "and yp<=greatest(0,y) and yp>=least(0,y)"  заменить на "yp<=y"

Это сообщение отредактировал(а) Zloxa - 8.10.2010, 09:19


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
KateL
  Дата 8.10.2010, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 9.8.2007
Где: Новосибирск

Репутация: нет
Всего: нет



Еще раз спасибо за советы.

Я ранее не работала с такими сложными запросами, поэтому долго разбиралась.
Но пока у меня не получилось заставить его работать.
При выполнении запроса выдает ошибку: "Ошибка синтаксиса в выражении запроса"

Возможно, дело в этом: (из хелпов про SQL)

В общем случае оператор SELECT с подзапросом имеет вид:

SELECT ...
FROM ...
WHERE <сравниваемое значение> <оператор> (SELECT ... FROM ... WHERE ...)


Подзапрос часто называют вложенной командой SELECT, подкомандой SELECT или внутренней командой SELECT. Обычно подзапрос выполняется первым, и его результат используется для определения выборки в главном или внешнем запросе.

Подзапрос можно использовать в следующих предложениях SQL команд:
• WHERE
• HAVING

Примечание: Такие сервера как Oracle, MS SQL, Interbase поддерживают использование подзапросов еще и в предложении FROM.


Это сообщение отредактировал(а) KateL - 8.10.2010, 18:10
PM   Вверх
Zloxa
Дата 8.10.2010, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3470
Регистрация: 12.9.2008

Репутация: 53
Всего: 161



Цитата(KateL @  8.10.2010,  18:09 Найти цитируемый пост)
(из хелпов про SQL)

читайте документацию по тому продукту, с которым работатете, а не по какието невнятные  хелпы по SQL.
Акцесс поддерживает подзапросы в from.

Цитата(KateL @  8.10.2010,  18:09 Найти цитируемый пост)
Примечание: Такие сервера как Oracle, MS SQL, Interbase поддерживают использование подзапросов еще и в предложении FROM.

Сейчас скорее по пальцам нужно перечислять движки, которые их не поддреживают нежели те, кто его поддерживает.


Это сообщение отредактировал(а) Zloxa - 8.10.2010, 19:41


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
KateL
  Дата 13.10.2010, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 16
Регистрация: 9.8.2007
Где: Новосибирск

Репутация: нет
Всего: нет



Большое спасибо за помощь!
Все заработало!  smile 

(Моя ошибка была в том, что я немного переписала условие, и в качестве оператора "не равно" использовала != вместо <>)

PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Составление SQL-запросов | Следующая тема »


 




[ Время генерации скрипта: 0.1550 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.