Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 21.07.2020, 10:55   #21
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Цитата:
normal = crossProduct(p2 - p1, p4 - p1);
после вычисления нормали, ее нужно нормализировать или нет?
BLACK_RAIN вне форума Ответить с цитированием
Старый 21.07.2020, 23:00   #22
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

BLACK_RAIN
Давно бы взяли Ogre3D и срисовали бы решение.
Код:
 std::pair<bool, Real> Math::intersects(const Ray& ray, const Plane& plane)
    {

        Real denom = plane.normal.dotProduct(ray.getDirection());
        if (Math::Abs(denom) < std::numeric_limits<Real>::epsilon())
        {
            // Parallel
            return std::pair<bool, Real>(false, 0);
        }
        else
        {
            Real nom = plane.normal.dotProduct(ray.getOrigin()) + plane.d;
            Real t = -(nom/denom);
            return std::pair<bool, Real>(t >= 0, t);
        }
        
    }
Цитата:
Сообщение от BLACK_RAIN Посмотреть сообщение
после вычисления нормали, ее нужно нормализировать или нет?
Нет.

А вот с делением я немного ошибся, там умножение N^-1 что равно транспонированному вектору и имеем "plane.normal.dotProduct( ray.getDirection() )".

Смотри схему из книги Никулин Е.А. - Компьютерная геометрия и алгоритмы машинной графики - 2005
2020-07-21_22-51-14.jpg

Код:
Function TERRARay.Intersect(Const P:Plane; Var T:Single):Boolean;
Begin
  T := -(P.A * Origin.X + P.B * Origin.Y + P.C * Origin.Z + P.D) / (P.A * Direction.X + P.B * Direction.Y + P.C * Direction.Z);

  If (T < 0.0) Then
  Begin
    Result := False;
    Exit;
  End;

  Result := True;
End;
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .

Последний раз редактировалось Pavia; 21.07.2020 в 23:06.
Pavia вне форума Ответить с цитированием
Старый 22.07.2020, 16:08   #23
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
По умолчанию

Код:
struct RAY
{
    glm::vec3 start;
    glm::vec3 direction;
};

struct QUAD
{
    glm::vec3 p1;
    glm::vec3 p2;
    glm::vec3 p3;
    glm::vec3 p4;
};

glm::vec3 GetNormal(QUAD q)
{
    return glm::cross(q.p2 - q.p1, q.p4 - q.p1);
}

std::pair<bool, float> intersects(RAY ray, QUAD plane)
{
    glm::vec3 normal = GetNormal(plane);
    float denom = glm::dot(normal, ray.direction);
    if (abs(denom) < std::numeric_limits<float>::epsilon())
    {
        return std::pair<bool, float>(false, 0.0f);
    }
    else
    {
        float nom = glm::dot(normal, ray.start + plane.p4);
        float t = -(nom / denom);
        return std::pair<bool, float>(t >= 0.0f, t);
    }
}

    RAY ray;
    ray.start = glm::vec3(5.0f, -0.3f, 1.0f);
    ray.direction = glm::vec3(0.0f, 0.0f, -1.0f);

    QUAD q;
    q.p1 = glm::vec3(0.0f, 0.0f, 0.0f);
    q.p2 = glm::vec3(10.0f, 0.0f, 0.0f);
    q.p3 = glm::vec3(10.0f, 10.0f, 0.0f);
    q.p4 = glm::vec3(0.0f, 10.0f, 0.0f);

    std::pair<bool, float> res = intersects(ray, q);
    if (res.first)
    {
        std::cout << ":)" << std::endl;
    }
возвращает true, хотя луч ниже квада
BLACK_RAIN вне форума Ответить с цитированием
Старый 22.07.2020, 16:46   #24
Pavia
Лис
Старожил
 
Аватар для Pavia
 
Регистрация: 18.09.2015
Сообщений: 2,409
По умолчанию

Цитата:
Сообщение от BLACK_RAIN Посмотреть сообщение
возвращает true, хотя луч ниже квада
У вас квадр лежит на полу z=0 луч падает с высоты 1 в минус. Разумеется он в него попадет. И вернёт "" . Плюс к тому же Вы проверку габаритов квадра потеряли.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
У дзен программиста программа делает то что он хотел, а не то что он написал .
Pavia вне форума Ответить с цитированием
Старый 22.07.2020, 17:43   #25
BLACK_RAIN
Форумчанин
 
Регистрация: 13.02.2012
Сообщений: 867
Вопрос

Цитата:
Сообщение от Pavia Посмотреть сообщение
У вас квадр лежит на полу z=0 луч падает с высоты 1 в минус.
то есть y и z местами перепутаны?
Цитата:
Сообщение от Pavia Посмотреть сообщение
Плюс к тому же Вы проверку габаритов квадра потеряли.
какую еще проверку? я же код с огра срисовал. Какая там еще проверка должна быть?

а еще я в дебаггере заметил, что
Код:
    if (abs(denom) < std::numeric_limits<float>::epsilon())
это условие не выполняется даже тогда, когда должно выполниться.
epsilon равен примерно 1.19
a denom у меня получается равен -100. Но если, ради эксперимента, попробовать нормализировать нормаль, то denom станет равен -1. Тогда условие должно выполниться, но не выполняется
Более того, если убрать abs и вручную изменить знак у denom (умножив на -1), то условие всё-равно не выполняется! Почему? Ведь 1 < 1.19 == true

Последний раз редактировалось BLACK_RAIN; 23.07.2020 в 11:15.
BLACK_RAIN вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как сделать пересечение луча и модели в OpenGL? Rasool Мультимедиа в Delphi 1 28.03.2015 23:07
Обрезание луча по границам прямоугольника С# Weyner Помощь студентам 0 10.04.2013 17:10
Обрезание луча по границам прямоугольника Weyner C# (си шарп) 0 10.04.2013 17:00
Обратный ход луча по горизонтали 04h andy301086 Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 3 23.12.2011 12:56
Отражение луча Illusionist Общие вопросы Delphi 3 30.05.2009 23:20