Определение того, находится ли указанная пользователем точка внутри 2-го многоугольника - PullRequest
0 голосов
/ 19 ноября 2018

Я провел некоторое исследование, и есть много способов сделать это, если вершины и точки предопределены, как видно здесь .Однако в моем случае все указано пользователем.Код, который я собрал (с помощью других), позволяет пользователю создавать многоугольник и размещать точки.Я написал функции, чтобы попытаться создать векторы от точки до вершин, а затем вычислить угол.Если дело доходит до 360, оно должно быть внутри, и оно должно быть зеленого цвета.Иначе он должен быть снаружи и красным.

Это то, над чем я работал, но я не могу понять это: (Редактировать: Включен весь мой код)

GLint vert[100][2];
int width = 400, height = 600, n = 0, m = 0, type = GL_LINE_STRIP, v;
bool rubberbanding = false;
bool closed = false;

double testx, testy;
bool isitin;

double dotp(double x1, double y1, double x2, double y2) {
    double a;
    a = (x1 * x2) + (y1 * y2);
    return a;
}

double mag(double x1, double y1, double x2, double y2) {
    double a;
    double x = (x2 - x1);
    double y = (y2 - y1);
    a = sqrt((x*x) + (y*y));
    return a;
}


bool inpoly(int numv, GLint vx[][2], GLint vy[][2], double tx, double ty) {
    double angle = 0.0;
    int n = 0;
    while (n != numv) {
        //vector from point to vertex
        double newv1x = vx[n][0] - tx;
        double newv1y = vy[n][1] - ty;
        double magv1 = mag(tx, ty, vx[n][0], vy[n][1]); //magnitude of vector

        //vector from point to next vertex
        double newv2x = vx[n + 1][0] - tx;
        double newv2y = vy[n + 1][1] - ty;
        double magv2 = mag(tx, ty, vx[n+1][0], vy[n+1][1]);//magnitude of vector

        //dot product between the two vectors
        double dp = dotp(newv1x, newv1y, newv2x, newv2y);

        //angle between two vectors
        double vang = acos(dp / (magv1*magv2));

        angle += vang;

        n++;
    }

    //vector from point to last vertex
    double newv1x = vx[numv][0] - tx;
    double newv1y = vy[numv][1] - ty;
    double magv1 = mag(tx, ty, vx[numv][0], vy[numv][1]); //magnitude of vector

    //vector from point to first vertex
    double newv2x = vx[0][0] - tx;
    double newv2y = vy[0][1] - ty;
    double magv2 = mag(tx, ty, vx[0][0], vy[0][1]);//magnitude of vector

    //dot product between the two vectors
    double dp = dotp(newv1x, newv1y, newv2x, newv2y);

    //angle between two vectors
    double vang = acos(dp / (magv1*magv2));

    angle += vang;

    if (angle == 360.0) return true;

    return false;

}




void display(){
     glClear(GL_COLOR_BUFFER_BIT);
     glColor3f(1, 1, 0);
     glBegin(closed ? GL_LINE_LOOP : GL_LINE_STRIP);
     for(int i = 0; i < m; i++){
             glVertex2iv(vert[i]);
     }
     glEnd();
     /*
     glColor3f(0, 0, 1);
     glBegin(GL_POINTS);
     for (int i = m; i < n; i++) {
         glVertex2iv(vert[i]);
     }
     */

     isitin = inpoly(m, vert, vert, testx, testy);

     if (isitin == true) {
         glColor3f(0, 1, 0);
         glBegin(GL_POINTS);
         for (int i = m; i < n; i++) {
             glVertex2iv(vert[i]);
         }
     }
     else {
         glColor3f(1, 0, 0);
         glBegin(GL_POINTS);
         for (int i = m; i < n; i++) {
             glVertex2iv(vert[i]);
         }
     }

     glEnd();
     glutSwapBuffers();
     glutPostRedisplay();
}

void keyboard(unsigned char key, int x, int y){
     switch(key){
                 case 'r': n = 0; m = 0; closed = false; break;

                 case 'c': closed = true; break;
     }
     glutPostRedisplay();
}

int findVertex(int x, int y){
    int dx, dy;
    for(int i = 0; i < n; i++){
            dx = vert[i][0] - x;
            dy = vert[i][1] - y;
            if(dx*dx + dy*dy < 16) return i;
    }
    return - 1;
}

void mousemove(int x, int y)
{
    testx = x;
    testy = height - 1 - y;
}

void mouse(int button, int state, int x, int y){
     switch(button){
     case GLUT_LEFT_BUTTON:
                         if(state == GLUT_DOWN){
                             if (n < 100) {
                                v = n++;
                                vert[v][0] = x;
                                 vert[v][1] = height - 1 - y;

                                // n++;
                                 rubberbanding = true;
                                 glutPostRedisplay();

                                 if (!closed) m = n;
                             }
                         }
                         else{
                                  rubberbanding = false;
                         }
                         break;
     }
}
void motion(int x, int y){
     if(rubberbanding){
                       vert[v][0] = x;
                       vert[v][1] = height - 1 - y;
                       glutPostRedisplay();
     }
}

void main(int argc, char** argv){
     glutInit(&argc, argv);
     glutInitDisplayMode(GLUT_RGB|GLUT_DOUBLE);
     glutInitWindowSize(width,height);
     glutInitWindowPosition(50,100);
     glutCreateWindow("Project 3");
     glClearColor(0.0,0.0,0.0,0.0);
     glColor3f( 1, 1, 0);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     gluOrtho2D(0, width, 0, height);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     glutDisplayFunc(display);
     glutKeyboardFunc(keyboard);
     glutMouseFunc(mouse);
     glutPassiveMotionFunc(mousemove);
     glutMotionFunc(motion);
     glutMainLoop();
}

When I run the program in Visual Studio, I can draw the polygon, and I can specify

точки, но по какой-то причине все точки кажутся красными.Если у кого-то есть идеи, как это исправить, это будет с благодарностью.

1 Ответ

0 голосов
/ 19 ноября 2018

Возможно, ваша ошибка в том, что acos возвращает в радианах, и вы проверяете, равна ли сумма 360 градусам.

Кроме того, вы не должны сравнивать удвоения таким образом, так как эти вычисления, вероятно, добавляют ошибку округления в каждую сумму. См. здесь для получения дополнительной информации.

...