Алгоритмы и формулы |
Здравствуйте, гость ( Вход | Регистрация )
Алгоритмы и формулы |
07 Mar 2008, 16:28
Сообщение
#21
|
|
Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз |
Цитата(Chrono Syndrome @ 06 Mar 2008, 19:54) Его же потом еще закрасить придется . ну так обвести линией, а потом FloodFill хотя если учесть что где-то в массиве наверняка хранится поле, то можно и напрямую |
|
|
07 Mar 2008, 16:35
Сообщение
#22
|
|
•●Revolucionario●• Сообщений: 2 467 Спасибо сказали: 5934 раза |
Цитата ну так обвести линией, а потом FloodFill А если FloodFill и его аналоги недоступны по каким-то причнам ? Тогда придется закрашивать сомстоятельно. Ну а уж коли идет закраска - почему бы не посчитать пиксели мимоходом ? -------------------- life MOV.I #life+1, *life
האם יש זמן לעצור ? |
|
|
Гость_Д'якон_* |
07 Mar 2008, 20:24
Сообщение
#23
|
|
Есть такое предложение. Понятно, что поле состоит из квадратов (в зависимости от размера человека, например 5х5 пикселей), каждый квадрат имеет свои координаты (например координаты у нас от 0 до 100 по 2-ум координатным прямым). Хотя это не суть важно.
Ну а дальше можно так сделать (надеюсь не сильно сложно): 1) Создаем массив из координат поля 2) Запоминаем в одномерный массив все координаты передвижения человека, кроме углов (т.е. там где менялось направление движения). 3) После того как человек повторно пересек границу поля (т.е. момент отсечения фигуры), запускаем цикл, который проверяет все координаты поля, т.е. For y:= 1 to 100 do begin For x:=1 to 100 do begin Т.е. как бы проводим линии через все поле паралельно оси х-ов по каждой координате у. При этом проверяем количество координат которые посещал игрок на каждой линии. Далее: если координат на линии больше 1-ой, то вытираем участки поля которые находятся по координатам между 1 и2 3 и 4 5 и 6 и т.д. если координата 1-на, то подсчитывае расстояние от начала и конца поля до координаты, т.е. Х или 100-Х, и вытираем участки поля которые оказались на меньшей стороне (т.е. либо от 0 до Х, либо от Х до 100). Далее проверяем начальный и конечные координаты поля, что бы знать в следующий раз в каких рамках запускать цикл для каждого у-ка. Надеюсь понятно объяснил |
|
|
Гость_Д'якон_* |
07 Mar 2008, 21:02
(Сообщение отредактировал Д'якон - 07 Mar 2008, 21:03)
Сообщение
#24
|
|
Да забыл добавить, что углы (т.е. точки где меняется маршрут) тоже нужно сохранять, чтобы знать где мы попадаем на границу фигуры и не учитывать ее.
|
|
|
Гость_Д'якон_* |
07 Mar 2008, 21:31
Сообщение
#25
|
|
Немного не так. Для начала нужно определить еще одну вещь, но смысл в том чтобы удалять поля которые находятся между двумя отрезками пути, которые пересекает прямая параллельная оси
|
|
|
08 Mar 2008, 12:30
(Сообщение отредактировал Chrono Syndrome - 08 Mar 2008, 12:47)
Сообщение
#26
|
|
В миру GrayFace Сообщений: 2 528 Спасибо сказали: 817 раз |
Д'якон, твой алгоритм в таком виде не сработает, т.к. не сможет различить 2 таких случая:
1) 00000____00000 00000000000000 00000000000000 2) 00000____88888 00000000_88888 00000000_88888 т.е. в первом случае игрок пошел по горизонтали и вернулся наверх, а во 2м - пошел вниз и отсек поле, закрашенное 8-ми. В твоем алгоритме первая строка будет одинаковой. Дамаю, надо, наоборот, оперировать вертикальными и горизонтальными отрезками. Идя по горизонтали надо считать кол-во пересечений вертикальных отрезков, а при переходе на след. линию учитывать пересечение горизонтального отрезка в точке x=0. Вообще, в дискретном случае получается много тонкостей: 1) Надо считать пересечения не отрезков, а полуинтервалов. Исключать либо меньшую по координате вершину отрезка, либо большую. Например, не будем учитывать пересечения большей по координате вершины. 2) Тогда, при переходе на след. строку надо менять "ориентацию" сразу, как только мы коснулись горизонтального полуинтервала. Только, чтобы это работало быстро, надо хранить, таки, сами точки, но в каждой из них прописывать, является ли она частью горизонтального и является ли частью вертикального полуинтервала. Чтобы учесть то, что от области уже отрезаны какие-то куски,надо учитывать движение человека и в этих областях. А простой алгоритм такой: находим первую незакрашенную точку и шуруем от нее чем-то типа FloodFill'а. Т.е. закрашиваем ее, просматриваем соседей и с незкраенными рекуррентно делаем то же самое. Потом так же закрашиваем 2ю часть области, а потом убираем меньшую по кол-ву точек. Скорость уменьшится максимум раз в 10. -------------------- ДНК банана на 50% состоит из человека.
|
|
|
08 Mar 2008, 12:41
Сообщение
#27
|
|
•●Revolucionario●• Сообщений: 2 467 Спасибо сказали: 5934 раза |
Цитата А простой алгоритм такой: находим первую незакрашенную точку и шуруем от нее чем-то типа FloodFill'а. Т.е. закрашиваем ее, просматриваем соседей и с незкраенными рекуррентно делаем то же самое. Потом так же закрашиваем 2ю часть области, а потом убираем меньшую по кол-ву точек. Скорость уменьшится максимум раз в 10. 1) А если отсечена большая часть поля ? 2) А в случае самопересечения что делать ? -------------------- life MOV.I #life+1, *life
האם יש זמן לעצור ? |
|
|
Гость_Д'якон_* |
08 Mar 2008, 12:51
Сообщение
#28
|
|
Да я и сам понял, что метод не совсем полный. Но я придумал как сделать полным.
Нужно "проводить" линии во всех направлениях, учитывая при этом край поля от которого отталкиваемся за линию пересечения и один раз провести линию не учитывая края полей. В конце сравнить результаты и удалить меньшую часть. Сейчас нарисую, чтоб было понятно |
|
|
Гость_Д'якон_* |
08 Mar 2008, 13:17
Сообщение
#29
|
|
Добавлено ([mergetime]1204971458[/mergetime]): 1 - это движение игрока по полю А потом пять методов из которого выбираем меньшую площадь (т.е. меньшее кол-во координат было удалено) |
|
|
08 Mar 2008, 16:39
Сообщение
#30
|
|
Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз |
считаем две площади по обе стороны и закрашиваем меньшую.
а в случае самопересечения закрашиваем тот участок и не учитываем. |
|
|
Гость_Д'якон_* |
08 Mar 2008, 16:49
Сообщение
#31
|
|
//считаем две площади по обе стороны и закрашиваем меньшую.
А как посчитать? |
|
|
08 Mar 2008, 16:51
Сообщение
#32
|
|
Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз |
ну писали уже. поле наверняка хранится в массиве булевском. а там уж посчитать размеры не составит проблем.
|
|
|
Гость_Д'якон_* |
08 Mar 2008, 16:54
Сообщение
#33
|
|
А как выделить нужную часть поля. Как программа поймет какую часть нужно посчитать?
Добавлено ([mergetime]1204984484[/mergetime]): Допустим взять мой рисунок. Как программа поймет, что там всего две фигуры? |
|
|
08 Mar 2008, 18:36
Сообщение
#34
|
|
Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз |
волновой алгоритм, но вместо последовательных чисел используем одинаковые. теперь одна часть у нас пронумерована одним числом, другая - другим. осталось посчитать.
я вообще не понял твоего рисунка. |
|
|
Гость_Д'якон_* |
08 Mar 2008, 18:48
Сообщение
#35
|
|
волновой алгоритм? Как? Разъясни
|
|
|
08 Mar 2008, 19:14
Сообщение
#36
|
|
Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз |
помечаешь одну вершину каким-либо числом (обычно 0). увеличиваем счетчик на 1. все вершины смежные с вершинами, у которых метка равна счетчик-1, и не имеющие метки помечаем числом счетчик. делаем это пока можно пометить хоть что-то.
Добавлено ([mergetime]1204992873[/mergetime]): зы. разъясни свой рисунок |
|
|
Гость_Д'якон_* |
08 Mar 2008, 19:33
Сообщение
#37
|
|
Все равно не понял, что это даст.
Разъясняю рисунки. На 1-ом рисунке, более жирной линией отмечен путь человека. На 2-ом рисунке запускаем цикл F:=1 - устанавливаем флаг в true For y:=1 to 100 do begin For x:=1 to 100 do begin где от 1 до 100 - координаты поля (допустим!) Если при прохождении цикла координата X;Y - совпадет с координатой на которой был человек флаг устанавливается в 0. При этом каждая координата проходит проверку на удаление. Если F=1, то координата удаляется. Если опять попали на координату игрока, то F=1. Стрелочки на линии показвают направление в котором мы запускаем цикл. Дальше еще 3-ри цикла в разных направлениях, при этом считаем удаленные координаты в каждом направлении. И 5-ый рисунок. Запускаем сразу в двух направлениях по х и по у, но с начальным флагом 0. И там где пересекутся удаленные координаты в двух направлениях, те и удаляем (рисунок немного не правильный, извеняюсь). В принципе 5-ый цикл нужен для проверки самопересечений. Понятно? |
|
|
08 Mar 2008, 19:45
Сообщение
#38
|
|
Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз |
неа
|
|
|
Гость_Д'якон_* |
08 Mar 2008, 19:59
Сообщение
#39
|
|
Хорошо, давай так. Флаг F=true, говорит нам о том, что координату нужно удалить.
Рассмотрим рисунок№2 Представь, что ты ведешь прямую линию СЛЕВА НАПРАВО паралельно оси Х, с координатой по у=20 (как линия на рисунке примерно). Переходишь на координату 1;20 , проверяешь равено ли F единице, если да, то уделяешь эту координату. Дальше 2;20, то же самое. И так до тех пор пока координато на который ты в данный момент не совпадет с координатой на которой был игрок, т.е. где-то 85;20. Ставишь флаг в 0. И продолжаешь до конца поля тем же макаром. На 3-рисунке, Справа Налево, 4-ый - сверху вниз, 5-ый снизу вверх. А на 6-ом в двух направлениях, но с начальным флагом 0 |
|
|
09 Mar 2008, 13:26
Сообщение
#40
|
|
Яблочный произвол! Сообщений: 11 080 Спасибо сказали: 3988 раз |
вот вам. разбирайтесь.
http://gcr.by.ru/game01.7z |
|
|
Текстовая версия | Сейчас: 25 April 2024 - 16:28 |
Copyright by Алексей Крючков
Programming by Degtyarev Dmitry |