好吧,这是越来越复杂...获取画布位置之后旋转/平移和恢复
鉴于情况:
我的800x600尺寸的画布。
我的鼠标位于画布位置100x200(例如)。
我保存了我的画布状态。
现在我旋转并翻译画布,画一个正方形。
我恢复了我的画布状态。
有什么方法可以确定我的鼠标是否在广场上?
我想我必须翻译/旋转我的鼠标位置 - 在相反的方向,但我该怎么做?
好吧,这是越来越复杂...获取画布位置之后旋转/平移和恢复
鉴于情况:
我的800x600尺寸的画布。
我的鼠标位于画布位置100x200(例如)。
我保存了我的画布状态。
现在我旋转并翻译画布,画一个正方形。
我恢复了我的画布状态。
有什么方法可以确定我的鼠标是否在广场上?
我想我必须翻译/旋转我的鼠标位置 - 在相反的方向,但我该怎么做?
您可以通过递归地应用这个公式得到一个对象的世界位置/旋转的保持:
worldX = parentX + x * Math.cos(parentR) - y * Math.sin(parentR);
worldY = parentY + x * Math.sin(parentR) + y * Math.cos(parentR);
worldR = parentR + r;
一个JavaScript实现是:
var deg2rad, rad2deg, getXYR;
deg2rad = function (d) { return d * Math.PI/180 };
rad2deg = function (r) { return r/Math.PI * 180 };
getXYR = function (node) {
var x, y, r,
parentXYR, pX, pY, pR,
nX, nY;
x = y = r = 0;
if (node) {
parentXYR = getXYR(node.parent);
pX = parentXYR.x;
pY = parentXYR.y;
pR = deg2rad(parentXYR.r);
nX = node.x;
nY = node.y;
x = pX + nX * Math.cos(pR) - nY * Math.sin(pR);
y = pY + nX * Math.sin(pR) + nY * Math.cos(pR);
r = rad2deg(pR + deg2rad(node.r));
}
return { x:x, y:y, r:r };
};
试试看这些对象:
el1 = {x:3,y:0,r:45};
el2 = {x:0,y:0,r:45};
el1.parent = el2;
getXYR(el1);
要计算两个对象之间的最短角度之前,它不会很长,如果两个物体之间获得DELTAX(X2-X1)和移动deltaY(Y2-Y1),你可以用此功能获得角度:
var getAngle = function (dx, dy) {
var r = Math.atan2(dy, dx) * 180/Math.PI;
return (r > 180) ? r-360 :
(r < -180) ? r+360 :
r;
}
从长远来看,最好是使用矩阵来学习。获得世界正/反腐等值是一个世界矩阵。下面是关于矩阵的一些好的信息(在SVG文档,但它是不相关):http://www.w3.org/TR/SVG/coords.html#NestedTransformations
这是你将如何处理矩阵(和GL-矩阵LIB https://github.com/toji/gl-matrix)做到这一点:
var getWorldMatrix = function (node) {
var parentMatrix;
if (!node)
return mat4.identity();
parentMatrix = getWorldMatrix(node.parent);
return mat4.multiply(parentMatrix, node.matrix);
};
哦,我忘了,现在终于注册一个点击,你只需获得鼠标的屏幕坐标,并将它们与对象位置+画布视口偏移进行比较。
您的回答非常好!感谢您为帮助我所做的一切努力:) 我直接采用矩阵方式 - 目前看起来有些复杂,但我希望长远来看付出代价。 另外,我并没有选择使用gl-matrix,而是使用Sylvester。js,因为gl矩阵在我的矩阵中做了一些奇怪的事情,并且离ctx.transform()等待的矩阵格式太远了。 我希望我的大脑不会在矩阵的力量下融化x) – 2012-01-13 15:25:20
好的答案,另一个查询!这个问题考虑了三个因素,x,y和r;如果考虑所有转换因素会怎么样?我的意思是如果应用缩放,平移,倾斜和旋转转换,算法会是什么。算法的来源是什么? – 2012-06-05 05:39:17
@bennedich你可以看看这个问题吗? http://stackoverflow.com/questions/10892267/html5-canvas-transformation-algorithm-finding-object-coordinates-after-applyin – 2012-06-05 05:54:50
是的,您必须翻译鼠标坐标或为您的形状保留第二组坐标。我建议保留第二组坐标,因为您将移动鼠标的次数超过您转换对象的次数。尝试使用对象,像这样
箱
function Box(x, y, w, h){
this.x = x;
this.y = y;
this.tx = x; //transformed x
this.ty = y; //transformed y
this.w = w;
this.h = h;
this.mouseover = function(x, y){
if (this.tx < x && this.tx + this.w > x && this.ty < y && this.ty + this.h > y){
return true;
}
return false;
}
this.applyTransformation = function(transformation){
switch(transformation){
case 'rotation':
//update tx/ty to match rotation
break;
case 'translation':
//update tx/ty to match translation
break;
default:
//do nothing or raise exception
}
}
你有没有与你绘制的东西相关的对象?你有场景图吗?每个物体都有矩阵吗?如果不是,你如何保存你所画的位置和旋转角度? – bennedich 2012-01-13 01:13:06
是的,这个正方形也是一个物体,其值为x,y,w,h,r。它变得越来越复杂的一点是,一个物体也可以有孩子继承父母的位置和旋转,并且自己根据父母的起源定位和旋转。 – 2012-01-13 01:17:18