从这个问题Detecting mouse coordinates with precision开始,我在过去的几天里学到了很多东西。以下是我选择的关于此主题的最佳学习资源:
(3)中的代码在JSFiddle中工作,但在我的测试环境(VS2012)中在此部分中断:
var myTree = new Quadtree({
x: 0,
y: 0,
width: 400,
height: 300
});
在IE中未定义消息Quadtree。 FF& Chrome只是对其进行光泽处理并显示空白页面。我无法理清。 问题1:有人可以提供帮助吗?
我的主要问题: 我有一个地区(像地图一样的地块),大约有1500个地块用html5绘制,而不是jpg或png图像。要完成它需要很多代码,但渲染效果很好,所以我保持这种方式。我打算让鼠标悬停事件告诉我当鼠标停止时我站在哪个包裹上。正如您在上一个问题中所看到的那样,我以前的尝试并不令人印象深刻。基于我一直在做的学习,并且由于Ken J的回答/评论,我想采用这种新的方法将我的画布分成15个四元组,每个对象100个。但是,在我以错误的方式进行另一次疯狂潜水之前,我想要一些指导。
问题2:我应该在创建时将其切片,还是应该在鼠标位于某个区域时切片,即跟踪鼠标?后者听起来对我来说更好,但我认为我可以做一些建议,如果可能的话,一些开始代码。四叉树概念对我来说是全新的。感谢。
答案 0 :(得分:1)
对问题1无能为力。
你应该尽可能早地构建树,因为目标是在用户点击某个地方后让页面尽快响应。
只要用户与2d区域交互,就保留树。更新四叉树不应该太难,所以即使该区域改变内容,您也应该能够重用现有树(只需更新它)。
答案 1 :(得分:1)
鉴于您的绘图区域是众所周知的,我认为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];
}
答案 2 :(得分:0)
除了别人说的话之外,我会给你一些提示。
...有一个鼠标悬停事件告诉我我正站在哪个包裹上......
从您的其他消息中我得出结论,包裹将具有不规则的形状。 Quadtrees通常使用矩形,因此您必须围绕宗地的形状计算边界矩形并在四叉树中插入该矩形。然后当你想确定鼠标是否在一个包裹上时,你将查询四叉树,它将为你提供一组可能在鼠标下的包裹,但你必须这样做更准确地检查你自己是否确实。
...当鼠标停止时。
从其他问题我看到你试图检测鼠标何时“停止”。也许你应该这样看待它:鼠标光标永远不会移动,它是从前一个点到另一个点在屏幕周围传送。它总是停止,永不停止。这可能看起来有点哲学,但它会让你的代码更简单。你绝对应该能够在没有任何setTimeout检查的情况下实现你的目标。
...将我的画布分成15个四个100个对象。
...我应该在创建时将其切片,还是应该在鼠标位于某个区域时进行切片
当你从中插入或删除项目时,你不会(也不能)进行切片,四叉树实现会自动执行(这是它的目的)(请注意,移动项目实际上是删除然后重新插入它)。
我没有研究你正在使用的四叉树的实现,但是这里有两个MX-CIF四叉树实现,以防一个不适合你:
问题1中的问题可能是因为jsfiddle(http)页面正在尝试访问位于https上的quadtree.js