How to get the degree of rotation from an event with two fingers with a few touches?

I have an ImageView that you can use to create a finger with one finger or with two fingers. It is working fine. I expanded it to handle rotation, and its behavior causes some confusion.

When an event with multiple touches occurs, this method is called, which should return the angle of rotation in degrees. It does not do what I expect.

private int fingersAngle(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); int degrees = (int)(Math.toDegrees(Math.atan2(y, x))); return degrees; } 

When I rotate two fingers, I expect the exits ...

158 166 168 169 174 176 179 181 etc.

But what I actually get is more like this:

158 166 -179 179 -179 179 -179

The problem seems to be related to the symptoms. How does this method know if it will be 180 or -180, or 90 or -270? The image often rotates in the wrong way, and then suddenly jumps and starts to rotate in the opposite way. Worse, the direction it initially rotates is random.

I am testing the application using Nexus One, but also see the same problem on the Advent Vega tablet. Both devices work fine with Google Maps in 3D to rotate the screen (if sometimes jumping a little), so the data does not indicate a hardware limitation.

The second problem is that when two fingers are approximately vertically or horizontally aligned, the angle simply does not change, so the rotation “sticks” about 10-20 degrees up / down / left / right.

I'm currently doing a check to see if the angle has suddenly changed, and if so, subtract it from 360. Ugly, damn it, but it helps a little.

Hopefully one of you has seen this before and knows how to extract angular rotation from multi-touch gestures.

Some things on Android are so light that it's awesome, but such things are very painful.

+6
source share
4 answers

To make this work, as users expect, you must save some state.

A tangent arc will only tell you the angle between two points - a snapshot of the system. But you do the animation - what happens over time.

So, I think you're on the right track with your “ugly” solution, which is trying to detect big changes in the corner. What you really need to track over time is the position of each finger.

Suppose the user uses the index finger and index finger for gestures. You need to make sure that their numbers are sequentially presented, for example. the thumb is always represented (x 0 , y 0 ), and the index finger is (x 1 , y 1sub>).

The device probably has some rule, as each coordinate is reported. For example, perhaps it will always indicate the upper left coordinate in the slot "0" of the event and the lower right coordinate in the slot "1". But if the user moves the thumb from the lower right to the upper left, you must make sure that you still consider it as (x 1 , y 1 ) in your own although the device now reports this as (x 0 , y 0 ) in this case . Otherwise, the image will quickly flip 180 °, back and forth.

If the device does not track fingers for you, you will have to come up with a heuristic for guessing. A simple “which of the previous coordinates is closer to the current coordinate” would be a good place to start, but I could see the need for something more interesting if the resolution of the events is small.

+4
source

I have never encountered this problem, but I assume that using atan2 forces your angles from -180 to +180.

But the rotation you want to apply to your image should be between 0 and 360.

The simplest solution would probably be to add 180 to the degrees variable before returning it.

EDIT:. Since you added in the comments that there is an accident, I think that depending on the device you are working with, you may encounter the notorious HTC multitouch error (and other early ones): http://www.youtube.com/watch ? v = Ds5qZ_3XRzI This shows it for the nexus, but the hero and some motorcycles had the same problems.

+1
source

atan2 () returns a value in the range (-180 .. + 180).

Given this, does it seem to work correctly now?

(if you are +179 degrees, the rotation by another three degrees will be +182, but it is represented as -178)

0
source

Check if you can read 2 points at the same time and completely independently. I'm not sure what the Nexus One does. Check out this page:

http://developer.android.com/reference/android/content/pm/PackageManager.html

and find out if your target device only supports FEATURE_TOUCHSCREEN_MULTITOUCH or better (i.e. FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT). Probably the easiest way is to install a test application - I think I used the "multitouch visible test."

If your device does not work, there are no fixes or workarounds. This driver limitation is usually caused by the crappy selection of touch screens by penny manufacturers.

0
source

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


All Articles