在绕 X 轴旋转的画布上绘制位图时出现问题

发布于 2024-11-26 23:47:44 字数 1002 浏览 2 评论 0原文

美好的一天,

我在绘制图像时遇到了奇怪的问题。代码和图片比文字更能说明问题。

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

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

// here I draw images
...

canvas.restore();

结果如下图所示。第一张图片的角度为 0 度,第二张图片的角度约为 45 度,最后一张图片的角度更大。这取决于我想要绘制的区域大小(位图数量)。我注意到,当我绘制完全适合画布边界的位图时,它工作得很好。但问题主要是当我用类似的东西绘制图像(因此部分在画布之外)

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

和图像(嗯,因为我是新来的,我无法直接发布图像......)

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

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

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

所以问题是,是否有任何可行的解决方案或至少有任何提示。另外,如果有经验的人可以判断使用 OpenGL 绘图是否可以对此有所帮助,如果可以,请向我指出任何可以帮助我绘制变化很大的位图的信息源(它是地图应用程序,因此用户随地图移动),因为我仍然找不到任何简单明了的信息来源。

非常感谢大家

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

空城旧梦 2024-12-03 23:47:44

这是 2D 绘图 API 的限制。要实现真正的 3D,您应该使用 OpenGL。

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

落花浅忆 2024-12-03 23:47:44

我希望您正在尝试产生谷歌地图倾斜/旋转效果,我已经为谷歌地图成功完成了这一效果,因为他们认为我们不需要更新;-)并且我的应用程序需要它,即使您使用自己的应用程序瓷砖基本上是一样的。

一件有帮助的事情是认识到相机矩阵的旋转是在左上角执行的。

因此,您应该转换到适当的位置(取决于旋转轴和您的预期结果),然后返回,类似......在我阅读文档并弄清楚之前,您得到的效果与我的非常相似。

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

另一件要做的事情是加大容器的尺寸,这样在倾斜/旋转操作后就没有空白空间(或至少限制它),您可以通过计算所需的超大尺寸来做到这一点,显示器的对角线适用于基本的旋转,+ 基于倾斜的百分比(如果您使用的话)。

使用 pre/postTranslate 可以给你一些有趣的结果。

至于移动位图,我不太确定你为什么要这样做,可能是平移,但只要画布被填满,就没关系

更新

这是我如何超大画布,我尝试使用 LayoutParams 来执行此操作,但运气不佳,因此 Measure 是我的最佳选择。

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

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文