繁体   English   中英

从Javascript画布获取点的未翻译,未旋转(x,y)坐标

[英]Get un-translated, un-rotated (x,y) coordinate of a point from a Javascript canvas

在Javascript中,我们通常通过在发送内容之前旋转和平移坐标平面来渲染图形

ctx.save();
ctx.translate(someX, someY);
ctx.rotate(someAngle * Math.PI / 180);

ctx.beginPath();
ctx.moveTo(x1, y1);    // What's the actual (x1,y1)?
ctx.lineTo(x2, y2);    // What's the actual (x2,y2)?
ctx.stroke();

ctx.restore();

因此,如何确定绘制的线段端点的实际值? 因为在进行平移和旋转之后,(x1,y1)和(x2,y2)远离没有平移和旋转的位置。 有一种简单的方法可以找出它们的实际值是多少?

目前无法获取当前的变换矩阵,因此您需要自己跟踪所有旋转/平移/缩放。

要实际执行转换,您需要将转换矩阵乘以该点(作为列向量)。

您可以覆盖影响转换的方法,以存储自己的矩阵副本。 我尚未测试此代码,但类似的东西应该可以工作:

var contextPrototype = CanvasRenderingContext2D.prototype;

contextPrototype.xform = Matrix.I(3);

contextPrototype.realSave = contextPrototype.save;
contextPrototype.save = function() {
    if (!this.xformStack) {
        this.xformStack = [];
    }
    this.xformStack.push(this.xform.dup());
    this.realSave();
}

contextPrototype.realRestore = contextPrototype.restore;
contextPrototype.restore = function() {
    if (this.xformStack && this.xformStack.length > 0) {
        this.xform = this.xformStack.pop();
    }
    this.realRestore();
}

contextPrototype.realScale = contextPrototype.scale;
contextPrototype.scale = function(x, y) {
    this.xform = this.xform.multiply($M([
        [x, 0, 0],
        [0, y, 0],
        [0, 0, 1]
    ]));
    this.realScale(x, y);
}

contextPrototype.realRotate = contextPrototype.rotate;
contextPrototype.rotate = function(angle) {
    var sin = Math.sin(angle);
    var cos = Math.cos(angle);
    this.xform = this.xform.multiply($M([
        [cos, -sin, 0],
        [sin,  cos, 0],
        [   0,   0, 1]
    ]));
    this.realRotate(angle);
}

contextPrototype.realTranslate = contextPrototype.translate;
contextPrototype.translate = function(x, y) {
    this.xform = this.xform.multiply($M([
        [1, 0, x],
        [0, 1, y],
        [0, 0, 1]
    ]));
    this.realTranslate(x, y);
}

contextPrototype.realTransform = contextPrototype.transform;
contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {
    this.xform = this.xform.multiply($M([
        [m11, m21, dx],
        [m12, m22, dy],
        [  0,   0,  1]
    ]));
    this.realTransform(m11, m12, m21, m22, dx, dy);
}

contextPrototype.realSetTransform = contextPrototype.setTransform;
contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {
    this.xform = $M([
        [m11, m21, dx],
        [m12, m22, dy],
        [  0,   0,  1]
    ]);
    this.realSetTransform(m11, m12, m21, m22, dx, dy);
}

为了方便起见,我使用了Sylvester矩阵库 ,但是您可以自己进行乘法。

要获得转换点,只需将转换矩阵乘以该点即可:

// Get the transformed point as [x, y]
contextPrototype.getTransformedPoint = function(x, y) {
    var point = this.xform.multiply($V([x, y, 1]));
    return [point.e(1), point.e(2)];
}

我认为唯一的发现方法是将与在渲染上下文中所做的转换相同的转换应用于您想知道实际坐标的点。 一些库提供矩阵运算,例如: http : //sylvester.jcoglan.com/您可以尝试对笛卡尔坐标执行旋转运算

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM