开发者

Problem with draw bitmap on rotated canvas around X axis

开发者 https://www.devze.com 2023-03-24 03:11 出处:网络
Good day, I have weird problem with drawing image. Code and pictures say more then words. mCamera.save();

Good day,

I have weird problem with drawing image. Code and pictures say more then words.

mCamera.save();
mCamera.rotateX(rotateX);
mCamera.getMatrix(mMatrix);
mCamera.restore();

canvas.save();
canvas.setMatrix(mMatrix);

// here I draw images
...

canvas.restore();

and results are at images below. First picture have angle 0, second around 45 degree and last something more. It depend on size of area (number of bitmaps) I want to draw. I notice that when I draw bitmaps that whole fits canvas bounds, it works fine. But problem is mainly when I draw images with something like (so with part outside of canvas)

canvas.drawBitmap(image, -100, -100, null)

and images (hmm, because I'm new here, I cannot post images directly ..开发者_StackOverflow.)

ttp://locus.asamm.cz/data/_temp/1311873666794.png

http://locus.asamm.cz/data/_temp/1311873695945.png

http://locus.asamm.cz/data/_temp/1311873782054.png

So question is, if there is any working solution or at least any tip. Also if anyone experienced can tell if drawing with OpenGL can help with this and if so, please point me to any information source that can help me with drawing bitmaps that change a lot (it's map application so user move with map), because I still cannot find any simple and clear source of info.

Thanks to all very much


It's a limitation of the 2D drawing API. To do true 3D you should use OpenGL.


I expect you are trying to produce a google maps tilt/rotate effect which I have successfull done for google maps since they don't think we need an update ;-) and I needed it for my application, even if you are using your own tiles it's basically the same thing.

One thing that helps is realize that the rotations for the Camera Matrix are performed in the upper left corner.

So you should transform to the appropriate location (dependent on axis of rotation and your expected results) and then back, something like ... the effects you are getting were very similar to mine before I read the docs and figured that out.

camera.save();
    camera.rotateX(tilt);  // tilt forward or backward
    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
     // use the center of the canvas, or the bottom center dependent on your results 
     cameraMatrix.preTranslate(-centerX, -centerY);

     // NOTE: Camera Rotations logically happen here when the canvas has the matrix applied  
     // 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 

     // Move it back after the rotations are applied
     cameraMatrix.postTranslate(centerX, centerY);

camera.restore();

canvas.concat(cameraMatrix);

The other thing to do is to oversize the container so you don't have empty space (or at least limit it) after your tilt/rotate operations, you can do that by calculating the needed oversize, the diagonal of your display works for basic rotation, + a percentage based on tilt if you are using that.

Playing around with the pre/postTranslate can can give you some interesting results.

As to moving the bitmap I am not really sure why you are doing this, probably panning, but as long as the canvas is getting filled it shouldn't matter

Update

Here is how I oversize the canvas, I tried to use the LayoutParams to do this but didn't have much luck with it so on Measure was the way to go for me.

@Override 
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
    if (!isInEditMode())
        super.onMeasure(View.MeasureSpec.makeMeasureSpec(scaledDimensionsW,
        View.MeasureSpec.EXACTLY),
        View.MeasureSpec.makeMeasureSpec(scaledDimensionsH,
        View.MeasureSpec.EXACTLY));
   else
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
0

精彩评论

暂无评论...
验证码 换一张
取 消