tias/xinput_calibrator — pull request #52 by kreijack (2013-06-10 20:31:53+00:00)
Title: Correct the calibration when the axes are inverted.

I had a problem to calibrate a touch screen with the axes inverted. Looking at the code I found that when the axes inversion is detected, the {x,y}_{max,min} are swapped:

// calculate average of clicks
float x_min = (clicked.x[UL] + clicked.x[LL])/2.0;
float x_max = (clicked.x[UR] + clicked.x[LR])/2.0;
float y_min = (clicked.y[UL] + clicked.y[UR])/2.0;
float y_max = (clicked.y[LL] + clicked.y[LR])/2.0;

// Should x and y be swapped?
if (abs(clicked.x[UL] - clicked.x[UR]) < abs(clicked.y[UL] - clicked.y[UR])) {
std::swap(x_min, y_min);
std::swap(x_max, y_max);

However I think that when the axis are swapped the calculation of the
{x,y}_{max,min} are wrong.
Let me explain why:

During the calibration, on the screen are showed four crosses called UL, LR, LL, UR (Upper Left, Lower Right...).

If the axes are not swapped during the calibration we got the following coordinates (x,y the numbers are hypothetical):

UL -> 10,10 UR -> 90,10
LL -> 10,70 LR -> 90,70

and

x_min = (10+10)/2 = 10
x_max = (90+90)/2 = 90
y_min = (10+10/2 = 10
y_max = (70+70)/2 = 70

Instead if the axes are inverted

UL -> 10,10 UR -> 10,90
LL -> 70,10 LR -> 70,90

and

x_min = (10+70)/2 = 35
x_max = (10+70)/2 = 35 x_min == x_max !!!!
y_min = (10+90)/2 = 45
y_max = (10+90)/2 = 45 y_min == y_max !!!!

which are basically wrong. I think that the right solution should be to calculate the
{x,y}_{max,min} as following when an axis inversion is detected:

x_min = (clicked.x[UL] + clicked.x[UR])/2.0;
x_max = (clicked.x[LL] + clicked.x[LR])/2.0;
y_min = (clicked.y[UL] + clicked.y[LL])/2.0;
y_max = (clicked.y[UR] + clicked.y[LR])/2.0;

( Note the different array indexes )

How reproduce the bug:
1) start xinput_calibrator --fake
2) calibrating clicking the upper left corner, then the LOWER LEFT corner, then the UPPER RIGHT corner, then the lower right corner

RESULT: in the output message message you can see the MaxX and MinX values, the MaxY and the MinY values very near.
EXPECTED RESULT: the difference between MaxX and MinX should be comparable to the screen width.