Пересечение точки биссектрисы с прямоугольником

Я пытался осмыслить это весь день ...

По сути, у меня есть координаты двух точек, которые всегда внутри прямоугольника. Я также знаю положение углов прямоугольника. Эти две точки входа задаются во время выполнения.

Мне нужен алгоритм, чтобы найти 2 точки, в которых биссектриса, образованная отрезком прямой между данными точками, пересекает этот прямоугольник.

image

Некоторые детали:

На изображении выше A и B даны своими координатами: A (x1, y1) и B (x2, y2). По сути, мне нужно найти положение C и D. Красный X - центр сегмента AB. Эта точка (назовем ее центром) должна быть на линии CD.

Что я сделал:

  • нашел центр:

     center.x = (A.x + Bx) / 2; 
    center.y = (A.y + By) / 2; 
     
  • найден наклон КД:

     AB_slope = Ay - By / Ax - Bx; 
    CD_slope = -1 / AB_slope; 
     

Знание центра и наклон CD дали мне уравнение CD и тому подобное, я попытался найти решение, попробовав положение точек на всех четырех границах прямоугольника. Однако по какой-то причине это не работает: каждый раз, когда у меня есть решение, скажем, для C, D отображается снаружи или наоборот.

Вот уравнения, которые я использую:

  • зная x:

     y = (CD_slope * (x - center.x)) + center.y; 
    если y> 0 && y  решение найдено! 
     
  • зная y:

     x = (y - center.y + CD_slope * center.x) / CD_slope; 
    если x> 0 && x  решение найдено! 
     

Из этого я мог бы получить еще один сегмент (скажем, я нашел C и знаю центр), но геометрия у меня не удалась чтобы найти продолжение этого сегмента до пересечения с другой стороной прямоугольника.

Обновлено, чтобы включить фрагмент кода

(см. Комментарии в основной функции)

typedef struct { double x; double y; } Point;

Point calculate_center(Point p1, Point p2) {
    Point point;
    point.x = (p1.x+p2.x)/2;
    point.y = (p1.y+p2.y)/2;
    return point;
}

double calculate_pslope(Point p1, Point p2) {
    double dy = p1.y - p2.y;
    double dx = p1.x - p2.x;
    double slope = dy/dx; // this is p1 <-> p2 slope

    return -1/slope;
}

int calculate_y_knowing_x(double pslope, Point center, double x, Point *point) {
    double min= 0.00;
    double max= 512.00;
    double y = (pslope * (x - center.x)) + center.y;

    if(y >= min && y <= max) {
        point->x = corner;
        point->y = y;
        printf("++> found Y for X, point is P(%f, %f)\n", point->x, point->y);
        return 1;
    }
    return 0;
}

int calculate_x_knowing_y(double pslope, Point center, double y, Point *point) {
    double min= 0.00;
    double max= 512.00;
    double x = (y - center.y + pslope*center.x)/pslope;

    if(x >= min && x <= max) {
        point->x = x;
        point->y = y;
        printf("++> found X for Y, point is: P(%f, %f)\n", point->x, point->y);
        return 1;
    }
    return 0;
}

int main(int argc, char **argv) {
    Point A, B;

    // parse argv and define A and B
    // this code is omitted here, let's assume:
    // A.x = 175.00;
    // A.y = 420.00;
    // B.x = 316.00;
    // B.y = 62.00;

    Point C;
    Point D;

    Point center;
    double pslope;

    center = calculate_center(A, B);
    pslope = calculate_pslope(A, B);

    // Here's where the fun happens:
    // I'll need to find the right succession of calls to calculate_*_knowing_* 
    // for 4 cases: x=0, X=512 #=> call calculate_y_knowing_x
    // y=0, y=512 #=> call calculate_x_knowing_y
    // and do this 2 times for both C and D points.
    // Also, if point C is found, point D should not be on the same side (thus C != D)

    // for the given A and B points the succession is:
    calculate_y_knowing_x(pslope, center, 0.00, C);
    calculate_y_knowing_x(pslope, center, 512.00, D);
    // will yield: C(0.00, 144.308659), D(512.00, 345.962291)

    // But if A(350.00, 314.00) and B(106.00, 109.00)
    // the succesion should be:
    // calculate_y_knowing_x(pslope, center, 0.00, C);
    // calculate_x_knowing_y(pslope, center, 512.00, D);
    // to yield C(0.00, 482.875610) and D(405.694672, 0.00)


    return 0;
}

Это код на языке C.

Примечания:

  • Изображение нарисовано от руки.
  • Система координат повернута на 90 ° против часовой стрелки, но не должна влиять на решение
  • Я ищу алгоритм на C, но я могу читать на других языках программирования
  • Это двумерная проблема

]

6
задан Glorfindel 12 August 2019 в 23:38
поделиться