Demo touching the perimeter of a circle

Dependencies:   RA8875

Committer:
WiredHome
Date:
Sun Apr 04 17:17:02 2021 +0000
Revision:
1:e4f92c21e329
Parent:
0:f2a6447e607c
Child:
2:3077639f94fa
Documentation cleanup

Who changed what in which revision?

UserRevisionLine numberNew contents of line
WiredHome 0:f2a6447e607c 1 ///
WiredHome 0:f2a6447e607c 2 /// RA8875 display library example where a user touch on the perimeter
WiredHome 0:f2a6447e607c 3 /// of a circle should be detected.
WiredHome 0:f2a6447e607c 4 ///
WiredHome 0:f2a6447e607c 5 ///
WiredHome 0:f2a6447e607c 6 /// 0 deg
WiredHome 0:f2a6447e607c 7 /// -+-
WiredHome 0:f2a6447e607c 8 /// - -
WiredHome 0:f2a6447e607c 9 ///
WiredHome 0:f2a6447e607c 10 /// / \
WiredHome 0:f2a6447e607c 11 ///
WiredHome 0:f2a6447e607c 12 ///
WiredHome 0:f2a6447e607c 13 /// | |
WiredHome 0:f2a6447e607c 14 /// -90 deg + + + +90 deg
WiredHome 0:f2a6447e607c 15 /// | |
WiredHome 0:f2a6447e607c 16 ///
WiredHome 0:f2a6447e607c 17 ///
WiredHome 0:f2a6447e607c 18 /// \ /
WiredHome 0:f2a6447e607c 19 ///
WiredHome 0:f2a6447e607c 20 ///
WiredHome 0:f2a6447e607c 21 /// - -
WiredHome 0:f2a6447e607c 22 /// -+-
WiredHome 0:f2a6447e607c 23 /// +180 deg
WiredHome 0:f2a6447e607c 24 ///
WiredHome 0:f2a6447e607c 25 ///
WiredHome 0:f2a6447e607c 26 /// NOTE NOTE NOTE NOTE NOTE NOTE
WiredHome 0:f2a6447e607c 27 ///
WiredHome 0:f2a6447e607c 28 /// The code in this example would greatly benefit by refactoring to
WiredHome 0:f2a6447e607c 29 /// use radians, rather than degrees. Further, the coordinate system
WiredHome 0:f2a6447e607c 30 /// desired here is more like a clock-face, with 0 degrees is straight
WiredHome 0:f2a6447e607c 31 /// up and increasing angle in the clockwise direction.
WiredHome 0:f2a6447e607c 32 ///
WiredHome 0:f2a6447e607c 33 /// There are a few transformations (direction of rotation and angle
WiredHome 0:f2a6447e607c 34 /// offset) that didn't "feel right", even with the right result.
WiredHome 0:f2a6447e607c 35 ///
WiredHome 1:e4f92c21e329 36 /// NOTE NOTE NOTE NOTE NOTE NOTE
WiredHome 1:e4f92c21e329 37 ///
WiredHome 1:e4f92c21e329 38 /// I didn't pay too much attention to managing int, float, and double
WiredHome 1:e4f92c21e329 39 /// to avoid unnecessary promotion or math complexity.
WiredHome 1:e4f92c21e329 40 ///
WiredHome 0:f2a6447e607c 41 #include "mbed.h"
WiredHome 0:f2a6447e607c 42 #include "RA8875.h"
WiredHome 0:f2a6447e607c 43
WiredHome 1:e4f92c21e329 44 // Display with Capacitive Touch panel on I2C
WiredHome 0:f2a6447e607c 45 RA8875 lcd(p5,p6,p7,p12,NC, p9,p10,p13, "tft"); // MOSI,MISO,SCK,/ChipSelect,/reset, SDA,SCL,/IRQ, name
WiredHome 0:f2a6447e607c 46 //RA8875 lcd(p5,p6,p7,p8,NC, p28,p27,p30, "tft");
WiredHome 0:f2a6447e607c 47
WiredHome 1:e4f92c21e329 48 // debug serial for printf.
WiredHome 1:e4f92c21e329 49 // Some versions of the OS don't support the baud initializer here, then use device.baud(460800) in main.
WiredHome 1:e4f92c21e329 50 Serial device(USBTX,USBRX, 460800); // Initialize to a fast baud
WiredHome 1:e4f92c21e329 51 //Serial device(p26,p25);
WiredHome 0:f2a6447e607c 52
WiredHome 0:f2a6447e607c 53 // Screen size and color depth
WiredHome 0:f2a6447e607c 54 #define LCD_W 800
WiredHome 0:f2a6447e607c 55 #define LCD_H 480
WiredHome 1:e4f92c21e329 56 #define LCD_C 8 // color - bits per pixel
WiredHome 1:e4f92c21e329 57
WiredHome 1:e4f92c21e329 58 #define BL_NORM 100 // Backlight Normal setting (0 to 255)
WiredHome 0:f2a6447e607c 59
WiredHome 1:e4f92c21e329 60 //
WiredHome 0:f2a6447e607c 61 // The Circle definition around which touches are relevant
WiredHome 1:e4f92c21e329 62 //
WiredHome 0:f2a6447e607c 63 const point_t center = {200,250};
WiredHome 0:f2a6447e607c 64 const dim_t radius = 125;
WiredHome 0:f2a6447e607c 65 const dim_t touch_tolerance = 30;
WiredHome 0:f2a6447e607c 66
WiredHome 0:f2a6447e607c 67 #define PI 3.14159265359f
WiredHome 0:f2a6447e607c 68
WiredHome 0:f2a6447e607c 69 // ---------------
WiredHome 0:f2a6447e607c 70 // radius = \ / x ^ 2 + y ^ 2
WiredHome 0:f2a6447e607c 71 // \/
WiredHome 0:f2a6447e607c 72 int GetRadius(point_t touch, point_t center)
WiredHome 0:f2a6447e607c 73 {
WiredHome 0:f2a6447e607c 74 return sqrt(pow(touch.x - center.x, 2) + pow(touch.y - center.y, 2));
WiredHome 0:f2a6447e607c 75 }
WiredHome 0:f2a6447e607c 76
WiredHome 0:f2a6447e607c 77 // (radians * 180)
WiredHome 0:f2a6447e607c 78 // degrees = ---------------
WiredHome 0:f2a6447e607c 79 // pi
WiredHome 0:f2a6447e607c 80 float Degrees(float radians)
WiredHome 0:f2a6447e607c 81 {
WiredHome 0:f2a6447e607c 82 return radians * 180 / PI;
WiredHome 0:f2a6447e607c 83 }
WiredHome 0:f2a6447e607c 84
WiredHome 0:f2a6447e607c 85 // (pi * degrees)
WiredHome 0:f2a6447e607c 86 // radians = --------------
WiredHome 0:f2a6447e607c 87 // 180
WiredHome 0:f2a6447e607c 88 float Radians(float degrees)
WiredHome 0:f2a6447e607c 89 {
WiredHome 0:f2a6447e607c 90 return (degrees * PI)/180;
WiredHome 0:f2a6447e607c 91 }
WiredHome 0:f2a6447e607c 92
WiredHome 0:f2a6447e607c 93 int GetAngle(point_t touch, point_t center)
WiredHome 0:f2a6447e607c 94 {
WiredHome 0:f2a6447e607c 95 int angle = 180 - Degrees(atan2(touch.x - center.x, touch.y - center.y));
WiredHome 0:f2a6447e607c 96 if (angle < 0)
WiredHome 0:f2a6447e607c 97 angle += 360;
WiredHome 0:f2a6447e607c 98 return angle;
WiredHome 0:f2a6447e607c 99 }
WiredHome 0:f2a6447e607c 100
WiredHome 0:f2a6447e607c 101 // From a starting point, and at a given angle (where 0 is straight up),
WiredHome 0:f2a6447e607c 102 // and clockwise is increasing angle,
WiredHome 0:f2a6447e607c 103 // project a given distance at that angle and return those coordinates.
WiredHome 0:f2a6447e607c 104 //
WiredHome 0:f2a6447e607c 105 point_t ProjectPoint(point_t start, int angle, dim_t distance)
WiredHome 0:f2a6447e607c 106 {
WiredHome 0:f2a6447e607c 107 point_t newPoint;
WiredHome 0:f2a6447e607c 108 float radians = Radians(angle); // radians are rooted in 0 to the right, and increasing counterclockwise
WiredHome 0:f2a6447e607c 109 radians = -radians + Radians(90); // reverse direction and 0 at the top
WiredHome 0:f2a6447e607c 110 //device.printf("adj Radians %4.3f\r\n", radians);
WiredHome 0:f2a6447e607c 111 newPoint.x = start.x + distance * sin(radians);
WiredHome 0:f2a6447e607c 112 newPoint.y = start.y - distance * cos(radians);
WiredHome 0:f2a6447e607c 113 return newPoint;
WiredHome 0:f2a6447e607c 114 }
WiredHome 0:f2a6447e607c 115
WiredHome 0:f2a6447e607c 116
WiredHome 0:f2a6447e607c 117 int main()
WiredHome 0:f2a6447e607c 118 {
WiredHome 1:e4f92c21e329 119 //device.baud(460800);
WiredHome 1:e4f92c21e329 120 printf("\r\n RA8875 Touch Dial Example - Build " __DATE__ " " __TIME__ "\r\n");
WiredHome 1:e4f92c21e329 121 printf("MBED v%d.%d.%d\r\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
WiredHome 0:f2a6447e607c 122
WiredHome 0:f2a6447e607c 123 lcd.init(LCD_W,LCD_H,LCD_C,BL_NORM);
WiredHome 0:f2a6447e607c 124 lcd.TouchPanelInit();
WiredHome 0:f2a6447e607c 125
WiredHome 0:f2a6447e607c 126 lcd.foreground(White); // Change to white
WiredHome 0:f2a6447e607c 127 lcd.printf("RA8875 Touch Dial Example - Build " __DATE__ " " __TIME__ "\r\n");
WiredHome 0:f2a6447e607c 128 lcd.printf("MBED v%d.%d.%d\r\n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION);
WiredHome 0:f2a6447e607c 129
WiredHome 1:e4f92c21e329 130 // Draw a thickened circle
WiredHome 1:e4f92c21e329 131 for (int r = 0; r <= 3; r++) {
WiredHome 0:f2a6447e607c 132 lcd.ellipse(center.x, center.y, radius + r, radius + r, BrightBlue);
WiredHome 0:f2a6447e607c 133 }
WiredHome 0:f2a6447e607c 134
WiredHome 0:f2a6447e607c 135 while (1) {
WiredHome 0:f2a6447e607c 136 TouchCode_t touched;
WiredHome 0:f2a6447e607c 137
WiredHome 0:f2a6447e607c 138 touched = lcd.TouchPanelReadable();
WiredHome 0:f2a6447e607c 139 if (touched) {
WiredHome 0:f2a6447e607c 140 point_t Touch = lcd.TouchCoordinates();
WiredHome 0:f2a6447e607c 141
WiredHome 0:f2a6447e607c 142 // If the touch is near the drawn circle (+/- 30 pixels),
WiredHome 0:f2a6447e607c 143 // compute the angle to the touch from the center of the circle
WiredHome 0:f2a6447e607c 144 if (abs(GetRadius(Touch, center) - radius) <= touch_tolerance) {
WiredHome 0:f2a6447e607c 145 int angle = GetAngle(Touch, center);
WiredHome 1:e4f92c21e329 146 printf("Touch at (%4d,%4d) is %3d degrees from (%4d,%4d)\r\n",
WiredHome 0:f2a6447e607c 147 Touch.x, Touch.y, angle, center.x, center.y);
WiredHome 0:f2a6447e607c 148
WiredHome 0:f2a6447e607c 149 // Fill the circle using 6° pie slices up to the angle of the touch
WiredHome 0:f2a6447e607c 150 point_t lastP = ProjectPoint(center, 90, radius); // seed it at angle 0
WiredHome 0:f2a6447e607c 151 for (int a=6; a<=360; a+=6) {
WiredHome 0:f2a6447e607c 152 point_t p = ProjectPoint(center, 90 - a, radius);
WiredHome 0:f2a6447e607c 153 color_t fillColor = (a <= angle) ? Blue : Black;
WiredHome 1:e4f92c21e329 154 //if ((a <= angle)) { // show the triangle coordinates (only the fill)
WiredHome 1:e4f92c21e329 155 // printf(" (%3d,%3d), (%3d,%3d), (%3d,%3d)\r\n",
WiredHome 1:e4f92c21e329 156 // lastP.x,lastP.y, p.x,p.y, center.x,center.y);
WiredHome 1:e4f92c21e329 157 //}
WiredHome 0:f2a6447e607c 158 lcd.filltriangle(center, p, lastP, fillColor);
WiredHome 0:f2a6447e607c 159 lastP = p;
WiredHome 0:f2a6447e607c 160 }
WiredHome 0:f2a6447e607c 161 // Show the touch point (note we're not erasing the old one)
WiredHome 0:f2a6447e607c 162 lcd.fillellipse(Touch.x, Touch.y, 5, 5, BrightRed);
WiredHome 0:f2a6447e607c 163 }
WiredHome 0:f2a6447e607c 164 }
WiredHome 0:f2a6447e607c 165 }
WiredHome 0:f2a6447e607c 166 }