簡體   English   中英

當正方形完全在圓內時檢測碰撞

[英]Detect collision when a square is totally inside a circle

我有這個 function 來檢測圓形和方形之間的碰撞

function detectCollision(square, circle) {
    let distX = Math.abs(circle.x - square.x);
    let distY = Math.abs(circle.y - square.y);

    if (distX > square.w / 2 + circle.r) return false;
    if (distY > square.w / 2 + circle.r) return false;

    if (distX <= square.w / 2) return true;
    if (distY <= square.w / 2) return true;

    let dx = distX - square.w / 2;
    let dy = distY - square.w / 2;
    return dx * dx + dy * dy <= circle.r * circle.r;
  }

它工作得很好,但我需要另外,function 檢測正方形是否完全在圓內

在此處輸入圖像描述

就像添加:

if (square is totally inside) console.log("its inside!");

一種方法是檢查正方形的角 go 是否分別在圓的 4 個象限中的任何一個之外。 為了檢查我們是否可以用 sin 和 cos 計算圓周上的點,並根據象限檢查它們是否在外面:

 <canvas height='500' width='500'></canvas>

 <script>
    const canvas = document.querySelector('canvas');
    const ctx = canvas.getContext('2d');

    let circle = {
        x: 200,
        y: 200,
        r: 100
    };

    let square = {
        x: 200,
        y: 120,
        side: 50
    };

    ctx.beginPath();
    ctx.arc(circle.x, circle.y, circle.r, 0, 2 * Math.PI);
    ctx.stroke();

    ctx.beginPath();
    ctx.rect(square.x, square.y, square.side, square.side);
    ctx.stroke();

    function detectContains(circle, square) {

        let sw = square.side;
        for(let deg=0; deg<=360; ++deg) {
            let x = circle.x + circle.r * Math.sin(Math.PI * 2 * deg / 360)
            let y = circle.y - circle.r * Math.cos(Math.PI * 2 * deg / 360)
            
            if(deg >= 0 && deg <= 90) {
                if(square.x+sw > x && square.y < y)
                    return false;
            } else if(deg >= 90 && deg <= 180) {
                if(square.x+sw > x && square.y+sw > y)
                    return false;
            } else if(deg >= 180 && deg <= 270) {
                if(square.x > x && square.y+sw > y)
                    return false;
            } else {
                if(square.x < x && square.y < y) {
                    return false;
                }
            }
            
        }

        return true;
    }

    console.log(detectContains(circle, square))


</script>

PS:這是我最近在圖形編程方面學到的東西,我認為解決方案可以更好。 一旦我得到更好的解決方案,我會嘗試更新。

我會檢查到正方形角落的距離,看看它們都小於半徑。

 let canvas = document.getElementById("canvas"); let ctx = canvas.getContext("2d"); canvas.width = 300; canvas.height = 300; let canvasBounds = canvas.getBoundingClientRect(); class Rect { constructor(x, y, w, h) { this.x = x; this.y = y; this.w = w; this.h = h; this.c = "blue"; } draw() { ctx.strokeStyle = this.c; ctx.strokeRect(this.x, this.y, this.w, this.h); } } class Circle { constructor(x, y, r) { this.x = x; this.y = y; this.r = r; } draw() { ctx.strokeStyle = "black"; ctx.beginPath(); ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2); ctx.stroke(); } } let rect = new Rect(100, 100, 40, 40); let circle = new Circle(100, 100, 75); function detectCollision(square, circle) { let distX = Math.abs(circle.x - (square.x + square.w / 2)); let distY = Math.abs(circle.y - (square.y + square.h / 2)); let dx = distX - square.w / 2; let dy = distY - square.h / 2; if ( distance(square.x, square.y, circle) < circle.r && distance(square.x + square.w, square.y, circle) < circle.r && distance(square.x + square.w, square.y + square.h, circle) < circle.r && distance(square.x, square.y + square.h, circle) < circle.r ) { console.log("it's totally inside") } else if (dx * dx + dy * dy <= circle.r * circle.r) { console.log("it's not totally inside") } else { console.log("there's no collision") } } function distance(ptX, ptY, circle) { return Math.hypot(ptX - circle.x, ptY - circle.y); } canvas.addEventListener("mousemove", (e) => { rect.x = ex - canvasBounds.x - rect.w / 2; rect.y = ey - canvasBounds.y - rect.h / 2; }); function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); rect.draw(); circle.draw(); detectCollision(rect, circle); requestAnimationFrame(animate); } animate();
 <canvas id="canvas"></canvas>

您可能需要將其設為全屏才能看到圓圈

感謝您的回答,我沒有考慮過4個角,但我想出了另一種更簡單的方法,從圓的原點到正方形原點的距離加上一點(正方形的“半徑”)必須小於圓的半徑。

 let mysquare = { x: 200, y: 200, w: 50 }; let mycircle = { x: 110, y: 110, r: 100 }; function setup() { createCanvas(512, 512); rectMode(CENTER); } function draw() { clear(); fill(255); circle(mycircle.x, mycircle.y, mycircle.r * 2); mysquare.x = mouseX; mysquare.y = mouseY; if (isInside(mysquare, mycircle)) fill(255, 0, 0); square(mysquare.x, mysquare.y, mysquare.w); } function isInside(square, circle) { let dx = Math.abs(circle.x - square.x) + square.w/2; let dy = Math.abs(circle.y - square.y) + square.w/2; return dx ** 2 + dy ** 2 <= circle.r ** 2; }
 <script src="https://cdn.jsdelivr.net/npm/p5@1.4.0/lib/p5.min.js"></script>

暫無
暫無

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

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