Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Чт апр 18, 2024 08:02

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Охват множества точек
СообщениеДобавлено: Вт июл 31, 2007 22:03 
ТЗ восстановлено модератором форума.

Дано множество точек:
Изображение
Найти такую последовательность точек соединив которые можно составить фигуру, содержащую в себе все точки:
Изображение
Предлагаемые варианты задания входных данных (выбор между ними произволен и не ограничиваем, выбирайте что понравилось или придумайте своё):
Графический файл (если цветной то с соглашением какие цвета считать точками, а какие -- нет)
Текстовый файл в виде псевдографики, опять же с неким соглашением о том что считать точкой а что -- нет, например, пробел будет обозначать пустоту, а любой символ кроме пробела (и перевода строки, само собой) будет обозначать точку.
\"Интерактивное\" задание точек через \"тыканье\" в рамочке внутри GUI-окошка.
Варианты задания выходных данных:
Графический файл, где точки соединены и наглядно видна корректность решения.
Текстовое обозначение множества соединённых точек. Для этого можно идентифицировать точки во входном формате и тогда на выходе должно получаться что-то вроде: \"PGBERTY\" означающее: точка P -- точка G -- точка B и т.д.
Картинка из первого варианта, но только в окошке.
PS. Про \"вумные\" названия всего вышеописанного и про \"вумное\" название задачи мне известно. Не пишу его только потому что оно: а) \"вумное\" б) название само содержит в себе решение задачи (по крайней мере я от него плясал и доплясался до решения лет 7 назад когда решал)


Последний раз редактировалось profiT Сб мар 01, 2008 00:48, всего редактировалось 1 раз.

Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 01, 2007 00:22 
Не в сети

Зарегистрирован: Вт май 09, 2006 12:31
Сообщения: 3438
Благодарил (а): 5 раз.
Поблагодарили: 16 раз.
Составить массив, описывающий точки по след. параметрам -
координаты, наличие-отсутствие точек по обе стороны прямой (отрезка) между данной точкой и точками с ближайшими координатами, если таковые только по одну сторону отрезка - вносим ещё один параметр - для какого вектора (справа-налево, вниз ... ) может быть ограничителем, если по обе стороны - отрезок выбраковывается, дальше не помню. И на Форте пока не в состоянии быстро...
Плясать начинаем от точек с крайними координатами, разумеется, соединяя с ближайшими :)

_________________
понимаю некоторую бестолковость некоторых вопросов


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 01, 2007 09:08 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 13:19
Сообщения: 3565
Откуда: St.Petersburg
Благодарил (а): 4 раз.
Поблагодарили: 72 раз.
profiT писал(а):
Найти такую последовательность точек соединив которые можно составить фигуру, содержащую в себе все точки:


нужно уточнить в задании, какую фигуру получать, а то, можно по тем же точкам вместо колобка нарисовать ежа, и он тоже будет включать в себя все точки.

Подходит ли такое решение?
Изображение

_________________
С уважением, WingLion
Forth-CPU . RuF09WE
Мой Форт
Отсутствие бана это не заслуга юзера, а недоработка модератора (с)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 01, 2007 10:16 
WingLion
Мда. Правильная претензия.

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


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 08, 2007 19:53 
Скорее не выпуклый, а содержащий наименьшее число точек...


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 08, 2007 20:07 
не-е... в задание сказано - должен содержать ВСЕ точки!


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт авг 10, 2007 01:21 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 7960
Благодарил (а): 25 раз.
Поблагодарили: 144 раз.
Взять крайнюю точку (для определенности - самую левую), определить направления на все остальные, выбрать с наибольшим значением угла (в полярных координатах, разумеется). Для полученной точки повторить, пока не придем к началу.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пт авг 10, 2007 18:46 
Спокойно.

Я уже давно ;) решение этой задачки показал кому следует.

Так что, думаю, можно от теории уже переходить немножко к практике :)


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Пн авг 13, 2007 23:09 
Где-то видел уже эту задачку. Отсортировать точку по углу (в системе координат с центром в самой левой точке), далее обходить и выкидывать "неправильные" вершины, пока таковых не останется. Каждое ребро — вектор (в направлении порядка обхода), знак векторного произведения смежных векторов определяет "правильность" вершины.
Кодировать библиотеки для таких задач скушно. На основе s-expr.f может выйти нечто вроде следующего кода алгоритма:
Код:
  \ на входе список точек в виде пар (x y)
  split-by-min-y s-tuck .-  \ вычли левую точку из остальных ( p1 list1 )
  sort-by-tg s-swap 1 list append \ отсортировали по углу и вернули точку в список ( list2 )
  0
  BEGIN ( s: list ) ( prev-length )
    s-dup
      s-dup lshift-circle .- \ получили список векторов (циклически сдвинули список и по-элементно вычели )
      s-dup lshift-circle .crossprod .is-positive \ из списка векторых произведений получен список флагов
    .filter \ оставили элементы с положительным знаком
    s-dup length TUCK = \ если удаленных вершин не было, то решение достигнуто
  UNTIL DROP
  \ на выходе список охватывающих точек
