我有一个问题我正在尝试解决,我有一个点我正在尝试检查碰撞的列表,我有一般的想法可能使用一些pytagoras,但我的主要问题是效率的算法,因为我需要检查是否只有一个轴的矩形相交,假设我有一个矩形点(0,100),其他点(300,100),两者都在y = 100,所以我的应用程序我决定他们碰撞了,现在我怎么检查其中任何一个是否与其他任何一个碰撞?
我的第一次尝试是对我添加的每个矩形进行循环检查,如果新的矩形与其余的冲突,但我认为是错误的,因为如果我有100个rects,我将需要检查第一次碰撞其他99,如果他们与其他人发生碰撞,他们每个人都会。
我很确定循环会以指数方式增加,所以有人可以指出我正确的方向如何才能成为最有效的检查方式,谢谢!
编辑22-oct-13 使用@John Phu Nguyen函数
var events = [ {start: 30, end: 150}, {start: 540, end: 600}, {start: 560, end: 620}, {start: 610, end: 670} ];
//each start and end props are y coordinates, basically where the rect start and ends
function layOutDay(events) {
//console.log(events);
var events_container = document.querySelector('.events-col');
var frag = document.createDocumentFragment();
for(var i=0; i<events.length; i++){
//console.log(events[i].start);
var top = events[i].start;
var bottom = events[i].end-events[i].start;
var event = createEventDOM();
var gutter = event.querySelector('.gutter');
event.style.top = top + 'px';
event.style.height = gutter.style.height = bottom + 'px';
if(y_coords.indexOf(top) === -1 && y_coords.indexOf(bottom) === -1){
y_coords.push(top);
y_coords.push(bottom);
y_coords.sort();
event.style.left = '10px';
console.log('NO collision', top, bottom);
}else{
console.log('collision', top, bottom);
event.style.width = '250px';
event.style.left = '220px';
}
frag.appendChild(event);
}
events_container.appendChild(frag);
}
所以运行我得到的函数有2个碰撞,但是有3个不是2,我需要知道谁在x轴上相互移动了相互作用的人!
Here is a screenshot of what I'm trying to do
可能是一个调整,但我找不到它,任何帮助都非常感谢,谢谢!
答案 0 :(得分:2)
循环不会以指数方式增加,而是以二次方式增加,这可能仍然很糟糕。
有几种解决方案,具体取决于移动的矩形数量以及固定的矩形数量。
非常简单的解决方案是
移动矩形时,此网格数据结构很容易维护更新:只需将其从当前列表中删除,然后将其插入新位置列表中即可。
什么是最佳N
实际取决于应用程序。
答案 1 :(得分:1)
如果您只想检查沿轴的各个点,则排序列表可以正常工作。
在Javascript中:
//Existing points:
var x_coords = [0, 20, 310, 400];
var y_coords = [0, 50, 100, 500];
//New point
x_new = 300;
y_new = 100;
//Check for collision
if(x_cords.indexOf(300) == -1 && y_cords.indexOf(100) == -1)
{
//No collision, add to list
//Add another point
x_coords.push(300);
x_coords.push(100);
//Sort list, complexity should be low if sorted after every insert
x_coords.sort();
y_coords.sort();
}
如果您正在寻找范围内的碰撞,
x_cords.indexOf( 100 )
x_cords.indexOf( 200 )
将为您提供值100和200的索引。该范围内的任何内容都将出现在排序列表中的这两个索引之间。
其他信息:
'bottom'目前是元素高度,而不是底部。 if语句应该是:
if(y_coords.indexOf(top) === -1 && y_coords.indexOf(end) === -1)
但是,这仍然不会产生任何结果,因为indexOf()函数专门查找某个值,而不是某些值之间存在值。
为此,您可以使用列表理解:
elements_between_y100_and_y300 = [i for i in y_cords if (i >= 100 && i <=300)]
如果列表返回空,则表示没有冲突。
为了找出碰撞的元素,您很可能必须保留一个单独的列表,例如:
element_at[200] = 2