
Demo touching the perimeter of a circle
main.cpp@1:e4f92c21e329, 2021-04-04 (annotated)
- 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?
User | Revision | Line number | New 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 | } |