Операции начинающиеся с точки — аналогичны по смыслу матлабовским. ".+" сложить списки по-элементно, или добавить элемент к каждому элементу списка.


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вт авг 14, 2007 12:17 
Интересное решение: аскетично в плане используемой "библиотечной" функциональности, без отдельной сортировки, но лежащее в основе рекурсивное деление плоскости очень напоминает quick-sort. В слове hull-split комментов очень не хватает ;)


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Вт авг 14, 2007 16:27 
В основе лежит известный алгоритм quickhull(google). Вы точно подметили его сходство с quicksort!
Код у меня получился гораздо более громоздкий, чем мог быть, если бы я не так торопился с этой задачей поквитаться. (Проще всего "облагородить" мое решение можно было бы с помощью имен, вместо c-pick).

Даю ниже описание hull-split:

Слово hull-split принимает в качестве аргументов список точек(p) и две точки(x1y1 x2y2) прямой разбиения. Строится список из элементов вида ( d (x y) ). То есть для каждой из точек c данной прямой считается векторное произведение. Затем список фильтруется на предмет положительных произведений. Если длина результата оказалась меньше двух, возвращаем (x1y1 cadrs(p)). Иначе находим элемент с максимальным произведением(он заведомо принадлежит оболочке), и выполняем(p' = cadrs(p)):

append(hull-split(p', x1y1, max), hull-split(p', max, x2y2)).

Сам код hull-split интересен разве что "трюком" с присоединением к функции-аргументу map значений прямой:
... ['] h-s' xt->s 3 list map ... на самом деле map получает ( x1y1 x2y2 h-s' ) в качестве второго аргумента.

Спасибо за проявленный интерес! :)


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 22, 2007 13:58 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2168
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
Решение в лоб(недостатки - глобальные переменные, возня с циклами), алгоритм - как делал бы человек с карандашом и точками на мм-ке.
Для вывода результатов использовал метод true-grue.
Запускаем программу, получаем exe-файл. Пишем bat-файл, например такой:
Код:
G:\spf-418\svg.exe > G:\spf-418\p.svg BYE
G:\inkscape\inkscape.exe G:\spf-418\p.svg.

Запускаем этот bat-файл, inkscape.exe(д.б. установлен) выводит результат.
Программа дает результат при числе точек больше 0(в том числе при одной и двух точках - в отличие от программы true-grue).
Сам текст программы:
Код:
101 CONSTANT gbr                \ размер стороны поля для точек
35 CONSTANT N-points           \ количество точек
CREATE Abeg  gbr DUP * ALLOT

REQUIRE RANDOMIZE lib\ext\rnd.f

: gen-points  N-points RANDOMIZE 0 DO 1 Abeg gbr CHOOSE gbr * gbr CHOOSE + + C! LOOP ;

\ геом. характеристики множества точек
gbr VALUE X-  gbr VALUE Y-  0 VALUE X+   0 VALUE Y+
gbr VALUE X-- gbr VALUE Y-- 0 VALUE Y+-  0 VALUE X+-  0 VALUE X++ 0 VALUE Y++ gbr VALUE Y-+ gbr VALUE X-+
\ параметры для функции поиска точки
0 VALUE XB      0 VALUE XE  0 VALUE YB   0 VALUE YE   0 VALUE AREA?
0 VALUE X       0 VALUE Y   0 VALUE dX   0 VALUE dY
0 VALUE XO      0 VALUE YO  0 VALUE dXO  0 VALUE dYO

: @A   gbr * + Abeg + C@ ;
: xy-bounds  \ Определение характеристик
Abeg gbr DUP * + Abeg
DO I C@
   IF  I Abeg - gbr /MOD  \ Y X
       DUP X- MIN TO X- X+ MAX TO X+ DUP Y- MIN TO Y- Y+ MAX TO Y+
   THEN
LOOP
X- TO X BEGIN Y- X  @A IF X TO X-- 1 ELSE X 1+ TO X 0 THEN UNTIL
X+ TO X BEGIN Y- X  @A IF X TO X+- 1 ELSE X 1- TO X 0 THEN UNTIL
X- TO X BEGIN Y+ X  @A IF X TO X-+ 1 ELSE X 1+ TO X 0 THEN UNTIL
X+ TO X BEGIN Y+ X  @A IF X TO X++ 1 ELSE X 1- TO X 0 THEN UNTIL
Y- TO Y BEGIN Y  X- @A IF Y TO Y-- 1 ELSE Y 1+ TO Y 0 THEN UNTIL
Y+ TO Y BEGIN Y  X- @A IF Y TO Y+- 1 ELSE Y 1- TO Y 0 THEN UNTIL
Y- TO Y BEGIN Y  X+ @A IF Y TO Y-+ 1 ELSE Y 1+ TO Y 0 THEN UNTIL
Y+ TO Y BEGIN Y  X+ @A IF Y TO Y++ 1 ELSE Y 1- TO Y 0 THEN UNTIL
;
: AREA XB XE > YE YB > AND XB XE < YB YE > AND OR IF 1 ELSE 0 THEN TO AREA? ;
: d+        < IF 1- ELSE 1+ THEN ;
: dX+       XE XB d+ ;     : dY+       YE YB d+ ;
: x++       X dX+ TO X ;   : y++       Y dY+ TO Y ;
: K1++      AREA? IF x++         ELSE y++         THEN ;
: K2++      AREA? IF y++         ELSE x++         THEN ;
: K1=E?     AREA? IF X XE =      ELSE Y YE =      THEN ;
: K2=E?     AREA? IF Y YE =      ELSE X XE =      THEN ;
: K1=B++    AREA? IF XB dX+ TO X ELSE YB dY+ TO Y THEN ;
: SET-dXYO  XE XB - ABS TO dXO YE YB - ABS TO dYO ;
: SET-dXY   X  XB - ABS TO dX  Y  YB - ABS TO dY  ;
: ANG<      SET-dXY AREA? IF dY dXO * dYO dX * ELSE dX dYO * dXO dY * THEN < ;
: ~dXYO     dY TO dYO  dX TO dXO X TO XO Y TO YO ;
: ~XYB      XO TO XB  YO TO YB ;
: POINT?    Abeg X gbr * Y + + C@ ;
: point. ." <circle cx=' " . ." ' cy=' " gbr SWAP - . ." ' r='0.4'/>" CR  ;
: points. Abeg gbr DUP * + Abeg  DO I C@ IF I Abeg - gbr /MOD point.  THEN LOOP ;
: poligon. SWAP . ."  , " gbr SWAP - . ;

: area. \ XB XE YB YE --
TO YE TO YB TO XE TO XB  AREA
BEGIN
  XE XB - ABS 1 > YE YB - ABS 1 > AND
  IF XB dX+ TO X  YB dY+ TO Y  SET-dXYO  SET-dXY  XB TO XO  YB TO YO
    BEGIN
      POINT? IF ANG< IF ~dXYO  THEN THEN  K1++ K1=E? IF K2++ K2=E? IF 1 ELSE K1=B++ 0 THEN ELSE 0 THEN
    UNTIL
    XO XB = YO YB = AND XB XE = OR IF  1 ELSE  ~XYB XB YB poligon. 0 THEN
  ELSE 1 THEN
UNTIL
;
: contur.  \ по часовой стрелке
." <polygon fill='none' points=' "
X-- Y-  poligon.                     X-- X-  Y-  Y--  area.
X-  Y-- poligon.   X-  Y+- poligon.  X-  X-+ Y+- Y+   area.
X-+ Y+  poligon.   X++ Y+  poligon.  X++ X+  Y+  Y++  area.
X+  Y++ poligon.   X+  Y-+ poligon.  X+  X+- Y-+ Y-   area.
X+- Y-  poligon.   ." '/>" CR
;
: SVG  gen-points  xy-bounds
   ." <?xml version='1.0'?>" CR   ." <svg height=' " gbr  . ." ' width=' " gbr  . ." '>" CR
   ." <g style='fill-opacity:1.0; stroke:black; stroke-width:0.2;'>" CR
   points. contur.  ." </g></svg>" ;

' SVG MAINX !  S" svg.exe" SAVE BYE

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 22, 2007 16:13 
chess писал(а):
Программа дает результат при числе точек больше 0(в том числе при одной и двух точках - в отличие от программы true-grue).
[/code]


Для работы с двумя точками достаточно вставить "s-dup length 2 > IF quick-hull THEN draw-hull".


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 22, 2007 16:54 
2chess: а как насчет точек из других квадрантов координатной плоскости?


Вернуться к началу
  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Ср авг 22, 2007 18:20 
Не в сети
Аватара пользователя

Зарегистрирован: Чт июл 20, 2006 11:31
Сообщения: 2168
Откуда: Екб
Благодарил (а): 0 раз.
Поблагодарили: 41 раз.
true-grue писал(а):
2chess: а как насчет точек из других квадрантов координатной плоскости?

Вопрос не понял. У тебя же точки тоже имеют только положительные координаты.
Все точки в квадрате с размером gbr(максимум gbr*gbr точек). Любое множество точек может быть в нем размещено.
Если надо чтобы были и отрицательные координаты - на входе задать соответствующие смещения, на выходе эти смещения убрать. Вообщем непонятно что непонятно - запусти программу. (Ухожу из Ineta - до завтра.)

_________________
С уважением, chess


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 30 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 8


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB