6
votes

Comment faire pivoter une toile à un point spécifique à l'aide d'Android.Graphics.camera.rotatex (angle)

J'essaie d'utiliser la caméra (android.graphics.camera pas la caméra matérielle) pour faire pivoter une toile de vues autour d'un point spécifique, dans ce cas, au milieu de la toile.

Dans DispatchDraw (toile de canvas) - Pour la brièveté, je laisse toutes les parties non importantes. P>

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


0 commentaires

4 Réponses :


9
votes

Résolu, je ne sais pas si c'est le meilleur moyen mais ça marche. La solution était de

traduire la toile d'abord pour centrer la plus grande toile dans l'affichage p>

puis appliquer les rotations de l'appareil photo p>

puis pour utiliser les méthodes de prédilection pré et post sur la matrice Pour changer le point de rotation similaire à ce que l'échantillon Android a fait. P>

Les bits manquants devaient d'abord faire la traduction de toile, et je n'utilisais pas non plus la plus grande taille de toile pour calculer les décalages pour le pré-post Traduire des méthodes. P>

Voici le code modifié si cela aide toute autre chose à sortir. P>

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


3 commentaires

Bonjour merci pour ce post, mais je ne suis pas capable de comprendre la quelle sera la valeur des variables TRUCLATEX, TRADUCTÉE ET CENTERSCALÉE. Pouvez-vous s'il vous plaît expliquer moi?


@Dhaval s'il vous plaît vérifier Inter-fuser.com/2009/ 08 / Android-Animations-3D-Flip.html


En fait, cela semble être une solution correcte. Depuis Caméra # ApplicTocanvas () Peut ne pas fonctionner pour certains appareils ICS



1
votes

Utilisez-le comme la transformation de votre classe d'animation

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

}


1 commentaires

J'utilise la solution acceptée (légèrement modifiée) depuis un certain temps et j'ai eu des problèmes de zéro avec elle.



1
votes

J'aime faire des choses de manière difficile et "rouler le mien". De plus, si vous faites des animations, des erreurs cumulatives peuvent se glisser dans la matrice concessive.

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.


0 commentaires

3
votes

Cela a fonctionné pour moi:

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


0 commentaires