簡體   English   中英

您將如何僅使用 vanilla JavaScript 和 HTML canvas 來實現圓的碰撞檢測?

[英]How would you implement collision detection of circles using only vanilla JavaScript and HTML canvas?

我是編程新手,所以我可能會搞砸一些事情,但我認為你會制作一個 class 來繪制圓形和/或正方形,然后繼續調用該 class 的新實例。 但我不知道如何 go 這樣做。

圓-圓碰撞檢測算法肯定是最容易實現的,因為從圓心到圓外任意點的距離相等。

為此,我們可以利用勾股定理,它說在直角三角形中,放在三角形兩個短邊上的正方形面積之和等於放在最長邊上的正方形面積。 如果我們知道它的面積——以及它是正方形的事實——我們知道我們可以簡單地計算平方根來得到它的邊長。

雖然這聽起來有點抽象,但如果你看一下下面的圖片,它就會變得更加明顯:

在這里,您會看到兩個圓圈 - 圓圈 A 和圓圈 B - 以及在它們之間放置一個直角三角形,因此最長邊(紅色)接觸圓圈的中心點。 你注意到紅色的一面圓圈之間的距離。 如果我們計算紅色邊並檢查它是否小於圓 A 和圓 B 的半徑之和,我們就知道它們發生了碰撞!

所以根據勾股定理,我們需要在藍邊和綠邊各放一個正方形,求和面積的平方根。

要在藍色邊上放置一個“虛擬”正方形,我們需要知道它的實際長度,為此我們只需從圓 B 中減去圓 A 的垂直 position - 反之亦然。 例如

let sideA = circleB.y - circleA.y;

根據實際的 position 這可能會導致負數,因此我們將計算包裝在對返回絕對正值的Math.abs()的調用中。

let sideA = Math.abs(circleB.y - circleA.y);

現在使用圓圈的水平 position 對綠色側執行相同操作:

let sideB = Math.abs(circleB.x - circleA.x);

計算面積,求和並取平方根:

let distance = Math.sqrt(Math.pow(sideA, 2) + Math.pow(sideB, 2));

而已!

這是一個實際的例子:

 class Circle { constructor(x, y, radius, name) { this.x = x; this.y = y; this.radius = radius; this.name = name; } } let canvas = document.getElementById('canvas'); let ctx = canvas.getContext('2d'); let circleA = new Circle(50, 50, 35, 'Circle A'); let circleB = new Circle(200, 110, 35, 'Circle B'); let circleC = new Circle(110, 50, 35, 'Circle C'); let circles = [circleA, circleB, circleC]; ctx.textAlign = 'center'; for (let a = 0; a < circles.length; a++) { ctx.beginPath(); ctx.arc(circles[a].x, circles[a].y, circles[a].radius, 0, 2 * Math.PI); ctx.stroke(); ctx.fillText(circles[a].name, circles[a].x, circles[a].y); } function checkCollision(circle1, circle2) { let sideA = Math.abs(circle1.y - circle2.y); let sideB = Math.abs(circle1.x - circle2.x); let distance = Math.sqrt(Math.pow(sideA, 2) + Math.pow(sideB, 2)); return distance <= circle1.radius + circle2.radius; } let result = document.getElementById('result'); result.innerText = 'Circle A touches Circle B: ' + checkCollision(circleA, circleB) result.innerText += '\nCircle A touches Circle C: ' + checkCollision(circleA, circleC)
 <canvas id="canvas"></canvas><br> <span id="result"></span>

暫無
暫無

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

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