2011-07-07 34 views
6

Tôi đang cố gắng sử dụng Máy ảnh (android.graphics.Camera không phải máy ảnh phần cứng) để xoay khung nhìn xung quanh một điểm cụ thể , trong trường hợp này là giữa canvas.Cách xoay canvas tại một điểm cụ thể bằng cách sử dụng android.graphics.Camera.rotateX (góc)

Trong dispatchDraw (Canvas canvas) - để ngắn gọn, tôi sẽ loại bỏ tất cả các phần không quan trọng.

camera.save(); 
    camera.rotateX(0); 
    camera.rotateY(0); 
    camera.rotateZ(angle); 
    camera.getMatrix(cameraMatrix); 
camera.restore(); 

canvas.concat(cameraMatrix); 

Canvas xoay, nhưng luôn luôn ở góc trên bên trái.

LƯU Ý: Bởi vì vải đã được xây dựng để được lớn hơn diện tích trưng bày tôi cũng cần phải dịch các kết quả cuối cùng để nó tập trung vào màn hình, tôi có thể làm điều này với một trong hai

canvas.translate(xOffset,yOffset) PRIOR to calling the camera methods 

HOẶC

cameraMatrix.preTranslate(xOffset,yOffset) AFTER the camera methods 

Cả hai tập trung đúng vải trong màn hình nhưng tôi dường như không thể nắm được vấn đề luân chuyển là trung tâm cho (góc) gọi camera.rotateZ, cố gắng sử dụng các phương pháp trong mẫu android 3D nhưng trong khi họ dường như làm việc cho trục X/Y họ dường như không ảnh hưởng đến trục Z

Bất kỳ trợ giúp nào sẽ được đánh giá cao, tài liệu không chính xác.

Trả lời

8

Giải quyết vấn đề này, không chắc chắn nếu đó là cách tốt nhất nhưng nó hoạt động. Giải pháp là

Dịch vải đầu tiên để tập trung bức tranh lớn hơn trong màn hình

Sau đó, áp dụng các phép quay camera

Sau đó, để sử dụng trước và sau khi dịch phương pháp trên ma trận để thay đổi điểm luân chuyển tương tự như những gì mẫu Android đã làm.

Các bit bị thiếu là thực hiện dịch canvas trước và tôi cũng không sử dụng kích thước canvas lớn hơn để tính toán bù trừ cho các phương thức dịch trước và sau.

Đây là mã được sửa đổi nếu nó giúp bất kỳ ai khác.

// Center larger canvas in display (was made larger so 
// corners will not show when rotated) 
canvas.translate(-translateX, -translateY); 

// Use the camera to rotate a view on any axis 
camera.save(); 
    camera.rotateX(0); 
    camera.rotateY(0); 
    camera.rotateZ(angle); // Rotate around Z access (similar to canvas.rotate)         

    camera.getMatrix(cameraMatrix); 

    // This moves the center of the view into the upper left corner (0,0) 
    // which is necessary because Matrix always uses 0,0, as it's transform point 
    cameraMatrix.preTranslate(-centerScaled, -centerScaled); 

    // NOTE: Camera Rotations logically happens here when the canvas has the 
    // matrix applied in the canvas.concat method 

    // This happens after the camera rotations are applied, moving the view 
    // back to where it belongs, allowing us to rotate around the center or 
    // any point we choose 
    cameraMatrix.postTranslate(centerScaled, centerScaled); 
camera.restore(); 

canvas.concat(cameraMatrix); 

Nếu có ai có cách tốt hơn hoặc gặp sự cố, vui lòng để lại nhận xét.

+2

Hi cảm ơn cho bài đăng này, Nhưng tôi không thể hiểu được những gì sẽ là giá trị của translateX, translateY và centerScaled biến. Bạn có thể giải thích cho tôi không? – Dhaval

+0

@Dhaval vui lòng kiểm tra http://www.inter-fuser.com/2009/08/android-animations-3d-flip.html – Ankit

+0

Thực ra, đây có vẻ là giải pháp đúng.Vì 'Camera # applyToCanvas()' có thể không hoạt động đối với một số thiết bị ICS –

0

Sử dụng này như là sự chuyển đổi trong lớp học hoạt hình của bạn

protected void applyTransformation(float interpolatedTime, Transformation t) { 

    final float fromDegrees = 0; 

    float degrees = fromDegrees 

    + ((180- fromDegrees) * interpolatedTime); 

    final float centerX = mCenterX; 

    final float centerY = mCenterY; 

    final Camera camera = mCamera; 

    final Matrix matrix = t.getMatrix(); 

    camera.save(); 

    camera.rotateX(degrees); 

    camera.getMatrix(matrix); 

    camera.restore(); 

    matrix.preTranslate(-centerX, -centerY); 

    matrix.postTranslate(centerX, centerY); 

} 
+0

Tôi đã sử dụng giải pháp được chấp nhận (được sửa đổi đôi chút) trong một thời gian và không có vấn đề gì với nó. – Idistic

1

Tôi muốn làm mọi thứ theo cách khó khăn và "cuộn của riêng tôi". Hơn nữa, nếu bạn đang làm hình ảnh động tích lũy lỗi có thể leo trong concat'ing Matrix's.

float rotate; // rotation in degrees 

float vcx; // center of rotation of view 
float vcy; 

float gcx; // center of rotation of graphic 
float gcy; 

float theta = (float) (Math.PI/180.0*rotate); 
float sin = (float) Math.sin(theta); 
float cos = (float) Math.cos(theta); 

float[] a = new float[9]; 
a[Matrix.MSCALE_X] = cos; 
a[Matrix.MSKEW_X] = sin; 
a[Matrix.MTRANS_X] = vcx-gcx*cos-gcy*sin; 
a[Matrix.MSCALE_Y] = cos; 
a[Matrix.MSKEW_Y] = -sin; 
a[Matrix.MTRANS_Y] = vcy-gcy*cos+gcx*sin; 
a[Matrix.MPERSP_0] = 0.0f; 
a[Matrix.MPERSP_1] = 0.0f; 
a[Matrix.MPERSP_2] = 1.0f; 

Matrix m = new Matrix(); 
m.setValues(a); 
view.setImageMatrix(m); // or setMatrix or whatever you're using. 
3

này đã làm việc cho tôi:

@Override 
public void drawPixmap3D(Pixmap pixmap, int x, int y, int r) { 
    Camera camera = mCamera; 
    int cx = pixmap.getWidth()/2; 
    camera.save(); 
    camera.rotateY(r); 
    camera.getMatrix(mtx); 
    mtx.preTranslate(-cx, 0); 
    mtx.postTranslate(x, y); 
    camera.restore(); 
    canvas.drawBitmap(((AndroidPixmap)pixmap).bitmap, mtx, this.paint); 
} 
Các vấn đề liên quan