Lassen Sie sich un-übersetzt, ungedrehten (x, y) Koordinate eines Punktes aus einer Javascript Leinwand

StackOverflow https://stackoverflow.com/questions/849785

Frage

In Javascript machen wir oft Grafiken durch Drehen und die Koordinatenebene zu übersetzen, bevor die Dinge zu senden

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();

So dies getan zu haben, wie Figur, die ich die aktuellen Werte der Endpunkte dieser Linie Segment I gezogen habe? Da nach diesem Verschieben und Drehen, (x1, y1) und (x2, y2) sind irgendwo weit weg von wo aus sie ohne übersetzen würden und zu drehen. Gibt es einen einfachen Weg, um herauszufinden, was ihre tatsächlichen Werte sind?

War es hilfreich?

Lösung

Es gibt keinen Weg jetzt die aktuelle Transformationsmatrix zu erhalten, so würden Sie Spur von irgendwelchen Drehungen / Übersetzungen halten müssen / selbst skaliert wird.

Um die Transformation tatsächlich durchführen, müssen Sie die Transformationsmatrix durch den Punkt (als Spaltenvektor) multiplizieren.

Sie können die Methoden außer Kraft setzen, die die Transformation beeinflussen Ihre eigene Kopie der Matrix zu speichern. Ich habe diesen Code nicht getestet, aber so etwas wie dies funktionieren soll:

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);
}

Ich benutzte die Sylvester Matrix Bibliothek für Bequemlichkeit, aber Sie können Ihre eigene Vermehrung tun.

den transformierten Punkt zu erhalten, multiplizieren Sie einfach die Transformations-Matrix durch den Punkt:

// 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)];
}

Andere Tipps

ich glaube, der einzige Weg, das zu finden, wäre die gleichen Transformationen anwenden, wie Sie auf die Punkte auf der Rendering-Kontext haben Sie die aktuellen Koordinaten wissen wollen. Einige Bibliotheken bieten Matrixoperationen, wie: http://sylvester.jcoglan.com/ Sie können versuchen, Rotationsoperationen auf die kartesischen Koordinaten

auszuführen
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top