簡體   English   中英

碰撞檢測算法

[英]Collision detection algorithm

我正在嘗試解決的算法有問題,我正在嘗試檢查碰撞的點列表,我大概有可能使用一些吊鈎,但是我的主要問題是算法的效率,因為我需要檢查是否僅在一個軸上進行rect相交,可以說我在點(0,100)上有一個rect,在點(300,100)上有一個rect,兩者都在y = 100,所以對於我的應用程序,我決定了碰撞,現在我如何檢查任何一個rect是否與其他任何碰撞?

我的第一次嘗試是循環檢查如果新的rect與其余的碰撞,我添加的每個rect的檢查,但是我認為是錯誤的,因為如果我有100 rect,我將需要檢查與其他99的第一個碰撞,並且它們中的每一個都與其他碰撞。

我敢肯定,循環將成倍增加,這是不好的,所以有人可以向我指出正確的方向,這將是最好的檢查效率的方法,謝謝!

使用@John Phu Nguyen函數編輯13年10月22日

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個rect碰撞,但是有3個不碰撞2,我需要知道誰正在與誰碰撞誰將x軸彼此相鄰移動!

這是我正在嘗試做的屏幕截圖

也許是一個調整,但我找不到它,非常感謝任何幫助,謝謝!!!

循環將不會呈指數級增長,而是呈二次方增長,這可能仍然很糟糕。

有幾種解決方案,例如,取決於移動多少個矩形以及固定多少個矩形。

一個非常簡單的編碼解決方案是

  • 建立NxN個單元格的網格,其中每個單元格可以包含接觸該單元格的矩形列表
  • 遍歷這些矩形,並針對每個矩形將其放入每個觸摸的單元格列表中。 這樣做時,您還可以檢查矩形是否與同一單元格列表中的其他矩形碰撞。

移動矩形時,此網格數據結構很容易維護更新:只需將其從當前列表中刪除,然后將其插入新位置的列表中即可。

最佳N實際取決於應用程序。

如果您只是想檢查沿軸的單個點,則排序列表會很好。

用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的索引。在該范圍內的任何內容都會在排序列表中的這兩個索引之間發生。


附加信息:

當前,“底部”是元素高度,而不是底部。 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM