I am trying to create a GUI joystick where I draw a circle and everything inside the circle is a variable. While it is easy to detect a touchpoint inside a rectangle, a circle is proving to be difficult. I know I could just make a square inside of my circle but since it is such a large circle that would not work. I thought I could use pythagorean theorem a^2 + b^2 = c^2 and that is what's in my code but it is still choosing a touchpoint outside my circle. I could split it into a bunch of triangles but the memory on a UNO is limited so i'm trying to keep it simple. Here is what I have so far.
#include <Adafruit_GFX.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_ILI9341.h>
#include <Adafruit_STMPE610.h>
// This is calibration data for the raw touch data to the screen coordinates
#define TS_MINX 150
#define TS_MINY 130
#define TS_MAXX 3800
#define TS_MAXY 4000
#define STMPE_CS 8
Adafruit_STMPE610 ts = Adafruit_STMPE610(STMPE_CS);
#define TFT_CS 10
#define TFT_DC 9
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
#define JOYSTICK_X 90 // X= ---->
#define JOYSTICK_Y 150 // Y= ---- UP/DN
#define JOYSTICK_R 30 // JOYSTICK RADIUS
#define KNOB_W 10 // KNOB RADIUS
#define FRAME_W 90 // OUTER RIM RADIUS
int x;
int y;
void drawFrame()
{
//tft.drawCircle(JOYSTICK_X, JOYSTICK_Y, JOYSTICK_R, ILI9341_GREEN);
tft.fillCircle(JOYSTICK_X, JOYSTICK_Y, JOYSTICK_R, 0x07e0);
tft.drawCircle(JOYSTICK_X, JOYSTICK_Y, FRAME_W, 0x0000);
//tft.drawCircle(JOYSTICK_X, JOYSTICK_Y, KNOB_W, ILI9341_BLACK);
tft.fillCircle(JOYSTICK_X, JOYSTICK_Y, KNOB_W, 0xf800); //color in hex
}
void setup(void)
{
Serial.begin(9600);
tft.begin();
if (!ts.begin()) {
Serial.println("Unable to start touchscreen.");
}
else {
Serial.println("Touchscreen started.");
}
tft.fillScreen(ILI9341_BLUE);
// origin = left,top landscape (USB left upper)
tft.setRotation(1);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.setCursor(160,10); tft.println("X = ");
tft.setCursor(160,30); tft.println("Y = ");
drawFrame();
}
void loop(){
// See if there's any touch data
if (!ts.bufferEmpty())
{
// Retrieve a point
TS_Point p = ts.getPoint();
// Scale using the calibration #'s
// and rotate coordinate system
p.x = map(p.x, TS_MINY, TS_MAXY, 0, tft.height());
p.y = map(p.y, TS_MINX, TS_MAXX, 0, tft.width());
int y = tft.height() - p.x;
int x = p.y;
if ((x*x) + (y*y) <= (FRAME_W * FRAME_W)){ // BEGINNING OF JOYSTICK DECECTION
tft.fillCircle(JOYSTICK_X,JOYSTICK_Y,KNOB_W,0XF800); //RED
}
tft.setTextSize(2);
tft.setTextColor(0XFFFF); //WHITE
tft.setCursor(200,10); tft.println(x);
tft.setCursor(200,30); tft.println(y);
delay(10);
tft.setTextColor(0X001F);
tft.setCursor(200,10); tft.println(x);
tft.setCursor(200,30); tft.println(y);
tft.fillCircle (JOYSTICK_X,JOYSTICK_Y,KNOB_W,0X07E0); //GREEN
} // end of touch section
} // end of loop
If this worked correctly the red circle would appear anytime a touchpoint is inside the outer circle and if a touchpoint is outside the outer circle it would change back to green. But since my math is wrong that is not the case. Eventually I will move both circles along the touchpoint but I need to stay inbounds first.
Any help would be greatly appreciated.