Javascript 二维变换,旋转不符合预期
我试图用javascript在2d空间实现一组基本的欧几里德变换,我的旋转似乎有问题Javascript 二维变换,旋转不符合预期,javascript,html,linear-algebra,Javascript,Html,Linear Algebra,我试图用javascript在2d空间实现一组基本的欧几里德变换,我的旋转似乎有问题 // simple 2d html5 interface "use strict"; class Point{ constructor(x,y){ this.x = x; this.y = y; } mul(c){ this.x *= c; this.y *= c; } } class TransMatr
// simple 2d html5 interface
"use strict";
class Point{
constructor(x,y){
this.x = x;
this.y = y;
}
mul(c){
this.x *= c;
this.y *= c;
}
}
class TransMatrix{
/* see https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/geometry/geo-tran.html
* for more info.
* c1 c2 c3
* c4 c5 c6
* c7 c8 c9
*/
constructor(){
this.c1 = 1;
this.c2 = 0;
this.c3 = 0;
this.c4 = 0;
this.c5 = 1;
this.c6 = 0;
this.c7 = 0;
this.c8 = 0;
this.c9 = 1;
}
applyMatrix(point){
point.x = this.c1*point.x + this.c2*point.y + this.c3;
point.y = this.c4*point.x + this.c5*point.y + this.c6;
}
copy(){
var matrix = new TransMatrix();
matrix.c1 = this.c1;
matrix.c2 = this.c2;
matrix.c3 = this.c3;
matrix.c4 = this.c4;
matrix.c5 = this.c5;
matrix.c6 = this.c6;
matrix.c7 = this.c7;
matrix.c8 = this.c8;
matrix.c9 = this.c9;
return matrix;
}
translation(x,y){
var newMatrix = this.copy();
newMatrix.c3 += x;
newMatrix.c6 += y;
return newMatrix;
}
scale(s){
var newMatrix = this.copy();
newMatrix.c1 += s;
newMatrix.c5 += s;
return newMatrix;
}
rotation(r){ //radians
var newMatrix = this.copy();
newMatrix.c1 += Math.cos(r);
newMatrix.c2 += -Math.sin(r);
newMatrix.c4 += Math.sin(r);
newMatrix.c5 += Math.cos(r);
return newMatrix;
}
}
function drawHexagon(canvas, matrix, strokeColor, fillColor) {
if (!canvas) {
return;
}
var points = [new Point(0.5 , 1),
new Point(1 , 0),
new Point(0.5 , -1),
new Point(-0.5, -1),
new Point(-1 , 0),
new Point(-0.5, 1)
];
points.forEach(point => {
matrix.applyMatrix(point);
});
drawHexagonLit(canvas,points[0],points[1],points[2],points[3],points[4],points[5], "red", "green");
}
function drawHexagonLit(canvas, p1, p2, p3 ,p4 ,p5, p6, strokeColor, fillColor){ // add border cases here
if(!canvas){
return;
}
var ctx = canvas.getContext("2d");
if(!ctx){
return;
}
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
ctx.lineTo(p3.x, p3.y);
ctx.lineTo(p4.x, p4.y);
ctx.lineTo(p5.x, p5.y);
ctx.lineTo(p6.x, p6.y);
ctx.lineTo(p1.x, p1.y);
ctx.strokeStyle = strokeColor;
ctx.fillColor = fillColor;
ctx.stroke();
ctx.fill();
ctx.closePath();
}
function dynamicBackgroundInit(canvas){
if(!canvas){
return;
}
var worldMatrix = new TransMatrix();
var rotate = 0;
function step(){
canvas.getContext("2d").clearRect(0, 0, canvas.width, canvas.height);
rotate += 0.01;
var transform = worldMatrix.rotation(rotate); // this is better reflected by a matrix inside an object
transform = transform.translation(50,50);
transform = transform.scale(30,30);
drawHexagon(canvas, transform, "red", "green");
window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
}
呼叫和翻译按预期进行,但轮换似乎效果不佳。最初我以为我只是在一个外部原点上旋转,但我不再这么认为,因为当初始对象只是简单地放大时,问题仍然存在。您的转换代码会产生瑕疵,因为您在转换之前和之后都使用点坐标,因此,在第二行中,使用转换后的坐标,而不是原始坐标:
applyMatrix(point){
point.x = this.c1*point.x + this.c2*point.y + this.c3;
point.y = this.c4*point.x + this.c5*point.y + this.c6; // transformed point.x is used instead of the original point.x
}
相反,请执行以下操作:
applyMatrix(point){
var x = point.x, y = point.y;
point.x = this.c1*x + this.c2*y + this.c3;
point.y = this.c4*x + this.c5*y + this.c6;
}
在您尝试同时应用的任何其他变换中,对原始坐标使用类似的缓存。首先将它们存储在临时变量中,然后使用原始坐标和新坐标作为不同的变量进行应用我应用了修复,它似乎有效,但旋转虽然居中,但似乎仍被限制在一个非常窄的角度范围内。主要是因为我不能只复制矩阵,我必须正确地将它们相乘。