求高手指点此函数用的什么东西算出来的??? 来人哪,有木有??有木有??? 触摸屏校准,有5个采样点:左上角,右上角,左下角,右下角,中间。存于数组pUncalXBuffer,pUncalYBuffer Function:根据这5组坐标计算出 A1,A2,B1,B2,C1,C2。公式:Sx = A1*Tx + B1*Ty + C1Sy = A2*Tx + B2*Ty + C2 BOOL
TouchPanelSetCalibration(
INT32 cCalibrationPoints, //@PARM The number of calibration points
INT32 *pScreenXBuffer, //@PARM List of screen X coords displayed
INT32 *pScreenYBuffer, //@PARM List of screen Y coords displayed
INT32 *pUncalXBuffer, //@PARM List of X coords collected
INT32 *pUncalYBuffer //@PARM List of Y coords collected
)
{
LARGENUM a11;
LARGENUM a21, a22;
LARGENUM a31, a32, a33;
LARGENUM b11, b12, b13;
LARGENUM b21, b22, b23;
LARGENUM lnScreenX;
LARGENUM lnScreenY;
LARGENUM lnTouchX;
LARGENUM lnTouchY;
LARGENUM lnTemp;
LARGENUM delta;
LARGENUM a1, b1, c1;
LARGENUM a2, b2, c2;
MATRIX33 Matrix;
INT32 cShift;
INT32 minShift;
int i;
DEBUGMSG(1,(__TEXT("calibrating %d point set\r\n"), cCalibrationPoints)); //
// If the calibration data is being cleared, set the flag so
// that the conversion operation is a noop.
// if ( cCalibrationPoints == 0 )
{
v_Calibrated = FALSE;
return TRUE;
} //
// Compute these large numbers
//
LargeNumSet(&a11, 0);
LargeNumSet(&a21, 0);
LargeNumSet(&a31, 0);
LargeNumSet(&a22, 0);
LargeNumSet(&a32, 0);
LargeNumSet(&a33, cCalibrationPoints);
LargeNumSet(&b11, 0);
LargeNumSet(&b12, 0);
LargeNumSet(&b13, 0);
LargeNumSet(&b21, 0);
LargeNumSet(&b22, 0);
LargeNumSet(&b23, 0);
for(i=0; i<cCalibrationPoints; i++){
LargeNumSet(&lnTouchX, pUncalXBuffer[i]);
LargeNumSet(&lnTouchY, pUncalYBuffer[i]);
LargeNumSet(&lnScreenX, pScreenXBuffer[i]);
LargeNumSet(&lnScreenY, pScreenYBuffer[i]);
LargeNumMult(&lnTouchX, &lnTouchX, &lnTemp);
LargeNumAdd(&a11, &lnTemp, &a11);
LargeNumMult(&lnTouchX, &lnTouchY, &lnTemp);
LargeNumAdd(&a21, &lnTemp, &a21);
LargeNumAdd(&a31, &lnTouchX, &a31);
LargeNumMult(&lnTouchY, &lnTouchY, &lnTemp);
LargeNumAdd(&a22, &lnTemp, &a22);
LargeNumAdd(&a32, &lnTouchY, &a32);
LargeNumMult(&lnTouchX, &lnScreenX, &lnTemp);
LargeNumAdd(&b11, &lnTemp, &b11);
LargeNumMult(&lnTouchY, &lnScreenX, &lnTemp);
LargeNumAdd(&b12, &lnTemp, &b12);
LargeNumAdd(&b13, &lnScreenX, &b13);
LargeNumMult(&lnTouchX, &lnScreenY, &lnTemp);
LargeNumAdd(&b21, &lnTemp, &b21);
LargeNumMult(&lnTouchY, &lnScreenY, &lnTemp);
LargeNumAdd(&b22, &lnTemp, &b22);
LargeNumAdd(&b23, &lnScreenY, &b23);
} Matrix.pa11 = &a11;
Matrix.pa21 = &a21;
Matrix.pa31 = &a31;
Matrix.pa12 = &a21;
Matrix.pa22 = &a22;
Matrix.pa32 = &a32;
Matrix.pa13 = &a31;
Matrix.pa23 = &a32;
Matrix.pa33 = &a33;
ComputeMatrix33(&delta, &Matrix); Matrix.pa11 = &b11;
Matrix.pa21 = &b12;
Matrix.pa31 = &b13;
ComputeMatrix33(&a1, &Matrix); Matrix.pa11 = &a11;
Matrix.pa21 = &a21;
Matrix.pa31 = &a31;
Matrix.pa12 = &b11;
Matrix.pa22 = &b12;
Matrix.pa32 = &b13;
ComputeMatrix33(&b1, &Matrix); Matrix.pa12 = &a21;
Matrix.pa22 = &a22;
Matrix.pa32 = &a32;
Matrix.pa13 = &b11;
Matrix.pa23 = &b12;
Matrix.pa33 = &b13;
ComputeMatrix33(&c1, &Matrix); Matrix.pa13 = &a31;
Matrix.pa23 = &a32;
Matrix.pa33 = &a33;
Matrix.pa11 = &b21;
Matrix.pa21 = &b22;
Matrix.pa31 = &b23;
ComputeMatrix33(&a2, &Matrix); Matrix.pa11 = &a11;
Matrix.pa21 = &a21;
Matrix.pa31 = &a31;
Matrix.pa12 = &b21;
Matrix.pa22 = &b22;
Matrix.pa32 = &b23;
ComputeMatrix33(&b2, &Matrix); Matrix.pa12 = &a21;
Matrix.pa22 = &a22;
Matrix.pa32 = &a32;
Matrix.pa13 = &b21;
Matrix.pa23 = &b22;
Matrix.pa33 = &b23;
ComputeMatrix33(&c2, &Matrix);#if 1
{
LARGENUM halfDelta;
//
// Take care of possible truncation error in later mapping operations
//
if(IsLargeNumNegative(&delta)){
LargeNumDivInt32(&delta, -2, &halfDelta);
} else {
LargeNumDivInt32(&delta, 2, &halfDelta);
}
LargeNumAdd(&c1, &halfDelta, &c1);
LargeNumAdd(&c2, &halfDelta, &c2);
}
#endif //
// All the numbers are determined now.
// Let's scale them back to 32 bit world
//
minShift = 0;
cShift = LargeNumBits(&a1) - MAX_COEFF_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&b1) - MAX_COEFF_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&a2) - MAX_COEFF_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&b2) - MAX_COEFF_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&c1) - MAX_TERM_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&c2) - MAX_TERM_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&delta) - 31;
if(cShift > minShift){
minShift = cShift;
} //
// Now, shift count is determined, shift all the numbers
// right to obtain the 32-bit signed values
//
if(minShift){
LargeNumRAShift(&a1, minShift);
LargeNumRAShift(&a2, minShift);
LargeNumRAShift(&b1, minShift);
LargeNumRAShift(&b2, minShift);
LargeNumRAShift(&c1, minShift);
LargeNumRAShift(&c2, minShift);
LargeNumRAShift(&delta, minShift);
}
v_CalcParam.a1 = a1.u.s32.u[0];
v_CalcParam.b1 = b1.u.s32.u[0];
v_CalcParam.c1 = c1.u.s32.u[0];
v_CalcParam.a2 = a2.u.s32.u[0];
v_CalcParam.b2 = b2.u.s32.u[0];
v_CalcParam.c2 = c2.u.s32.u[0];
v_CalcParam.delta = delta.u.s32.u[0]; // Don't allow delta to be zero, since it gets used as a divisor
if( ! v_CalcParam.delta )
{
RETAILMSG(1,(__TEXT("TouchPanelSetCalibration: delta of 0 invalid\r\n")));
RETAILMSG(1,(__TEXT("\tCalibration failed.\r\n")));
v_CalcParam.delta = 1; // any non-zero value to prevents DivByZero traps later
v_Calibrated = FALSE;
}
else
v_Calibrated = TRUE; return ErrorAnalysis(
cCalibrationPoints,
pScreenXBuffer,
pScreenYBuffer,
pUncalXBuffer,
pUncalYBuffer
);
} /*++Routine Description: Initializes the calibration info which is used to convert uncalibrated
points to calibrated points.
Autodoc Information: @doc INTERNAL DRIVERS MDD TOUCH_DRIVER
@func VOID | TouchPanelSetCalibration |
Initializes the calibration info which is used to convert uncalibrated
points to calibrated points. @comm
The information being initialized in vCalcParam is:<nl> a1<nl>
b1<nl>
c1<nl>
a2<nl>
b2<nl>
c2<nl>
delta<nl> @devnote This is the 2D version of the transform. A simpler 1D transform
can be found in the mdd code. The preprocessor variable
TWO_DIMENSIONAL_CALIBRATION can be used to select which of
the transforms will be used.<nl> The 2D version is more complicated,
but is more accurate since it does not make the simplification
of assuming independent X and Y values.--*/
TouchPanelSetCalibration(
INT32 cCalibrationPoints, //@PARM The number of calibration points
INT32 *pScreenXBuffer, //@PARM List of screen X coords displayed
INT32 *pScreenYBuffer, //@PARM List of screen Y coords displayed
INT32 *pUncalXBuffer, //@PARM List of X coords collected
INT32 *pUncalYBuffer //@PARM List of Y coords collected
)
{
LARGENUM a11;
LARGENUM a21, a22;
LARGENUM a31, a32, a33;
LARGENUM b11, b12, b13;
LARGENUM b21, b22, b23;
LARGENUM lnScreenX;
LARGENUM lnScreenY;
LARGENUM lnTouchX;
LARGENUM lnTouchY;
LARGENUM lnTemp;
LARGENUM delta;
LARGENUM a1, b1, c1;
LARGENUM a2, b2, c2;
MATRIX33 Matrix;
INT32 cShift;
INT32 minShift;
int i;
DEBUGMSG(1,(__TEXT("calibrating %d point set\r\n"), cCalibrationPoints)); //
// If the calibration data is being cleared, set the flag so
// that the conversion operation is a noop.
// if ( cCalibrationPoints == 0 )
{
v_Calibrated = FALSE;
return TRUE;
} //
// Compute these large numbers
//
LargeNumSet(&a11, 0);
LargeNumSet(&a21, 0);
LargeNumSet(&a31, 0);
LargeNumSet(&a22, 0);
LargeNumSet(&a32, 0);
LargeNumSet(&a33, cCalibrationPoints);
LargeNumSet(&b11, 0);
LargeNumSet(&b12, 0);
LargeNumSet(&b13, 0);
LargeNumSet(&b21, 0);
LargeNumSet(&b22, 0);
LargeNumSet(&b23, 0);
for(i=0; i<cCalibrationPoints; i++){
LargeNumSet(&lnTouchX, pUncalXBuffer[i]);
LargeNumSet(&lnTouchY, pUncalYBuffer[i]);
LargeNumSet(&lnScreenX, pScreenXBuffer[i]);
LargeNumSet(&lnScreenY, pScreenYBuffer[i]);
LargeNumMult(&lnTouchX, &lnTouchX, &lnTemp);
LargeNumAdd(&a11, &lnTemp, &a11);
LargeNumMult(&lnTouchX, &lnTouchY, &lnTemp);
LargeNumAdd(&a21, &lnTemp, &a21);
LargeNumAdd(&a31, &lnTouchX, &a31);
LargeNumMult(&lnTouchY, &lnTouchY, &lnTemp);
LargeNumAdd(&a22, &lnTemp, &a22);
LargeNumAdd(&a32, &lnTouchY, &a32);
LargeNumMult(&lnTouchX, &lnScreenX, &lnTemp);
LargeNumAdd(&b11, &lnTemp, &b11);
LargeNumMult(&lnTouchY, &lnScreenX, &lnTemp);
LargeNumAdd(&b12, &lnTemp, &b12);
LargeNumAdd(&b13, &lnScreenX, &b13);
LargeNumMult(&lnTouchX, &lnScreenY, &lnTemp);
LargeNumAdd(&b21, &lnTemp, &b21);
LargeNumMult(&lnTouchY, &lnScreenY, &lnTemp);
LargeNumAdd(&b22, &lnTemp, &b22);
LargeNumAdd(&b23, &lnScreenY, &b23);
} Matrix.pa11 = &a11;
Matrix.pa21 = &a21;
Matrix.pa31 = &a31;
Matrix.pa12 = &a21;
Matrix.pa22 = &a22;
Matrix.pa32 = &a32;
Matrix.pa13 = &a31;
Matrix.pa23 = &a32;
Matrix.pa33 = &a33;
ComputeMatrix33(&delta, &Matrix); Matrix.pa11 = &b11;
Matrix.pa21 = &b12;
Matrix.pa31 = &b13;
ComputeMatrix33(&a1, &Matrix); Matrix.pa11 = &a11;
Matrix.pa21 = &a21;
Matrix.pa31 = &a31;
Matrix.pa12 = &b11;
Matrix.pa22 = &b12;
Matrix.pa32 = &b13;
ComputeMatrix33(&b1, &Matrix); Matrix.pa12 = &a21;
Matrix.pa22 = &a22;
Matrix.pa32 = &a32;
Matrix.pa13 = &b11;
Matrix.pa23 = &b12;
Matrix.pa33 = &b13;
ComputeMatrix33(&c1, &Matrix); Matrix.pa13 = &a31;
Matrix.pa23 = &a32;
Matrix.pa33 = &a33;
Matrix.pa11 = &b21;
Matrix.pa21 = &b22;
Matrix.pa31 = &b23;
ComputeMatrix33(&a2, &Matrix); Matrix.pa11 = &a11;
Matrix.pa21 = &a21;
Matrix.pa31 = &a31;
Matrix.pa12 = &b21;
Matrix.pa22 = &b22;
Matrix.pa32 = &b23;
ComputeMatrix33(&b2, &Matrix); Matrix.pa12 = &a21;
Matrix.pa22 = &a22;
Matrix.pa32 = &a32;
Matrix.pa13 = &b21;
Matrix.pa23 = &b22;
Matrix.pa33 = &b23;
ComputeMatrix33(&c2, &Matrix);#if 1
{
LARGENUM halfDelta;
//
// Take care of possible truncation error in later mapping operations
//
if(IsLargeNumNegative(&delta)){
LargeNumDivInt32(&delta, -2, &halfDelta);
} else {
LargeNumDivInt32(&delta, 2, &halfDelta);
}
LargeNumAdd(&c1, &halfDelta, &c1);
LargeNumAdd(&c2, &halfDelta, &c2);
}
#endif //
// All the numbers are determined now.
// Let's scale them back to 32 bit world
//
minShift = 0;
cShift = LargeNumBits(&a1) - MAX_COEFF_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&b1) - MAX_COEFF_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&a2) - MAX_COEFF_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&b2) - MAX_COEFF_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&c1) - MAX_TERM_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&c2) - MAX_TERM_PRECISION;
if(cShift > minShift){
minShift = cShift;
}
cShift = LargeNumBits(&delta) - 31;
if(cShift > minShift){
minShift = cShift;
} //
// Now, shift count is determined, shift all the numbers
// right to obtain the 32-bit signed values
//
if(minShift){
LargeNumRAShift(&a1, minShift);
LargeNumRAShift(&a2, minShift);
LargeNumRAShift(&b1, minShift);
LargeNumRAShift(&b2, minShift);
LargeNumRAShift(&c1, minShift);
LargeNumRAShift(&c2, minShift);
LargeNumRAShift(&delta, minShift);
}
v_CalcParam.a1 = a1.u.s32.u[0];
v_CalcParam.b1 = b1.u.s32.u[0];
v_CalcParam.c1 = c1.u.s32.u[0];
v_CalcParam.a2 = a2.u.s32.u[0];
v_CalcParam.b2 = b2.u.s32.u[0];
v_CalcParam.c2 = c2.u.s32.u[0];
v_CalcParam.delta = delta.u.s32.u[0]; // Don't allow delta to be zero, since it gets used as a divisor
if( ! v_CalcParam.delta )
{
RETAILMSG(1,(__TEXT("TouchPanelSetCalibration: delta of 0 invalid\r\n")));
RETAILMSG(1,(__TEXT("\tCalibration failed.\r\n")));
v_CalcParam.delta = 1; // any non-zero value to prevents DivByZero traps later
v_Calibrated = FALSE;
}
else
v_Calibrated = TRUE; return ErrorAnalysis(
cCalibrationPoints,
pScreenXBuffer,
pScreenYBuffer,
pUncalXBuffer,
pUncalYBuffer
);
} /*++Routine Description: Initializes the calibration info which is used to convert uncalibrated
points to calibrated points.
Autodoc Information: @doc INTERNAL DRIVERS MDD TOUCH_DRIVER
@func VOID | TouchPanelSetCalibration |
Initializes the calibration info which is used to convert uncalibrated
points to calibrated points. @comm
The information being initialized in vCalcParam is:<nl> a1<nl>
b1<nl>
c1<nl>
a2<nl>
b2<nl>
c2<nl>
delta<nl> @devnote This is the 2D version of the transform. A simpler 1D transform
can be found in the mdd code. The preprocessor variable
TWO_DIMENSIONAL_CALIBRATION can be used to select which of
the transforms will be used.<nl> The 2D version is more complicated,
but is more accurate since it does not make the simplification
of assuming independent X and Y values.--*/
b - points to the large multiplier.
pResult - Points to the a large integer buffer to receive the difference.Return Value: The same pointer as pResult.Note: The sign of the returned large number is set according to the
multiplication result.--*/
PLARGENUM
LargeNumMult(
PLARGENUM pNum1,
PLARGENUM pNum2,
PLARGENUM pResult
)
{
LARGENUM lNumTemp;
LARGENUM lNumSum;
LARGENUM lNumCarry;
int i;
int j; LargeNumSet(&lNumCarry, 0);
for(i=0; i<SIZE_OF_LARGENUM; i++){
LargeNumSet(&lNumSum, 0);
for(j=0; j<=i; j++){
LargeNumMulUint32(pNum1->u.s32.u[j], pNum2->u.s32.u[i-j], &lNumTemp);
LargeNumMagAdd(&lNumTemp, &lNumSum, &lNumSum);
}
LargeNumMagAdd(&lNumCarry, &lNumSum, &lNumSum);
for(j=0; j<SIZE_OF_LARGENUM-1; j++){
lNumCarry.u.s32.u[j] = lNumSum.u.s32.u[j+1];
}
pResult->u.s32.u[i] = lNumSum.u.s32.u[0];
} if(!IsLargeNumNotZero(pResult)){
pResult->fNegative = FALSE;
} else {
pResult->fNegative = (pNum1->fNegative != pNum2->fNegative);
}
return pResult;
}VOID
ComputeMatrix33(
PLARGENUM pResult,
PMATRIX33 pMatrix
)
{
LARGENUM lnTemp; LargeNumMult(pMatrix->pa11, pMatrix->pa22, &lnTemp);
LargeNumMult(pMatrix->pa33, &lnTemp, pResult);
LargeNumMult(pMatrix->pa21, pMatrix->pa32, &lnTemp);
LargeNumMult(pMatrix->pa13, &lnTemp, &lnTemp);
LargeNumAdd(pResult, &lnTemp, pResult);
LargeNumMult(pMatrix->pa12, pMatrix->pa23, &lnTemp);
LargeNumMult(pMatrix->pa31, &lnTemp, &lnTemp);
LargeNumAdd(pResult, &lnTemp, pResult);
LargeNumMult(pMatrix->pa13, pMatrix->pa22, &lnTemp);
LargeNumMult(pMatrix->pa31, &lnTemp, &lnTemp);
LargeNumSub(pResult, &lnTemp, pResult);
LargeNumMult(pMatrix->pa12, pMatrix->pa21, &lnTemp);
LargeNumMult(pMatrix->pa33, &lnTemp, &lnTemp);
LargeNumSub(pResult, &lnTemp, pResult);
LargeNumMult(pMatrix->pa23, pMatrix->pa32, &lnTemp);
LargeNumMult(pMatrix->pa11, &lnTemp, &lnTemp);
LargeNumSub(pResult, &lnTemp, pResult);
}