У меня такой вопрос как разбить фигуры на прямоугольники?
возьмем такую ситуацию, что вам заранее известна форма, и имеются точки. нужно разбить фигуру на прямоугольники (rect), дело в том что саму область-фигуру не добавишь в регион. По любому надо разбивать на ректы. Ими проще проверять лежит ли точка внутри ректа или нет, чем какая то фигура.
Я уже многое сделал, у меня система находит эту фигуру. И надо после разбить на ректы.
Вот пример уже имеются 6 точек p1-p6, могу найти p7-p8. Теперь надо как-то собрать ректы (на глазок понятно что там 3, а то и меньше 2). надо как-то написать алгоритм, что эти отрезки образовали ректы
Фигуры могут быть любой формы
находил такой вопрос вот здесь, но ответа не нашел. алгоритм просто нужен

Принятый ответ

Вот конечный вариант. Переделал на хэш-таблицу
Исправил многие подвисы - большая часть которых эта строки. Именно строки вызывают подвисы. Они не только в дебагах, но в ExecuteFunc, строковое название молнии и пр. И теперь молнии могу миллиардами создавать без проблем. Я тексты строк все сохранил в бд. Без этого почему у юнитов анимация ходьбы поддергивалась.
Теперь все работает как надо и как часики. Единственная зараза - когда строю несколько деревней, потом вылетает чего-то с критом. Но это происходит очень и очень редко. где-то с шансом 0.05%. Возможно либо работаю с несуществующими объектами либо пытаюсь выгрузить из хэша не существующие данные. У вара какие то проблемы.
Пробовал вставить проверки GetHandleId(object) > 0 или HaveSavedReal или HaveSavedHandle - теперь сохранять карту не хочет. Пробую снова написать код

Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
37
4 года назад
Отредактирован ScorpioT1000
0
Вы 4 дня не можете решить элементарную задачу?
Делается это просто - надо реализовать понятие "прямоугольник" (= 2 точки) и операции булева вычитания
И можно будет вычитать что угодно сколько угодно раз.
Вот реализация для 2д ректа stackoverflow.com/questions/25116092/boolean-operations-on-2d-re...
0
24
4 года назад
0
Вы 4 дня не можете решить элементарную задачу?
Не 4 дня, а 9 месяцев. При этом, задача вполне решена самим варом, нужно только правильно воспользоваться тем что есть.
2
27
4 года назад
Отредактирован MpW
2
ScorpioT1000, спасибо. но информацию я знаю. И как применить эти две точки ректа я знаю. Но все равно че то по своему хочу до конца. Щас я близок к решению, исправляю ошибки. Я просто не понимаю, что там происходит. Почему так работает. То одно, нахожу ошибку, исправляю. то другое появляется. Ранее разные проблемы были. Сейчас такая проблема: То работает как часики, то выдает сообщение: вы не можете строить (а то он может), потом оказывается что там регион каким то образом лежит (это сейчас нашел, оказывается надо boolean проверку отдельно делать).
У меня из-за региона такие проблемы. Криво определяет IsPointInRegion лежит ли точка. Могу доказательства даже показать. Поэтому выверяю лишними проверками.
prog, не 9 месяцев. 2 года. У меня такая идея возникла тогда, мне показалось это необычным.

я вот подумал мб код с подробным разбором на обозрение выложить чем карту? Я думаю вы в карту не заглядывете даже

немного мыслей об этом
не хотел писать об этом. а то ругать будут что ты делаешь и прочее. Но все же осмеливаюсь написать.
все говорят, возьми сделай что-то подобие массива ректов. Но это еще надо придумать как их объединить вместе. Это алгоритм составить. И чтобы друг на друга не наслаивались. Потом еще регион то будет не один, планируется что у игрока мб несколько деревней (если он там захочет). А еще допустим игроков то тоже несколько будет. Это сколько регионов. А на каждый регион еще надо эти массивы. Да это наверное самое неудобная идея. А еще надо будет проверять лежит ли точка в регионе. Поэтому это отменяется.
Самое простое это иметь массив регионов udg_Region и туда просто добавлять ректы. Или удалять.

Еще самую хорошую идею подсказал NazarPunk использовать массив вершин многоугольника, и трассировку лучей. До сегодняшнего момента я не знал как этого сделать, поскольку не знал алгоритма пересечения точек. Но этот метод только пока мне кажется показывает, что лежит ли точка внутри многоугольника. И пока что мне проще IsPointInRegion. А как допустим к существующему многоугольнику встроить прямоугольник. Это опять придумать надо.
немного информации про IsPointInRegion. решил сделать такую херню. Но при чем рабочую.
function IsPointInArea takes real x, real y, integer k returns boolean
return (IsPointInRegion(udg_Region[k], x, y))
endfunction

