Javascript 确定选择框是否位于旋转的矩形上

Javascript 确定选择框是否位于旋转的矩形上,javascript,canvas,html5-canvas,trigonometry,Javascript,Canvas,Html5 Canvas,Trigonometry,我有一个矩形类用于绘制HTML画布。它有一个在其绘制方法中应用的旋转属性。如果用户在画布中拖动,将绘制一个选择框。当矩形位于选择框内时,如何使用math将矩形的active属性设置为true?这是我在另一种语言和上下文中遇到的问题,因此我在那里没有所有Canvas方法可用(例如,isPointInPath) 我发现了一篇关于查找的StackOverflow帖子,我正在矩形方法checkHit中实现它。但是,它不考虑选择框。它只是在看鼠标X&Y,它仍然处于关闭状态。浅蓝色圆点是矩形旋转的原点。如果

我有一个矩形类用于绘制HTML画布。它有一个在其绘制方法中应用的旋转属性。如果用户在画布中拖动,将绘制一个选择框。当矩形位于选择框内时,如何使用math将矩形的
active
属性设置为
true
?这是我在另一种语言和上下文中遇到的问题,因此我在那里没有所有Canvas方法可用(例如,
isPointInPath

我发现了一篇关于查找的StackOverflow帖子,我正在矩形方法
checkHit
中实现它。但是,它不考虑选择框。它只是在看鼠标X&Y,它仍然处于关闭状态。浅蓝色圆点是矩形旋转的原点。如果有什么不清楚的地方,请告诉我。多谢各位

类矩形
{
构造器(x、y、宽度、高度、旋转){
这个.x=x;
这个。y=y;
高度=高度;
这个。宽度=宽度;
this.xOffset=this.x+this.width/2;
this.yOffset=this.y+((this.y+this.height)/2);
这个旋转=旋转;
this.active=false;
}
checkHit()
{
//将鼠标点值转换为原点
设originX=this.xOffset;
让originY=this.yOffset;
设dx=marquee[2]-originX;
设dy=marquee[3]-原创;
//点与矩形中心之间的距离
设h1=Math.sqrt(dx*dx+dy*dy);
设currA=Math.atan2(dy,dx);
//相对于矩形原点旋转的点的角度
设newA=currA-this.rotation;
//旋转时鼠标点的新位置
设x2=Math.cos(newA)*h1;
设y2=Math.sin(newA)*h1;
//检查相对于矩形中心的位置
如果(x2>-0.5*this.width&&x2<0.5*this.width&&y2>-0.5*this.height&&y2<0.5*this.height){
this.active=true;
}否则{
this.active=false;
}
}
画()
{
ctx.save();
ctx.translate(this.xOffset,this.yOffset);
ctx.fillStyle='rgba(255255,1)';
ctx.beginPath();
ctx.arc(0,0,3,0,2*Math.PI,真);
ctx.fill();
ctx.rotate(this.rotation*Math.PI/180);
ctx.translate(-this.xOffset,-this.yOffset);
如果(此.active)
{
ctx.fillStyle='rgba(255,0,0,0.5)';
}否则{
ctx.fillStyle='rgba(0,0255,0.5)';
}
ctx.beginPath();
ctx.fillRect(this.x,this.y,this.width,this.y+this.height);
ctx.closePath();
ctx.stroke();
ctx.restore();
}
}
var canvas=document.getElementById(“canvas”);
var ctx=canvas.getContext(“2d”);
var-raf;
var rect=新矩形(50,50,90,30,45);
var marquee=[-3,-3,-3];
var BB=canvas.getBoundingClientRect();
var offsetX=BB.left;
var offsetY=BB.top;
var start_x,start_y;
让我们画=()=>{
ctx.clearRect(0,0,canvas.width,canvas.height);
//直线旋转+=1;
rect.draw();
ctx.fillStyle=“rgba(200200255,0.5)”;
ctx.fillRect(parseInt(选框[0])、parseInt(选框[1])、parseInt(选框[2])、parseInt(选框[3]))
ctx.strokeStyle=“白色”
ctx.lineWidth=1;
ctx.rect(parseInt(选框[0])、parseInt(选框[1])、parseInt(选框[2])、parseInt(选框[3]))
ctx.stroke()
raf=window.requestAnimationFrame(绘制);
}
让dragStart=(e)=>
{
start_x=parseInt(e.clientX-offsetX);
start_y=parseInt(例如clientY-offsetY);
选框=[start_x,start_y,0,0];
canvas.addEventListener(“mousemove”,拖动);
}
让拖动=(e)=>
{
设mouseX=parseInt(e.clientX-offsetX);
设mouseY=parseInt(e.clientY-offsetY);
选取框[2]=鼠标-开始x;
选取框[3]=鼠标-开始;
rect.checkHit();
}
设dragEnd=(e)=>
{
选框=[-10,-10,-10];
canvas.removeEventListener(“mousemove”,拖动);
}
canvas.addEventListener('mousedown',dragStart);
canvas.addEventListener('mouseup',dragEnd);
raf=window.requestAnimationFrame(绘制)
正文
{
保证金:0;
}
#帆布
{
宽度:360px;
高度:180像素;
边框:1px纯灰;
背景颜色:灰色;
}
凸多边形是否重叠 矩形是凸多边形

矩形
选框
各有4个点(角),定义了连接点的4条边(线段)

此解决方案适用于所有具有3条或更多边的凸不规则多边形

点和边的顺序必须为顺时针CW或顺时针CCW计数

测试点 如果一个多边形的任何点位于另一个多边形内,则它们必须重叠。请参见示例函数
isInside

若要检查点是否在多边形内,请获取的叉积为,边起点为向量,边起点为向量

如果所有叉积>=0(在的左侧),则存在重叠(对于CW多边形)。若多边形为逆时针,则若所有叉积均为0

不要传递长度为==0的边的多边形,否则将不起作用

补充 我添加了函数
Rectangle.toPoints
,该函数变换矩形并返回一组4个点(角点)

例子 示例是使用上述方法工作的代码的副本

canvas.addEventListener('mousedown',dragStart);
canvas.addEventListener('mouseup',dragEnd);
请求动画帧(绘制);
常量点=(x=0,y=0)=>({x,y,set(x,y){this.x=x;this.y=y});
常量行=(p1,p2)=>({p1,p2});
常量选择器={points:[Point(),Point(),Point(),Point()]}
选择器。行=[
行(选择器点[0],选择器点[1]),
行(选择器点[1],选择器点[2]),
行(选择器点[2],选择器点[3]),
行(选择器点[3],选择器点[0])
];
常量矩形={points:[Point(),Point(),Point(),Point()]}
矩形。直线=[
直线(矩形点[0],矩形点[1]),
直线(矩形点[1],矩形点[2]),
直线(矩形点[2],rec