Detect if a rotated rectangle is in the canvas

I have a rectangle that I rotated through ctx.rotateand an arc. I want to check if any part of the rectangle is inside the specified arc. For example, this should be true:

Arc crosses a rectangle

I tried to use isPointInPath, but the “point” I am looking for is not the actual coordinates of the rectangle, but non-rotating (Actual green, isPointInPathchecks the blue color):

isPointInPath skips point

Here's JS:

var canvas = document.querySelector('#canvas'),
    height = canvas.height = canvas.clientHeight,
    width = canvas.width = canvas.clientWidth,
    ctx = canvas.getContext('2d');
canvas.width = canvas.height = 512;

var shipx = 400,
    shipy = 256;

function moveShip() {
    ctx.fillStyle = '#000';
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    ctx.save();
    ctx.translate(shipx, shipy);
    ctx.rotate(3.66);
    ctx.fillStyle = 'green';
    ctx.fillRect(0, 0, 80, 20);
    ctx.restore();

    // This is what isPointInPath is seeing
    ctx.fillStyle = 'rgba(0,0,255,0.5)';
    ctx.fillRect(shipx, shipy, 80, 20);

    ctx.fillStyle = 'rgba(255,0,0,0.5)';
    ctx.beginPath();
    ctx.moveTo(256, 256);
    ctx.arc(256, 256, 100, -20 * Math.PI / 180, 90 * Math.PI / 180);
    ctx.lineTo(256, 256);

    if (ctx.isPointInPath(shipx, shipy) || ctx.isPointInPath(shipx + 20, shipy + 20)) {
        // This *should* trigger
        ctx.fillStyle = 'rgba(0,0,255,0.5)';
    };

    ctx.fill();
}

moveShip();

Jsbin for live code fun

+4
source share
1 answer

, , :

var dx = arc.x - ship.x,
    dy = arc.y - ship.y;

ctx.rotate( -ship.rot );

ctx.beginPath();
ctx.moveTo( 0, 0 );
ctx.arc( 0, 0, arc.r, arc.sRot, arc.eRot );

if( ctx.isPointInPath( dx, dy ) ||
    ctx.isPointInPath( dx + rect.w, dy ) ||
    ctx.isPointInPath( dx, dy + rect.h ) ||
    ctx.isPointInPath( dx + rect.w, dy + rect.h ) )

    collisionIsTrue();
+4

Source: https://habr.com/ru/post/1613120/


All Articles