Android视图3d旋转大分辨率屏幕上的转换

Hen*_*rik 6 android resolution transform rotation matrix

我正在为android(api> 14)实现3d卡翻转动画,并且有大屏幕平板电脑(> 2048 dpi)的问题.在问题调查期间,我来到以下基本块:

尝试使用矩阵和相机的旋转Y转换视图(简单的ImageView)一些角度,它适用于角度<60和角度> 120(转换和显示)但是当角度在60和60之间时图像消失(只是不显示) 120.这是我使用的代码:

private void applyTransform(float degree) 
{
     float [] values = {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f};
     float centerX = image1.getMeasuredWidth() / 2.0f;
     float centerY = image1.getMeasuredHeight() / 2.0f;

     Matrix m = new Matrix();
     m.setValues(values);

     Camera camera = new Camera();
     camera.save();

     camera.rotateY(degree);
     camera.getMatrix(m);

     camera.restore();

     m.preTranslate(-centerX, -centerY); // 1 draws fine without these 2 lines
     m.postTranslate(centerX, centerY);  // 2 

    image1.setImageMatrix(m);
}
Run Code Online (Sandbox Code Playgroud)

这是我的布局XML

   <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout     xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:id="@+id/ImageView01"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@drawable/naponer"
        android:clickable="true"
        android:scaleType="matrix">
    </ImageView>
</FrameLayout>  
Run Code Online (Sandbox Code Playgroud)

所以我有以下几种情况:

  • 适用于任何角度,任何中心点,如果在800X480,1024x720等小屏幕上运行...
  • 在大屏幕设备2048x1536,2560x1600上运行时,角度<60和> 120正常工作......
  • 如果旋转不居中(矩阵前后翻译注释掉),任何设备上的任何角度都可以正常工作
  • 在大屏幕设备上运行时失败(图像消失),旋转居中,角度在60到120度之间.

请告诉我我做错了什么并建议一些解决方法......谢谢!!!

mat*_*ash 7

此问题是由用于计算转换的摄像机距离引起的.虽然Camera类本身不说这个话题了,它更好地为文档中解释的View.setCameraDistance()方法(重点煤矿):

设置从摄像机到此视图的沿Z轴(与绘制视图的X/Y平面正交)的距离.相机的距离会影响3D变换,例如围绕X轴和Y轴的旋转.(......)

当摄像机围绕x轴或y轴旋转时,摄像机与视平面的距离会影响视图的透视畸变.例如,较大的距离将导致较大的视角,并且在旋转时视图将不会有太多的透视变形.短距离可能会在旋转时造成更多的透视扭曲,并且如果旋转的视图部分地在摄像机后面结束,也可能导致一些绘制伪影(这就是为什么建议使用距离至少远远大于如果要旋转视图,请查看.)

说实话,我之前没有看到过这种特殊的效果(根本没有画画),但我怀疑它可能与我过去遇到的透视失真问题有关.:)

因此,解决方案是使用该Camera.setLocation()方法来确保不会发生这种情况.

与该View.setCameraDistance()方法的重要区别在于单元不相同,因为setLocation()不使用像素.虽然 setCameraDistance()调整密度,setLocation()但没有.因此,如果要根据视图的尺寸计算适当的z距离,请记住调整密度.例如:

float cameraDistance = Math.max(image1.getMeasuredHeight(), image1.getMeasuredWidth()) * 5;
float densityDpi = getResources().getDisplayMetrics().densityDpi;
camera.setLocation(0, 0, -cameraDistance / densityDpi);
Run Code Online (Sandbox Code Playgroud)