Skip to content Skip to sidebar Skip to footer

How To Test If A Point Is In A Rectangle Area Which Rotates An Angle?

I am trying to test if a point is inside a rectangle area that rotates an angle around (x, y), like the image below. This is language agnostic problem but I am working with HTML5 c

Solution 1:

Assuming that you know how to check whether a dot is in the rectangle the approach to solution is to rotate and translate everything (dot and rectangle) to "normalized" coordinating system (Cartesian coordinate system that is familiar to us) and then to check it trivially.

For more information you should check Affine transformations. The good link where you could start is

http://www.mathworks.com/discovery/affine-transformation.html?requestedDomain=www.mathworks.com

Solution 2:

As you can see on this Codepen i did (to detect 2 rotate rect collide).

You have to check the 2 projections of your point (in my case, the 4 points of a rect) and look if the projections are on the other rect

You have to handle the same thing but only for a point and a rect instead of 2 rects

All projections are not collidingenter image description here

All projections are collidingenter image description here

required code for codepen link

Solution 3:

The browser always report mouse position untransformed (==unrotated).

So to test if the mouse is inside a rotated rectangle, you can:

  • Get the unrotated mouse position from the mouse event (relative to the canvas).
  • Rotate the mouse x,y versus the rotation point by the same rotation as the rectangle.
  • Test if the mouse is inside the rectangle. Now that both the rect and the mouse position have been similarly rotated, you can just test as if the mouse and rect were unrotated.

Annotated code and a Demo:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
functionreOffset(){
    varBB=canvas.getBoundingClientRect();
    offsetX=BB.left;
    offsetY=BB.top;        
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }

var isDown=false;
var startX,startY;

var rect=makeRect(50,20,35,20,Math.PI/4,60,30);

functionmakeRect(x,y,w,h,angle,rotationPointX,rotationPointY){
    return({
        x:x,y:y,width:w,height:h,
        rotation:angle,rotationPoint:{x:rotationPointX,y:rotationPointY},
    });
}

drawRect(rect);

$("#canvas").mousedown(function(e){handleMouseDown(e);});

functiondrawRect(r){
    var rx=r.rotationPoint.x;
    var ry=r.rotationPoint.y;
    // demo only, draw the rotation pointdot(rx,ry,'blue');
    // draw the rotated rect
    ctx.translate(rx,ry);
    ctx.rotate(r.rotation);
    ctx.strokeRect(rect.x-rx,rect.y-ry,r.width,r.height);
    // always clean up, undo the transformations (in reverse order)
    ctx.rotate(-r.rotation);
    ctx.translate(-rx,-ry);
}

functiondot(x,y,fill){
    ctx.fillStyle=fill;
    ctx.beginPath();
    ctx.arc(x,y,3,0,Math.PI*2);
    ctx.fill();
}

functionhandleMouseDown(e){
    // tell the browser we're handling this event
    e.preventDefault();
    e.stopPropagation();
    // get mouse position relative to canvas
    mouseX=parseInt(e.clientX-offsetX);
    mouseY=parseInt(e.clientY-offsetY);
    // rotate the mouse position versus the rotationPointvar dx=mouseX-rect.rotationPoint.x;
    var dy=mouseY-rect.rotationPoint.y;
    var mouseAngle=Math.atan2(dy,dx);
    var mouseDistance=Math.sqrt(dx*dx+dy*dy);
    var rotatedMouseX=rect.rotationPoint.x+mouseDistance*Math.cos(mouseAngle-rect.rotation);
    var rotatedMouseY=rect.rotationPoint.y+mouseDistance*Math.sin(mouseAngle-rect.rotation);
    // test if rotated mouse is inside rotated rectvar mouseIsInside=rotatedMouseX>rect.x &&
        rotatedMouseX<rect.x+rect.width &&
        rotatedMouseY>rect.y &&
        rotatedMouseY<rect.y+rect.height;
    // draw a dot at the unrotated mouse position// green if inside rect, otherwise redvar hitColor=mouseIsInside?'green':'red';
    dot(mouseX,mouseY,hitColor);
}
body{ background-color: ivory; }
#canvas{border:1px solid red; }
<scriptsrc="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script><h4>Clicks inside rect are green, otherwise red.</h4><canvasid="canvas"width=512height=512></canvas>

Post a Comment for "How To Test If A Point Is In A Rectangle Area Which Rotates An Angle?"