2009-05-11 1 views
2

В JavaScript мы часто делают графику путем вращения и перевода координат плоскости перед посылкой вещейПолучить ип переведенный, ун-повернута (х, у) координаты точки из холста 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) находятся где-то далеко от того, где они были бы без перевода и вращения. Есть ли простой способ узнать, каковы их фактические значения?

ответ

3

Там нет никакого способа, прямо сейчас, чтобы получить текущую матрицу преобразования, так что вам нужно будет следить за любые вращения/переводов/масштабируя себя.

Чтобы выполнить преобразование, необходимо умножить матрицу преобразования на точку (в виде вектора столбца).

Вы можете переопределить методы, влияющие на преобразование, чтобы сохранить собственную копию матрицы. Я не проверял этот код, но что-то, как это должно работать:

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 matrix library для удобства, но вы можете сделать свое собственное умножение.

Чтобы получить преобразованные точки, просто умножить матрицу преобразования точки:

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

Это необходимо для осуществления сохранения() и восстановления(), а также, но это выглядит как раз и должно получить отметку , –

+0

Хороший вопрос об save() и восстановлении(). Я добавлю их. –

+0

Это сработало с самого начала ... отлично, спасибо! Хотя почему они не думали об этом в оригинале, это вне меня. : / – HostileFork

1

Я думаю, что единственный способ найти это - применить те же преобразования, что и в контексте рендеринга, к точкам, которые вы хотите узнать о фактических координатах. Несколько библиотек обеспечивают матричные операции, как: http://sylvester.jcoglan.com/ Вы можете попытаться выполнить операции вращения на cartesian coordinates

Смежные вопросы