Javascript HTML5画布与N2的夹角为90度
我试图让绿色三角形围绕其中心旋转,并使其朝向鼠标位置。我能够完成这项工作,您可以在此处查看完整的代码和结果: 考虑以下代码行:Javascript HTML5画布与N2的夹角为90度,javascript,html,canvas,html5-canvas,Javascript,Html,Canvas,Html5 Canvas,我试图让绿色三角形围绕其中心旋转,并使其朝向鼠标位置。我能够完成这项工作,您可以在此处查看完整的代码和结果: 考虑以下代码行: r = Math.atan2(mouseY - centerY, mouseX - centerX) ctx.rotate(r + Math.PI/2) 我在角度计算中随意添加了Math.PI/2,因为如果没有它,旋转似乎偏离了90度(通过检查)。我想更好地理解atan2计算的坐标系,这样我就可以证明将角度偏移90度的原因(并希望简化代码) 编辑: 据我所
r = Math.atan2(mouseY - centerY, mouseX - centerX)
ctx.rotate(r + Math.PI/2)
我在角度计算中随意添加了Math.PI/2
,因为如果没有它,旋转似乎偏离了90度(通过检查)。我想更好地理解atan2计算的坐标系,这样我就可以证明将角度偏移90度的原因(并希望简化代码)
编辑:
据我所知,Math.atan2
正在测量蓝色图示的角度。旋转两个蓝色角度的三角形不应该使其朝向鼠标指针(橙色点)吗?显然不是,因为它是同一个角度,而且它们是两个不同的方向,但我似乎无法向自己证明这一点
当你在数学课上做弧切线时,你通常要处理的是一个向上增加的y轴。然而,在大多数计算机图形系统中,包括画布图形,y向下增加。[删除错误声明] 编辑:我必须承认我以前写的是错误的,原因有两个:
- 轴方向的变化将通过增加π而不是π/2来补偿
- canvas context
函数顺时针旋转正角度,仅此一项就可以补偿y轴的翻转rotate
我在Plunker中使用了你的代码副本,现在我意识到90°旋转只是补偿了你正在绘制的图形图像的起始方向。如果箭头开始指向右侧,而不是笔直向上,则无需添加π/2。画布上的坐标系以0°指向右侧。这意味着您想要指向“向上”的任何东西最初都必须画对 在这种情况下,您只需更改此图形: 到 指向“上”0° 你可以把数学还原到你期望的样子
var ctx=c.getContext(“2d”),img=new Image;
img.onload=go;img.src=”https://i.stack.imgur.com/Yj9DU.jpg";
功能图(pos){
var cx=c.宽度>>1,
cy=c.高度>>1,
角度=数学atan2(位置y-cy,位置x-cx);
setTransform(1,0,0,1,cx,cy);
ctx.旋转(角度);
ctx.drawImage(img,-img.width>>1,-img.height>>1);
}
函数go(){
ctx.globalCompositeOperation=“复制”;
window.onmousemove=函数(e){draw({x:e.clientX,y:e.clientY}}
}
html,正文{margin:0;背景:#ccc}
#c{背景:#fff}
这是因为Math.atan2
是如何工作的
:
这是正X轴与点(X,y)之间的逆时针角度,以弧度为单位测量。在上图中,正X轴是从连接点到最右侧位置的水平段 为了更清楚,这里是这个图的一个交互式版本,其中x,y值被转换为[-1~1]值
const ctx=canvas.getContext('2d'),
w=画布宽度,
h=画布高度,
半径=0.3;
ctx.textAlign='中心';
canvas.onmousemove=canvas.onclick=e=>{
//偏移鼠标值,使其相对于画布中心
绘制(如(e.offsetX),如(e.offsetY));
}
抽签(0,0);
函数图(x,y){
清除();
拉丝叉();
抽绳点(x,y);
提取点(x,y);
常数角=数学常数2(y,x);
牵引角;
扭角;
}
函数clear(){
ctx.clearRect(0,0,w,h);
}
函数drawCross(){
ctx.lineWidth=1;
ctx.beginPath();
ctx.moveTo(s(0),s(-1));
ctx.lineTo(s(0),s(1));
移动到(s(-1),s(0));
ctx.lineTo(s(0),s(0));
ctx.strokeStyle=ctx.fillStyle='#2e404f';
ctx.stroke();
//正X轴
ctx.lineWidth=3;
ctx.beginPath();
ctx.moveTo(s(0),s(0));
ctx.lineTo(s(1),s(0);;
ctx.stroke();
ctx.lineWidth=1;
ctx.font='20px/1无衬线';
ctx.fillText('+X',s(1)-20,s(0)-10);
}
功能提取点(x,y){
ctx.beginPath();
弧(s(x),s(y),10,0,数学π*2);
ctx.fillStyle='红色';
ctx.fill();
ctx.font='12px/1无衬线';
ctx.fillText(`x:${x.toFixed(2)}y:${y.toFixed(2)}`,s(x),s(y)-15);
}
函数drawLineToPoint(x,y){
ctx.beginPath();
ctx.moveTo(s(0),s(0));
ctx.lineTo(s(x),s(y));
ctx.strokeStyle=‘红色’;
ctx.setLineDash([5,5]);
ctx.stroke();
ctx.setLineDash([0]);
}
函数drawAngle(角度){
ctx.beginPath();
ctx.移动到(s(半径),s(0));
ctx.弧(s(0),s(0),半径*w/2,
0,//“圆弧”法也从正X轴(3点钟)开始
角度,
true//Math.atan2返回逆时针角度
);
ctx.strokeStyle=ctx.fillStyle='blue';
ctx.stroke();
ctx.font='20px/1无衬线';
ctx.fillText('∂: ' + 固定角度(2),s(0),s(0));
}
//以下方法将添加w/2偏移
//因为画布坐标在左上角设置了0,0
//从[-1~1]转换为px
函数s(值){
返回值*w/2+(w/2);
}
//从px转换为[-1~1]
函数为(值){
返回值(值-w/2)/(w/2);
}
我遇到了同样的问题,并能够通过以下轴“技巧”实现所需的结果:
// Default usage (works fine if your image / shape points to the RIGHT)
let angle = Math.atan2(delta_y, delta_x);
// 'Tricky' usage (works fine if your image / shape points to the LEFT)
let angle = Math.atan2(delta_y, -delta_x);
// 'Tricky' usage (works fine if your image / shape points to the BOTTOM)
let angle = Math.atan2(delta_x, delta_y);
// 'Tricky' usage (works fine if your image / shape points to the TOP)
let angle = Math.atan2(delta_x, -delta_y);
你是说y轴吗?谢谢。那么,有没有办法进行测量以避免增加90度?你可以尝试
Math.atan2(centerY-mouseY,mouseX-centerX)
。我已经尝试过了,不会产生预期的行为,或者我自己会先尝试,但你的代码笔是只读的。“这是正X轴与点(X,y)之间的逆时针角度,以弧度为单位。”。你的图像是旋转的,所以它指向正的Y轴,因此你需要添加Math.PI/2
@kaido我有