//Проверка IsPointInRegionVillage помогает определить занято место или нет
//У каждого региона udg_Region[] отдельный земельный участок
//В отличии от обычных областей udg_Region[] в udg_Territory_of_the_Village добавляют все все регионы. Это позволяет просто проверить в будущем занято или нет 
function IsPointInRegionVillage takes real x, real y returns boolean
return (IsPointInRegion(udg_Territory_of_the_Village, x, y))
endfunction

//лежит ли точка на покупаемом участке
//проверяет лишь нахождение точки на свободном участке
function IsPointInArea_1 takes real x, real y returns boolean
return (  (PointInRect1(x,y,udg_rect_minx_p1,udg_rect_maxx_p1,udg_rect_miny_p1,udg_rect_maxy_p1) ) and (not IsPointInRegionVillage(x, y)))
endfunction
//Точка лежит внутри многоугольника
//Проверяет принадлежность точки внутри земельного участка деревни IsPointInArea вместе с покупаемым участком udg_CheckRect 
function IsPointInArea_2 takes real x, real y, integer n returns boolean
return IsPointInArea(x,y,n) or  IsPointInArea_1(x, y)
endfunction
//Лежит ли точка внутри многоугольника и свободна точка от udg_Check_Region
//Это проверка необходима для разбивки многоугольника на ректы (прямоугольники)
//Но сперва необходимо проверить, лежит рект снаружи или внутри. Поэтому проверяем лежит ли центр внутри
//Когда мы находим две вершины ректа, то рект добавляем в временный udg_Check_Region, чтобы этот участок больше не трогали
function IsPointInArea_3 takes real x, real y returns boolean
return (IsPointInArea_2(x,y,udg_temp_integer))and (not IsPointInRegion(udg_Check_Region, x,y) )
endfunction

//CountOccupiedVertexsInRegion - ищет число занятых соседних точек
//Проверка позволяет определять касается ли точка с границей региона или ректа udg_CheckRect (k>0), лежит внутри (k=4) или не лежит (k=0).
//Помогает искать и создавать вершины многоугольника
//Проверяются обычно 4 диагональные клетки или... если быть точным, проверяем 4 точки
function CountOccupiedVertexsInRegion takes real x, real y, integer n returns integer
//Ранее boolean-проверкой IsPointInRegion определял ОДНУ соседнюю клетку, тк расчитывал на меньшее число операции. И если boolean-состояние клетки меняется, значит, упирается в границы. И стоит остановиться циклу.
//Но к сожалению, эта boolean-проверка IsPointInRegion не всегда работает точно. Если добавить рект в регион с помощью нативки RegionAddRect, вы получите совсем другие результаты. 
//-----
//   ПРОБЛЕМА ПЕРВАЯ: Если точнее, регион берет не точками, а ячейками, мин ячейка имеет размер 32x32 (в редакторе можно включить сетку: Вид -> Сетка G -> Мелкая). И вы можете получить совсем другие результаты при проверке IsPointInRegion
//   Если у вас какие-то произвольные координаты вершин ректа, то при добавлении в нативку RegionAddRect координаты подправляют на ближайщие кратные числу 32. Типа -96,-64,-32,0,32,64, 96, 128 итд 
//   Эта нативка RegionAddRect иногда добавляет лишнее, это очень плохо проверка IsPointInRegion. Как говорил, она клеточками занимает область. есть добавить рект с вершинами (minx=0, miny=0,maxx=32.,maxy=32). То рект он добавляет с размерами (minx=0,miny=0,maxx=64.,maxy=64). Короче берет ближайшую координату кратно числу 32. Если взять число 64, то вставит 96. Если 96, то 128. Пробовал меньше 31, подправляет на 32.
//   Нсли занять точку (32,32) то регион занимает ячейку (minx=32-maxx=64, miny=32-maxy=64). Теперь вы должны понимать как это работает. Если добавляю рект с вершинами (minx=0, miny=0,maxx=32.,maxy=32). То рект он добавляет с размерами (minx=0,miny=0,maxx=64.,maxy=64).
//-----
//   ПРОБЛЕМА ВТОРАЯ: Алгоритм. Проблема как раз возникает, если два игрока делят одну ячейку или точнее два граничащих объекта (пример ректы) имеют общую границу.
//   Регион то хранит не в виде точек, а ячеек. Не получится границу линиями, кто-то обязательно отожмет клетку. IsPointInRegion скажет, что клетка занята, поэтому завершит цикл раньше. А на деле оставит лишнюю ячейку, это еще надо будет как-то заранее выверять и мучиться. Придумал два-три алгоритма, не так хорошо работали. Потом еще больше нагромождении в виде доп проверок.
//----
//Поэтому сравнивают сразу несколько соседних клеток, проверяя "лежит ли точка в участке" и выводят те числа, которые приводят  изменению.
//Можно было проверять соседние клетки по вертикали и по горизонтали, но по сравнению с "проверкой соседних клеток по диагонали" это не практично.
//Проверка по диагонали позволяет определять направление, двигаясь по часовой стрелке. а еще заранее исключает точку x,y, образующую одну общую вершину
// 1 point \ | / 2 point |
// ----------?-------------
// 3 point / | \ 4 point |
// ----------| ----------|-


