如何判斷一個點在旋轉後的矩形中
阿新 • • 發佈:2020-06-28
前言
最近在做的一款遊戲中,用到點與旋轉矩形的判定來獲得一個選中的物體。在此做個記錄
如圖所示,黃色的顏料屏是旋轉的,如果不做處理直接判斷點是否在矩形中,那麼點選紅點的位置會判定為選中物體。顯然這是不對的。
如果物體沒有旋轉,判斷方法就很簡單了。
static isPositionInRect(point: cc.Vec2, rect: cc.Rect) { return point.x <= rect.x + rect.width/2 && point.x >= rect.x - rect.width/2 && point.y <= rect.y + rect.height /2&& point.y >= rect.y - rect.height /2; }
我這個矩形錨點為為(0.5,0.5),如果錨點不是(0.5,0.5)可以自行修改。
但是判斷一個點在旋轉後的矩形中就沒有這麼簡單了。
怎麼判斷呢?
- 首先我想到的是WebGL程式設計指南第92頁講到的內容。(x,y)在旋轉O角度後得到(x2,y2)
x2 = x * cos(O) - y * sin(O)
y2 = x * sin(O) + y * cos(O)
-
得到了這個公式,我們接下來就是要旋轉觸控點了。不過這個時候我們要確定要繞哪個點旋轉,是座標系的原點嗎?不是的,而是我們要碰撞的矩形的中心點,因為矩形是繞這個點旋轉的。
-
最終我們得到一個完整的判定函式
/** * 判斷點是否在旋轉後的矩形中 * @param point 觸控點的座標 * @param node 碰撞節點,錨點必須為(0.5,0.5) */ static isPosInRotationRect(point: cc.Vec2, node: cc.Node) { let hw = node.width / 2; let hh = node.height / 2 let O = node.angle; let center = node.position; let X = point.x let Y = point.y let r = -O * (Math.PI / 180) let nTempX = center.x + (X - center.x) * Math.cos(r) - (Y - center.y) * Math.sin(r); let nTempY = center.y + (X - center.x) * Math.sin(r) + (Y - center.y) * Math.cos(r); if (nTempX > center.x - hw && nTempX < center.x + hw && nTempY > center.y - hh && nTempY < center.y + hh) { return true; } return false }
- 這裡邊需要注意的是角度O我們用的是反方向的。因為我們判定使用的矩形的座標和寬高是未旋轉的,也就是下圖的紅色框。所以我們的觸控點需要反方向旋轉角度O才能使用之前的判定方法。
當你點選了1的位置,經過反方向的旋轉後會到達2的位置,然後與紅色框的矩形判斷,才會得到正確的判定結果。如果觸控點旋轉的角度與矩形旋轉的角度相同,那麼點選1的位置就會向左移動,也會判定為選中,就會得到不正確的結果了。
結語
以上就是如何判定一個點在旋轉後的矩形中的一種方式。在網上搜索的時候發現有很多種實現方式,但是感覺都比較繁瑣。有興趣的小夥伴可以自己去研究研究。不過用我這個判定函式已經可以達到目的了。
參考
- https://www.jianshu.com/p/bde70668b1bc
- https://www.deanhan.cn/js-point-in-rotate-rect.html
- https://blog.csdn.net/C_panpan/article/details/50476965?utm_source=blogxgwz1
長按下方二維碼,關注《微笑遊戲》公眾號,獲取更多精彩內容。
歡迎掃碼關注公眾號《微笑遊戲》,瀏覽更多內容。