Обнаружение неправильной формы

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

  1. http://gamedev.tutsplus.com/tutorials/implementation/quick-tip-use-quadtrees-to-detect-likely-collisions-in-2d-space/
  2. http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/quadtrees-r1303
  3. http://jsfiddle.net/2dchA/2/

Код в (3) работает в JSFiddle, но ломается в этом разделе в моей тестовой среде (VS2012):

var myTree = new Quadtree({
  x: 0,
  y: 0,
  width: 400,
  height: 300
});

с сообщением Quadtree не определено в IE. FF и Chrome просто замазывают это и отображают пустую страницу. Я не мог разобраться. Вопрос 1. Может ли кто-нибудь помочь с этим?

Мой главный вопрос: у меня есть регион (участки земли, такие как карта) с примерно 1500 участками, нарисованными в формате html5, а не изображениями jpg или png. Для этого требуется много строк кода, но рендеринг отличный, поэтому я оставлю его таким. Я намереваюсь, чтобы событие при наведении курсора сообщало мне, на каком участке я стою, когда мышь останавливается. Как вы увидите в предыдущем вопросе, мои предыдущие попытки не были впечатляющими. Основываясь на изучении, которое я делал, и благодаря ответу / комментариям Кена Дж., Я хотел бы использовать этот новый подход, разбивая мой холст, скажем, на 15 квадроциклов по 100 объектов в каждом. Тем не менее, я хотел бы получить некоторое руководство, прежде чем я совершу еще одно дикое погружение в неправильном направлении.

Вопрос 2. Должен ли я нарезать его при создании или нарезка должна происходить, когда мышь находится над регионом, т. е. следует за мышью? Последнее звучит лучше для меня, но я думаю, что могу обойтись некоторыми советами и, если возможно, некоторым исходным кодом. Концепция quadtree совершенно нова для меня. Спасибо.


person Hannington Mambo    schedule 21.07.2013    source источник


Ответы (3)


Не могу помочь с вопросом 1.

Вы обязательно должны построить дерево как можно раньше, учитывая, что цель состоит в том, чтобы страница реагировала как можно быстрее, как только пользователь щелкнет где-нибудь.

Сохраняйте дерево до тех пор, пока пользователь взаимодействует с двумерной областью. Обновление дерева квадрантов не должно быть слишком сложным, поэтому, даже если область изменит содержимое, вы сможете повторно использовать существующее дерево (просто обновите его).

person mzedeler    schedule 21.07.2013

Учитывая тот факт, что ваша область рисования хорошо известна, я не вижу преимуществ в QuadTree по сравнению с пространственной хэш-функцией. Эта функция даст вам целое число из точки (x, y).

var blocWidth   = 20;
var blocHeight  = 20;
var blocsPerLine = ( 0 | ( worldWidth / blocWidth) ) + 1 ; 
function hashPoint(x,y) {
   return ( 0 | (x/blocWidth)) + blocsPerLine*(0|(y/blocHeight));
}

как только вы это сделаете, хешируйте все свои посылки в массиве:

parcelHash = [];

function addHash(i,p) {
   if (!parcelHash[i]) { parcelHash[i]=[ p ]; return; }
   if (parcelHash[i].indexOf(p) != -1 ) return;
   parcelHash[i].push(p);
}

function hashParcel (p) {
     var thisHash = hashPoint(p.x,p.y); // upper left
     addHash( thisHash, p);
     thisHash = hashPoint(p.x+width, p.y); // upper right
     addHash(thisHash, p);
     thisHash = hashPoint(p.x, p.y+p.height); // lower left
     addHash(thisHash, p);
     thisHash = hashPoint(p.x+width, p.y+p.height); // lower right
     addHash(thisHash, p);         
};

for (var i=0; i<allParcels.length; i++) { hashParcel(allParcels[i]) };

теперь, если у вас есть положение мыши, вы можете получить все посылки в одном блоке с помощью:

  function getParcels(x,y) {  
       var thisHash = hashPoint(x,y); 
       return parcelHash[thisHash]; 
    }
person GameAlchemist    schedule 21.07.2013
comment
Винсент, ваш код предполагает прямоугольные формы (x, y)? Я не уверен, что следую вашему предложению: мои фигуры представляют собой участки земли неправильной формы со слишком большим количеством «moveTo (x, y)» и «lineTo (x, y)», которые пересекаются, чтобы нарисовать один кусок... - person Hannington Mambo; 21.07.2013
comment
Это неожиданно, потому что, насколько я понимаю, посылки всегда должны иметь одинаковое соотношение ширины и высоты. Вы уверены, что это Quad Trees, а не kd-деревья (или что-то подобное)? - person mzedeler; 21.07.2013
comment
Собственно, это как googlemap, только вместо стран у меня участки земли. на этой стороне света они редко бывают правильной формы :) демаркациями могут быть реки, холмы и т. д. Я только что проверил k-d деревьев и думаю, что это не то, что мне нужно. kd является многомерным. Мой случай простой 2d, только неровные края. - person Hannington Mambo; 21.07.2013
comment
Деревья k-d можно использовать в любом количестве измерений, включая два :) Но опять же, разве Quad Trees не требует регулярных участков? Иначе это просто что-то другое? - person mzedeler; 22.07.2013

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

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

Из других Ваших сообщений делаю вывод, что посылки будут иметь неправильную форму. Обычно деревья квадрантов работают с прямоугольниками, поэтому вам нужно будет вычислить ограничивающий прямоугольник вокруг формы участка и вставить этот прямоугольник в дерево квадрантов. Затем, когда вы хотите определить, находится ли мышь над участком, вы запросите дерево квадрантов, которое даст вам набор участков, которые могут находиться под мышью, но затем вам придется сделать более точная проверка самостоятельно, чтобы убедиться, что это действительно так.

... когда мышь останавливается.

Из других ваших вопросов я увидел, что вы пытаетесь определить, когда мышь «остановилась». Возможно, вам следует посмотреть на это так: курсор мыши никогда не движется, он телепортируется по экрану от предыдущей точки к следующей. Он всегда остановлен, никогда не двигается. Это может показаться немного философским, но это сделает ваш код проще. Вы определенно сможете достичь того, что задумали, без каких-либо проверок setTimeout.

... нарезка моего холста, скажем, на 15 квадратов по 100 объектов в каждом.
... Должен ли я нарезать его при создании или нарезка должна происходить, когда мышь находится над регион

Вы не будете (и не сможете) выполнять нарезку, реализация quadtree делает это автоматически (это ее цель), когда вы вставляете или удаляете элементы из него (обратите внимание, что перемещение элемента фактически удаляет его, а затем повторно вставляет).

Я не изучал реализацию quadtree, которую вы используете, но вот две реализации MX-CIF quadtree на случай, если одна из них вам не подойдет:

Проблема в вопросе 1, вероятно, возникает из-за того, что страница jsfiddle (http) пытается получить доступ к quadtree.js, который находится на https

person bgr    schedule 27.07.2013
comment
Спасибо за понимание bgr. Я закончил с таймером для «остановки мыши», как упоминалось ранее. И хотя дерево квадрантов действительно интересное, я обнаружил, что не могу использовать его для своего случая. Я сгруппировал свои фигуры в сотни по коду; работает достаточно быстро для моих целей и сроков. Я обязательно изучу это позже. - person Hannington Mambo; 28.07.2013