3D viewing of 3D images on a higher resolution screen

I am using the 3D flash card animation for Android (api> 14) and the problem with the tablet on the big screen (> 2048 dpi). While researching problems, I came to the following base unit:

I tried to just convert the view (simple ImageView) using the matrix and rotate the camera to some angle, and it works fine for the angle <60 and angle> 120 (it is converted and displayed), but the image disappears (just does not display) when the angle is between 60 and 120. Here is the code I'm using:

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

And here is my XML layout

  <?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> 

So, I have the following cases:

  • works great for any angle, any center point works on small screens 800X480, 1024x720, etc.
  • works fine for angles <60 and> 120 when working on large screens 2048x1536, 2560x1600 ...
  • works fine for any angle on any device if the rotation is not centered (comments before and after the translation are commented out)
  • it doesnโ€™t work (the image disappears) when working on the deviceโ€™s large screen, centering in the center and angle between 60 and 120 degrees.

Tell me what I'm doing wrong and advise a workaround ... thanks!

+6
source share
3 answers

This problem is caused by the distance between the cameras used to calculate the conversion. While the Camera class itself does not talk about the subject, it is better explained in the documentation for the View.setCameraDistance() method (highlighted by me):

Sets the distance along the Z axis (orthogonal to the X / Y plane for which views are drawn) from the camera to this view. Camera distance affects 3D transformations, such as rotations around X and Y. (...)

The distance from the camera to the viewing plane can affect the perspective distortion of the view when it rotates around x or the y axis. For example, a large distance will lead to a wide viewing angle, and there will not be much distortion of the perspective view when it rotates. Over a short distance, there may be much greater perspective distortion during rotation, and it can also lead to some artifact drawing if the rotated view is partially behind the camera (therefore, it is recommended to use a distance of at least how large the view is if the view should be rotated .)

Honestly, I had not seen this specific effect before (without drawing at all), but I suspected that this could be due to this issue related to perspective distortion I encountered in the past. :)

Therefore, the solution is to use the Camera.setLocation() method to prevent this from happening.

An important difference between the View.setCameraDistance() method is that the units are not the same , since setLocation() does not use pixels. As long as setCameraDistance() configured for density, setLocation() not. Therefore, if you want to calculate a suitable distance z based on the size of the view, be sure to adjust the density. For instance:

 float cameraDistance = Math.max(image1.getMeasuredHeight(), image1.getMeasuredWidth()) * 5; float densityDpi = getResources().getDisplayMetrics().densityDpi; camera.setLocation(0, 0, -cameraDistance / densityDpi); 
+7
source

Instead of using 12 lines to create a rotation matrix, you can simply implement this in the first line of http://en.wikipedia.org/wiki/Rotation_matrix

Depending on the effect you want, you may want to center the image on the axis you want to rotate. http://en.wikipedia.org/wiki/Transformation_matrix

Hmm for image fading, I would suggest that this has something to do with any memory (from memory - although this may lead to an exception) or rounding issues. Maybe you can try to increase the accuracy to double precision?

One thing that comes to mind is that cos (alpha) goes to 0 when alpha goes to PI / 2. Other than this, I do not see any correlation between the angles and why it does not work for large images.

0
source

You need to set up the Translate coordinates. When calculating the translation for your image, you must also consider the size of the image. When you do matrix calculations, you set android:scaleType="matrix" for your ImageView . This aligns the image in the upper left by default. Then, when you apply pre-translation, your image may go beyond your ImageView (especially if the ImageView relatively large and your image is relatively small, for example, in the case of beeg tablets).

The following translation causes the image to rotate around its central Y axis and align the image in the upper left corner:

 m.preTranslate(-imageWidth/2, 0); m.postTranslate(imageWidth/2, 0); 

The following alternative results, when you rotate the image around its central Y / X axis, align the image to the center of the ImageView :

 m.preTranslate(-imageWidth/2, -imageHeight/2); m.postTranslate(centerX, centerY); 

If your image is a bitmap, you can use the inner width / height:

 Drawable drawable = image1.getDrawable(); imageHeight = drawable.getIntrinsicHeight(); imageWidth = drawable.getIntrinsicWidth(); 
0
source

Source: https://habr.com/ru/post/980302/


All Articles