Пересечение прямой и прямоугольника

Тема в разделе "WASM.A&O", создана пользователем r90, 30 авг 2009.

  1. r90

    r90 New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2005
    Сообщения:
    898
    Стыдно признаться, но никак не могу найти подходящего решения задачи. Надо пойти поспать, но так обидно, что не заснуть :dntknw:
    Есть координаты верхнего левого и нижнего правого углов прямоугольника. Даны также точка на плоскости и угол наклона прямой проходящей через эту точку. Надо найти точки пересечения этой прямой и сторон прямоугольника.
    Проблема в том, что я не вижу как решить задачу в целых числах (изначально она из 2d графики и вообще-то целочисленная). Если же решать с плавающей точкой то возникают серьёзные проблемы с округлением когда синус или косинус данного угла близок к нулю.
    Есть ещё второстепенная проблема, мне не нравится идиотское количество if'ов. Я делаю так:

    Код (Text):
    1. struct vector
    2. {
    3.     int x, y;
    4. };
    5. int intersect (float a,         // угол наклона прямой
    6.            struct vector center,    // точка на ней
    7.            struct vector v0,    // верхний левый угол прямоугольника
    8.            struct vector v1,    // нижний правый
    9.            struct vector *r1,   // сюда складывать результаты
    10.            struct vector *r2)
    11. {
    12.     float ca = cos (a), sa = sin (a);
    13.     /* уравнение прямой заданной точкой center и углом a выглядит так:
    14.      * (y - center.y) / sa = (x - center.x) / ca
    15.      * Мы будем разглядывать разницу между правой и левой частями,
    16.      * поэтому: */
    17.     float f (float x, float y) {
    18.         return  (y - center.y) * ca - (x - center.x) * sa;
    19.     }
    20.     /* f(x,y) -- это функция плоскости, которая пересекается с Oxy по нашей
    21.      * прямой (center, a), то есть делит Oxy на две полуплоскости. Причём в
    22.      * одной из этих полуплоскостей f(x,y) > 0, в другой f(x,y) < 0 */
    23.     float f00, f10, f01, f11;
    24.  
    25.     f00 = f (v0.x, v0.y);
    26.     if (f00 > 0) {  /* для удобства выберем такое у-е плоскости, чтобы
    27.              * f(v0) < 0 */
    28.         ca = -ca;
    29.         sa = -sa;
    30.         f00 = f (slt.x, slt.y);
    31.     }
    32.     f10 = f (v1.x, v1.y);
    33.     f01 = f (v0.x, v1.y);
    34.     f11 = f (v1.x, v1.y);
    35.     /* Ну а дальше эти убогие ветвления. Я выкинул весь функциональный код,
    36.      * оставил лишь в комментариях системы уравнений которые позволяют
    37.      * найти координаты точек пересечения. Основной вопрос в том и состоит,
    38.      * как бы это так сосчитать-то пересечение двух прямых без существенных
    39.      * погрешностей */
    40.     if (f01 > 0) {
    41.         // r1->x = v0.x && f (r1) == 0
    42.         if (f10 > 0) {
    43.             // r2->y = v0.y && f (r2) == 0
    44.         } else if (f11 > 0) {
    45.             // r2->x = v1.x && f (r2) == 0
    46.         } else {
    47.             // r2->y = v1.y && f (r2) == 0
    48.         }
    49.     } else if (f10 > 0) {
    50.         // r1->y = v0.y && f (r1) == 0
    51.         if (f11 < 0) {
    52.             // r2->x = v1.x && f (r2) == 0
    53.         } else {
    54.             // r2->y = v1.y && f (r2) == 0
    55.         }
    56.     } else if (f11 > 0) {
    57.         // r1->x = v1.x && f (r1) == 0
    58.         // r2->y = v1.y && f (r2) == 0
    59.     } else
    60.         return 2;
    61. }
    Any ideas?
     
  2. Max

    Max Member

    Публикаций:
    0
    Регистрация:
    22 май 2003
    Сообщения:
    192
    гугли Вельтмандер П.В. Машинная графика. Основные алгоритмы
    раздел "Отсечение отрезков"