编辑:我做了一个视频来解释我不想做的事情https://youtu.be/-6I503Urhvg
目标:在旋转后在画布上查找初始X,初始Y,最终X和最终Y点。
问题:公式在我的代码中不起作用,我需要找出我做错了什么。
问题:我想知道我使用的公式是否正确以及如何正确使用它来查找目标。
我正在使用的公式是:
nX = x * Math.cos(-angle) - y * Math.sin(-angle)
nY = x * sin(-angle)+ y * Math.cos(-angle)
公式似乎几乎可以工作,因为它紧跟矢量的旋转。我正在使用小方块来看看公式给我的位置是什么。
代码中的公式:
this.nix = this.ix * Math.cos(-(rotation * (Math.PI / 180))) - this.iy * Math.sin(-(rotation * (Math.PI / 180)));
this.niy = this.ix * Math.sin(-(rotation * (Math.PI / 180))) + this.iy * Math.cos(-(rotation * (Math.PI / 180)));
this.nfx = this.fx * Math.cos(-(rotation * (Math.PI / 180))) - this.fy * Math.sin(-(rotation * (Math.PI / 180)));
this.nfy = this.fx * Math.sin(-(rotation * (Math.PI / 180))) + this.fy * Math.cos(-(rotation * (Math.PI / 180)));
ctx.fillRect(this.nix,this.niy,5,5);
ctx.fillRect(this.nfx,this.nfy,5,5);
/*GLOBAL*/var check,lineSquare,rotation,lineRotate;
rotation = 0;
check = false;
lineRotate = false;
function lineRotateBtn(){
lineRotate = true;
}
function setRotate(){
var intervalo2 = setInterval(function(){rotation += 0.01;},1000/60);
}
function load() {
var canvas = document.getElementById('box');
var ctx = canvas.getContext('2d');
function player(x, y, width) {
this.x = x;
this.y = y;
this.width = width;
this.vx = 3;
this.vy = 3;
this.up = false;
this.down = false;
this.left = false;
this.right = false;
this.drawn = function () {
ctx.fillStyle = "black";
ctx.fillRect(this.x, this.y, this.width, this.width);
if (this.up) {
this.y -= this.vy;
}
if (this.down) {
this.y += this.vy;
}
if (this.left) {
this.x -= this.vx;
}
if (this.right) {
this.x += this.vx;
}
}
}
var players = new player(100, 100, 20);
var keyUp, keyDown, keyLeft, keyRight;
keyUp = 87;
keyDown = 83;
keyLeft = 65;
keyRight = 68;
window.addEventListener("keydown", checkKeyDown, false);
function checkKeyDown(event) {
if (event.keyCode == keyUp) {
players.up = true;
} else if (event.keyCode == keyDown) {
players.down = true;
} else if (event.keyCode == keyLeft) {
players.left = true;
} else if (event.keyCode == keyRight) {
players.right = true;
}
}
window.addEventListener("keyup", checkKeyUp, false);
function checkKeyUp(event) {
if (event.keyCode == keyUp) {
players.up = false;
} else if (event.keyCode == keyDown) {
players.down = false;
} else if (event.keyCode == keyLeft) {
players.left = false;
} else if (event.keyCode == keyRight) {
players.right = false;
}
}
document.onmousemove = mouseMove;
function mouseMove(event) {
event = event || canvas.event
mouseX = event.pageX;
mouseY = event.pageY;
mouseX = mouseX - 11;
mouseY = mouseY - 13;
document.getElementById('test2').innerHTML = mouseX + " " + mouseY;
}
function line(ix, iy, fx, fy) {
this.ix = ix;
this.iy = iy;
this.fx = fx;
this.fy = fy;
this.update = function () {
this.nix = this.ix * Math.cos(-(rotation * (Math.PI / 180))) - this.iy * Math.sin(-(rotation * (Math.PI / 180)));
this.niy = this.ix * Math.sin(-(rotation * (Math.PI / 180))) + this.iy * Math.cos(-(rotation * (Math.PI / 180)));
this.nfx = this.fx * Math.cos(-(rotation * (Math.PI / 180))) - this.fy * Math.sin(-(rotation * (Math.PI / 180)));
this.nfy = this.fx * Math.sin(-(rotation * (Math.PI / 180))) + this.fy * Math.cos(-(rotation * (Math.PI / 180)));
ctx.fillRect(this.nix,this.niy,5,5);
ctx.fillRect(this.nfx,this.nfy,5,5);
var v1 = {}; //Player
v1.vx = players.vx;
v1.vy = players.vy;
v1.m = Math.sqrt(v1.vx * v1.vx + v1.vy * v1.vy);
v1.dx = v1.vx / v1.m;
v1.dy = v1.vy / v1.m;
var v2 = {ln: {}}; //Line;
v2.ix = this.ix;
v2.iy = this.iy;
v2.fx = this.fx;
v2.fy = this.fy;
v2.vx = v2.fx - v2.ix;
v2.vy = v2.fy - v2.iy;
v2.m = Math.sqrt(v2.vx * v2.vx + v2.vy * v2.vy);v2.dx = v2.vx / v2.m;
v2.dy = v2.vy / v2.m;
v2.ln.vx = v2.vy;
v2.ln.vy = -v2.vx;v2.ln.dx = v2.ln.vx / v2.m || 0;
v2.ln.dy = v2.ln.vy / v2.m || 0;
var v3 = {};
v3.vx = v2.ix - players.x;v3.vy = v2.iy - players.y;
var dp1 = v3.vx * v2.dx + v3.vy * v2.dy;
var dp2 = v3.vx * v2.ln.dx + v3.vy * v2.ln.dy;
if (dp1 > -v2.m && dp1 < 0) {
if (dp2 <= 2 && dp2 >= 0) {
console.log('colision');
if (players.up && players.right){
players.x -= players.vx*2;
players.y += players.vy*2;
}
players.x -= players.vx;
players.y += players.vy;
}
if (dp2 < -1 && dp2 >= -4) {
console.log('colision');
if (players.down && players.left){
players.x -= players.vx*2;
players.y += players.vy*2;
}
players.x += players.vx;
players.y -= players.vy;
}
}
ctx.save();
ctx.translate(this.ix + v2.vx / 2, this.iy + v2.vy / 2);
ctx.rotate(rotation * (Math.PI / 180));
ctx.translate(-(this.ix + v2.vx / 2), -(this.iy + v2.vy / 2));
ctx.beginPath();
ctx.moveTo(this.ix, this.iy);
ctx.lineTo(this.fx, this.fy);
ctx.stroke();
ctx.restore();
document.getElementById('test1').innerHTML = "dotProduct1: " + dp1 + "v2.m: " + (-v2.m) + "<br>" + dp2;
}
}
var linez = new line(300,300,400,400);
var intervalo = setInterval(animation, 1000 / 60);
function animation() {
check = true;
ctx.clearRect(0, 0, canvas.width, canvas.height);
players.drawn();
linez.update();
}
}
&#13;
#box {
border: 1px solid black;
}
#button {
border: none;
background-color: gray;
width: 70;
height: 50;
}
canvas {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
html {
background-color: white;
color: black;
font-family: courier new;
}
&#13;
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="css/estilo.css">
<script src="js/main.js"></script>
</head>
<body onload="load()">
<canvas id="box" width="1330" height="500"></canvas>
<button onclick="setRotate()">Rotate</button>
<h2 id="test1"></h2>
<h2 id="test2"></h2>
</body>
</html>
&#13;
答案 0 :(得分:1)
根据视频,你的旋转左上角窗口 - 坐标原点。
要围绕任意点cx,cy 进行旋转,您必须使用以下公式:
NX = CX + (X0-CX) * Cos(Theta) - (Y0-CY) * Sin(Theta)
NY = CY + (X0-CX) * Sin(Theta) + (Y0-CY) * Cos(Theta)
答案 1 :(得分:0)
这里的第一个关键概念是你需要识别旋转原点的发生位置。旋转画布时,它会围绕与页面垂直的轴旋转;用二维的说法,它围绕原点旋转。
考虑尾部为原点且其尖端位于某一点(X,Y)的向量,其中X和Y是从原点(以适当的单位)测量的。我们可以使用您在上面提到的公式计算新的旋转点(X&#39;,Y&#39;):
X' = X cos(A) - Y sin(A) and
Y' = X sin(A) + Y cos(A), where A is the angle of rotation measured in radians.
我们可以从X&#39;中恢复X和Y.和Y&#39;通过轮换-A来实现:
X = X' cos(-A) - Y' sin(-A)
Y = X' sin(-A) + Y' cos(-A)
这是您在帖子中的公式,它是正确的。
如果我的矢量没有从原点开始的尾部怎么办?好吧,事实证明你只需要将变换应用到该向量的尾部以获得新的尾部,然后再次到头部以获得新的头部。如果你有一个从(A,B)开始到(C,D)结束的向量,那么变换后的向量将是(A&#39;,B&#39;),头部将是(C&#39;, d&#39)。您可以使用逆转回(A,B); (C,D)来自旋转的帧。
如果您使用此公式但没有得到正确的答案,请确保您正确地从正在旋转的原点进行测量。您可能正在正确计算原始矢量,但是您错过了一些真正属于您正在尝试测量的关键偏移。