JavaScript 캔버스에서 한 지점의 번역되지 않은, 방해받지 않은 (X, y) 좌표를 받으십시오.

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

문제

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

나는 그것을 사용했다 실베스터 매트릭스 라이브러리 편의를 위해서는 자신의 곱셈을 할 수 있습니다.

변환 된 지점을 얻으려면 변환 매트릭스를 포인트로 곱하십시오.

// 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 ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top