Library for MI0283QT-2 LCD
Embed:
(wiki syntax)
Show/hide line numbers
calibrate.c
00001 /* 00002 * 00003 * Copyright (c) 2001, Carlos E. Vidales. All rights reserved. 00004 * 00005 * This sample program was written and put in the public domain 00006 * by Carlos E. Vidales. The program is provided "as is" 00007 * without warranty of any kind, either expressed or implied. 00008 * If you choose to use the program within your own products 00009 * you do so at your own risk, and assume the responsibility 00010 * for servicing, repairing or correcting the program should 00011 * it prove defective in any manner. 00012 * You may copy and distribute the program's source code in any 00013 * medium, provided that you also include in each copy an 00014 * appropriate copyright notice and disclaimer of warranty. 00015 * You may also modify this program and distribute copies of 00016 * it provided that you include prominent notices stating 00017 * that you changed the file(s) and the date of any change, 00018 * and that you do not charge any royalties or licenses for 00019 * its use. 00020 * 00021 * 00022 * 00023 * File Name: calibrate.c 00024 * 00025 * 00026 * This file contains functions that implement calculations 00027 * necessary to obtain calibration factors for a touch screen 00028 * that suffers from multiple distortion effects: namely, 00029 * translation, scaling and rotation. 00030 * 00031 * The following set of equations represent a valid display 00032 * point given a corresponding set of touch screen points: 00033 * 00034 * 00035 * /- -\ 00036 * /- -\ /- -\ | | 00037 * | | | | | Xs | 00038 * | Xd | | A B C | | | 00039 * | | = | | * | Ys | 00040 * | Yd | | D E F | | | 00041 * | | | | | 1 | 00042 * \- -/ \- -/ | | 00043 * \- -/ 00044 * 00045 * 00046 * where: 00047 * 00048 * (Xd,Yd) represents the desired display point 00049 * coordinates, 00050 * 00051 * (Xs,Ys) represents the available touch screen 00052 * coordinates, and the matrix 00053 * 00054 * /- -\ 00055 * |A,B,C| 00056 * |D,E,F| represents the factors used to translate 00057 * \- -/ the available touch screen point values 00058 * into the corresponding display 00059 * coordinates. 00060 * 00061 * 00062 * Note that for practical considerations, the utilitities 00063 * within this file do not use the matrix coefficients as 00064 * defined above, but instead use the following 00065 * equivalents, since floating point math is not used: 00066 * 00067 * A = An/Divider 00068 * B = Bn/Divider 00069 * C = Cn/Divider 00070 * D = Dn/Divider 00071 * E = En/Divider 00072 * F = Fn/Divider 00073 * 00074 * 00075 * 00076 * The functions provided within this file are: 00077 * 00078 * setCalibrationMatrix() - calculates the set of factors 00079 * in the above equation, given 00080 * three sets of test points. 00081 * getDisplayPoint() - returns the actual display 00082 * coordinates, given a set of 00083 * touch screen coordinates. 00084 * translateRawScreenCoordinates() - helper function to transform 00085 * raw screen points into values 00086 * scaled to the desired display 00087 * resolution. 00088 * 00089 * 00090 */ 00091 00092 00093 #define _CALIBRATE_C_ 00094 00095 00096 00097 /****************************************************/ 00098 /* */ 00099 /* Included files */ 00100 /* */ 00101 /****************************************************/ 00102 00103 #include "calibrate.h" 00104 00105 00106 00107 /****************************************************/ 00108 /* */ 00109 /* Local Definitions and macros */ 00110 /* */ 00111 /****************************************************/ 00112 00113 00114 00115 /****************************************************/ 00116 /* */ 00117 /* Global variables */ 00118 /* */ 00119 /****************************************************/ 00120 00121 00122 00123 /****************************************************/ 00124 /* */ 00125 /* Forward Declaration of local functions */ 00126 /* */ 00127 /****************************************************/ 00128 00129 00130 00131 00132 00133 00134 /********************************************************************** 00135 * 00136 * Function: setCalibrationMatrix() 00137 * 00138 * Description: Calling this function with valid input data 00139 * in the display and screen input arguments 00140 * causes the calibration factors between the 00141 * screen and display points to be calculated, 00142 * and the output argument - matrixPtr - to be 00143 * populated. 00144 * 00145 * This function needs to be called only when new 00146 * calibration factors are desired. 00147 * 00148 * 00149 * Argument(s): displayPtr (input) - Pointer to an array of three 00150 * sample, reference points. 00151 * screenPtr (input) - Pointer to the array of touch 00152 * screen points corresponding 00153 * to the reference display points. 00154 * matrixPtr (output) - Pointer to the calibration 00155 * matrix computed for the set 00156 * of points being provided. 00157 * 00158 * 00159 * From the article text, recall that the matrix coefficients are 00160 * resolved to be the following: 00161 * 00162 * 00163 * Divider = (Xs0 - Xs2)*(Ys1 - Ys2) - (Xs1 - Xs2)*(Ys0 - Ys2) 00164 * 00165 * 00166 * 00167 * (Xd0 - Xd2)*(Ys1 - Ys2) - (Xd1 - Xd2)*(Ys0 - Ys2) 00168 * A = --------------------------------------------------- 00169 * Divider 00170 * 00171 * 00172 * (Xs0 - Xs2)*(Xd1 - Xd2) - (Xd0 - Xd2)*(Xs1 - Xs2) 00173 * B = --------------------------------------------------- 00174 * Divider 00175 * 00176 * 00177 * Ys0*(Xs2*Xd1 - Xs1*Xd2) + 00178 * Ys1*(Xs0*Xd2 - Xs2*Xd0) + 00179 * Ys2*(Xs1*Xd0 - Xs0*Xd1) 00180 * C = --------------------------------------------------- 00181 * Divider 00182 * 00183 * 00184 * (Yd0 - Yd2)*(Ys1 - Ys2) - (Yd1 - Yd2)*(Ys0 - Ys2) 00185 * D = --------------------------------------------------- 00186 * Divider 00187 * 00188 * 00189 * (Xs0 - Xs2)*(Yd1 - Yd2) - (Yd0 - Yd2)*(Xs1 - Xs2) 00190 * E = --------------------------------------------------- 00191 * Divider 00192 * 00193 * 00194 * Ys0*(Xs2*Yd1 - Xs1*Yd2) + 00195 * Ys1*(Xs0*Yd2 - Xs2*Yd0) + 00196 * Ys2*(Xs1*Yd0 - Xs0*Yd1) 00197 * F = --------------------------------------------------- 00198 * Divider 00199 * 00200 * 00201 * Return: OK - the calibration matrix was correctly 00202 * calculated and its value is in the 00203 * output argument. 00204 * NOT_OK - an error was detected and the 00205 * function failed to return a valid 00206 * set of matrix values. 00207 * The only time this sample code returns 00208 * NOT_OK is when Divider == 0 00209 * 00210 * 00211 * 00212 * NOTE! NOTE! NOTE! 00213 * 00214 * setCalibrationMatrix() and getDisplayPoint() will do fine 00215 * for you as they are, provided that your digitizer 00216 * resolution does not exceed 10 bits (1024 values). Higher 00217 * resolutions may cause the integer operations to overflow 00218 * and return incorrect values. If you wish to use these 00219 * functions with digitizer resolutions of 12 bits (4096 00220 * values) you will either have to a) use 64-bit signed 00221 * integer variables and math, or b) judiciously modify the 00222 * operations to scale results by a factor of 2 or even 4. 00223 * 00224 * 00225 */ 00226 unsigned char setCalibrationMatrix( POINT * displayPtr, 00227 POINT * screenPtr, 00228 MATRIX * matrixPtr) 00229 { 00230 00231 unsigned char retValue = OK ; 00232 00233 00234 00235 matrixPtr->Divider = ((screenPtr[0].x - screenPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - 00236 ((screenPtr[1].x - screenPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; 00237 00238 if( matrixPtr->Divider == 0 ) 00239 { 00240 retValue = NOT_OK ; 00241 } 00242 else 00243 { 00244 matrixPtr->An = ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].y - screenPtr[2].y)) - 00245 ((displayPtr[1].x - displayPtr[2].x) * (screenPtr[0].y - screenPtr[2].y)) ; 00246 00247 matrixPtr->Bn = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].x - displayPtr[2].x)) - 00248 ((displayPtr[0].x - displayPtr[2].x) * (screenPtr[1].x - screenPtr[2].x)) ; 00249 00250 matrixPtr->Cn = (screenPtr[2].x * displayPtr[1].x - screenPtr[1].x * displayPtr[2].x) * screenPtr[0].y + 00251 (screenPtr[0].x * displayPtr[2].x - screenPtr[2].x * displayPtr[0].x) * screenPtr[1].y + 00252 (screenPtr[1].x * displayPtr[0].x - screenPtr[0].x * displayPtr[1].x) * screenPtr[2].y ; 00253 00254 matrixPtr->Dn = ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].y - screenPtr[2].y)) - 00255 ((displayPtr[1].y - displayPtr[2].y) * (screenPtr[0].y - screenPtr[2].y)) ; 00256 00257 matrixPtr->En = ((screenPtr[0].x - screenPtr[2].x) * (displayPtr[1].y - displayPtr[2].y)) - 00258 ((displayPtr[0].y - displayPtr[2].y) * (screenPtr[1].x - screenPtr[2].x)) ; 00259 00260 matrixPtr->Fn = (screenPtr[2].x * displayPtr[1].y - screenPtr[1].x * displayPtr[2].y) * screenPtr[0].y + 00261 (screenPtr[0].x * displayPtr[2].y - screenPtr[2].x * displayPtr[0].y) * screenPtr[1].y + 00262 (screenPtr[1].x * displayPtr[0].y - screenPtr[0].x * displayPtr[1].y) * screenPtr[2].y ; 00263 } 00264 00265 return( retValue ) ; 00266 00267 } /* end of setCalibrationMatrix() */ 00268 00269 00270 00271 /********************************************************************** 00272 * 00273 * Function: getDisplayPoint() 00274 * 00275 * Description: Given a valid set of calibration factors and a point 00276 * value reported by the touch screen, this function 00277 * calculates and returns the true (or closest to true) 00278 * display point below the spot where the touch screen 00279 * was touched. 00280 * 00281 * 00282 * 00283 * Argument(s): displayPtr (output) - Pointer to the calculated 00284 * (true) display point. 00285 * screenPtr (input) - Pointer to the reported touch 00286 * screen point. 00287 * matrixPtr (input) - Pointer to calibration factors 00288 * matrix previously calculated 00289 * from a call to 00290 * setCalibrationMatrix() 00291 * 00292 * 00293 * The function simply solves for Xd and Yd by implementing the 00294 * computations required by the translation matrix. 00295 * 00296 * /- -\ 00297 * /- -\ /- -\ | | 00298 * | | | | | Xs | 00299 * | Xd | | A B C | | | 00300 * | | = | | * | Ys | 00301 * | Yd | | D E F | | | 00302 * | | | | | 1 | 00303 * \- -/ \- -/ | | 00304 * \- -/ 00305 * 00306 * It must be kept brief to avoid consuming CPU cycles. 00307 * 00308 * 00309 * Return: OK - the display point was correctly calculated 00310 * and its value is in the output argument. 00311 * NOT_OK - an error was detected and the function 00312 * failed to return a valid point. 00313 * 00314 * 00315 * 00316 * NOTE! NOTE! NOTE! 00317 * 00318 * setCalibrationMatrix() and getDisplayPoint() will do fine 00319 * for you as they are, provided that your digitizer 00320 * resolution does not exceed 10 bits (1024 values). Higher 00321 * resolutions may cause the integer operations to overflow 00322 * and return incorrect values. If you wish to use these 00323 * functions with digitizer resolutions of 12 bits (4096 00324 * values) you will either have to a) use 64-bit signed 00325 * integer variables and math, or b) judiciously modify the 00326 * operations to scale results by a factor of 2 or even 4. 00327 * 00328 * 00329 */ 00330 unsigned char getDisplayPoint( POINT * displayPtr, 00331 POINT * screenPtr, 00332 MATRIX * matrixPtr ) 00333 { 00334 unsigned char retValue = OK ; 00335 00336 00337 if( matrixPtr->Divider != 0 ) 00338 { 00339 00340 /* Operation order is important since we are doing integer */ 00341 /* math. Make sure you add all terms together before */ 00342 /* dividing, so that the remainder is not rounded off */ 00343 /* prematurely. */ 00344 00345 displayPtr->x = ( (matrixPtr->An * screenPtr->x) + 00346 (matrixPtr->Bn * screenPtr->y) + 00347 matrixPtr->Cn 00348 ) / matrixPtr->Divider ; 00349 00350 displayPtr->y = ( (matrixPtr->Dn * screenPtr->x) + 00351 (matrixPtr->En * screenPtr->y) + 00352 matrixPtr->Fn 00353 ) / matrixPtr->Divider ; 00354 } 00355 else 00356 { 00357 retValue = NOT_OK ; 00358 } 00359 00360 return( retValue ) ; 00361 00362 } /* end of getDisplayPoint() */ 00363
Generated on Fri Jul 15 2022 19:54:13 by 1.7.2