zzz
zzz

Reputation: 123

How to detect whether or not the cursor is within a set of vertices?

I would like to detect whether or not the cursor is within the area of a mobile circle/disk. I've attempted to solve the problem with the code below. The if statement seems to be "functioning", as it does not report an error, but the else condition is the only output ever printed, even when the cursor is moved within the area of the circle, across its circumference, or through its center.

I am obviously missing something with regard to defining the appropriate area to detect the mouse within, but I cannot figure what. I assumed (ignorantly) that the best option would be to use the vertex coordinates defined within the glVertex2f(), but that is either obviously inaccurate or I have executed it improperly. Any assistance or guidance would be appreciated.

glBegin(GL_TRIANGLE_FAN);

    glColor3f(1, 0, 0);

    int j[5] = {100,80,60,55,50};
    int z = 1;
    float radius = j[z];
    int xoffset = radius - (2 * radius);
    int yoffset = 384;
    double x1 = xoffset + radius;
    double y1 = yoffset + radius * (sin(iteration));

    void cursor_position_callback(GLFWwindow* w, double x, double y)
    {
        FILE *f = fopen("data.txt", "a");

        if (cursor_x == (x1 + radius * cos(i)) && cursor_y == (y1 + radius * sin(i))){
        fprintf(f,"+++%0.3f: Cursor position: %f %f (%+f %+f)\n",
                glfwGetTime(),
                x, y, x - cursor_x, y - cursor_y);
        }
        else{
        fprintf(f,"---%0.3f: Cursor position: %f %f (%+f %+f)\n",
                glfwGetTime(),
                x, y, x - cursor_x, y - cursor_y);
        }
        cursor_x = x;
        cursor_y = y;
        fclose(f);
    }

    for (double i = 0; i < 2 * M_PI; i = i + ((2 * M_PI) / a))
    {

        glVertex2f(x1 + radius * cos(i), y1 + radius * sin(i));
        glfwSetCursorPosCallback(w, cursor_position_callback);

    }

    iteration += 0.01;

glEnd();
glTranslatef(1.0f,0.0f,0.0f);

Upvotes: 0

Views: 383

Answers (1)

Colonel Thirty Two
Colonel Thirty Two

Reputation: 26609

A point lies within a circle if the distance from the point to the center point of the circle is less than or equal to the circle's radius.

double dx = cursor_x - circle_x;
double dy = cursor_y - circle_y;
double dist_squared = dx*dx+dy*dy;
if(dist_squared <= radius*radius) {
    // inside circle
}

Your code has other issues:

  • Defining functions withing other functions in C is a non-portable GCC extension, and likely does not work the way you think it works (I'm pretty sure it runs into undefined behavior as soon as i leaves scope).
  • Only one function may be registered with glfwSetCursorPosCallback (or any GLFW callback function); calling glfwSetCursorPosCallback again sets the callback to the new function and discards the old one.

You need to keep a global list of circles to test against and check it in your singular cursor callback function.

Upvotes: 2

Related Questions