local integer a = 0
local real r = 2.00
local real angle

//1) берем 4 точки от точки x,y
//считаем кол-во лежащих точек
if IsPointInArea_2(x-r,y+r,n) then
    set udg_px[a] = x-r
    set udg_py[a] = y+r
    set a = a + 1
endif
if IsPointInArea_2(x+r,y+r,n) then
    set udg_px[a] = x+r
    set udg_py[a] = y+r
    set a = a + 1
endif
if IsPointInArea_2(x+r,y-r,n) then
    set udg_px[a] = x+r
    set udg_py[a] = y-r
    set a = a + 1
endif
if IsPointInArea_2(x-r,y-r,n) then
    set udg_px[a] = x-r
    set udg_py[a] = y-r
    set a = a + 1
endif

//Проверка не образует ли одну общую вершину (2 ректа могут касаться углами)
//            ¦ ¦ ¦ ¦ ¦ ¦ ¦
//            ¦ ¦ ¦ ¦ ¦ ¦ ¦
//^^^^^^^^^^^?¦ ¦ ¦ ¦ ¦ ¦ ¦
//^^^^^^^^^^^^
//^^^^^^^^^^^^
//Если 2 занятые точки не имеют 90 гр значит это диагонально касаются
if a == 2 then
    set angle = Acos(AngleBetweenTwoVectors(udg_px[0]-x,udg_py[0]-y, udg_px[1]-x,udg_py[1]-y)) * bj_RADTODEG
    //call DisplayDebugTextToPlayer("угол: " + R2S(angle) )
    if angle == 90.00 then
        return 2
    else
        return 5
    endif

endif

return a
endfunction
0
18
4 года назад
Отредактирован Vlod
0
Если функционал, который вам нужен, это:
Строить здания типа A.r, окруженные прямоугольной областью а.r так, что области а.r и а.b, принадлежащие разным игрокам, не могут накладываться. И строить здания типа В.r только внутри областей а.r.
То такая наработка пишется за ~ час.
вы в карту не заглядываете даже
Вам подсказали несколько раз. Если не получается написать, можете попросить другого пользователя
0
27
4 года назад
Отредактирован MpW
0
Все работа завершена. Работает исправно и без лагов.
Единственное, что это примерная наработка на одну деревню. буду переделывать на несколько
Есть конечно недостатки: это число вершин многоугольника. Чем больше вершин имеет, тем больше вычислении делает на каждый отрезок. Немного подвисало. При разбивке еще больше таких вычислении. Пришлось сделать временную структуру, чтобы из нее удалять точки для уменьшения работ цикла. А также число вершин влияет и на число молнии. 0-100 молнии еще норм. Где-то 300 молнии уже создают лаги на слабом компе. Я просто уже думаю, что сделать надо ограничение вершин на регион, чтобы игрок строил ровно. И еще кнопочку добавить: показать зоны молниями или спрятать, чтоб не мешало. Помню, что молнии можно локально создавать на игрока
не знаю как это работать будет с несколькими игроками
Загруженные файлы
0
27
4 года назад
Отредактирован MpW
0
Вот конечный вариант. Переделал на хэш-таблицу
Исправил многие подвисы - большая часть которых эта строки. Именно строки вызывают подвисы. Они не только в дебагах, но в ExecuteFunc, строковое название молнии и пр. И теперь молнии могу миллиардами создавать без проблем. Я тексты строк все сохранил в бд. Без этого почему у юнитов анимация ходьбы поддергивалась.
Теперь все работает как надо и как часики. Единственная зараза - когда строю несколько деревней, потом вылетает чего-то с критом. Но это происходит очень и очень редко. где-то с шансом 0.05%. Возможно либо работаю с несуществующими объектами либо пытаюсь выгрузить из хэша не существующие данные. У вара какие то проблемы.
Пробовал вставить проверки GetHandleId(object) > 0 или HaveSavedReal или HaveSavedHandle - теперь сохранять карту не хочет. Пробую снова написать код

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