1. Pascal / Говнокод #6797

    +94

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    procedure rayxtriangle(Xa,Ya,Za, {Точка отправления луча}
                                        X1,Y1,Z1,X2,Y2,Z2,X3,Y3,Z3 : real; {Координаты полигона (триангла)}
                                        Vx,Vy,Vz : real;{Вектор направления луча} Var Xc,Yc,Zc : real;{Точка пересечения}
                                        bol : boolean {Для проверки пересечения триангла});
    Var A,B,C,D : real;
          k : real;
          ac1,ac2,ac3 : real;
    begin
      A:=(Y2-Y1)*(Z3-Z1)-(Z2-Z1)*(Y3-Y1); //Вычисляем вектор нормали к треугольному полигону (векторное произведение)
      B:=(Z2-Z1)*(X3-X1)-(X2-X1)*(Z3-Z1);
      C:=(X2-X1)*(Y3-Y1)-(Y2-Y1)*(X3-X1);
      D:=-A*X1-B*Y1-C*Z1;
      k:=-(A*Xa+B*Ya+C*Za+D)/(A*Vx+B*Vy+C*Vz); //поскольку вектора луча (Vx Vy Vz) и вектор с даной
                                                                                  //точки к точке пересечения (Xc-Xa, Yc-Ya, Zc-Za) - колинеарны
                                                                                  //ето соотношение выведено мною, обьяснение было раньше (в предыдущем ответе)
      Xc:=k*Vx+Xa; //Вычисляем точку пересечения луча с полигоном
      Yc:=k*Vy+Ya;
      Zc:=k*Vz+Za;
                            //здесь проверяем лежыт ли даная точка в треугольном полигоне
                            //ac1,ac2,ac3 арккосинусы углов между векторами с точки пересечения (Xc Yc Zc)
                            //к вершинам треугольника (из скалярного произведения) 
                            //Для других полигонов (4,5,6... и т.д. угольных) надо побольше вычислений 
      ac1:=arccos(((x1-xc)*(x2-xc)+(y1-yc)*(y2-yc)+(z1-zc)*(z2-zc))/(sqrt(sqr(x1-xc)+sqr(y1-yc)+sqr(z1-zc))*sqrt(sqr(x2-xc)+sqr(y2-yc)+sqr(z2-zc))));
      ac2:=arccos(((x2-xc)*(x3-xc)+(y2-yc)*(y3-yc)+(z2-zc)*(z3-zc))/(sqrt(sqr(x2-xc)+sqr(y2-yc)+sqr(z2-zc))*sqrt(sqr(x3-xc)+sqr(y3-yc)+sqr(z3-zc)))); 
      ac3:=arccos(((x3-xc)*(x1-xc)+(y3-yc)*(y1-yc)+(z3-zc)*(z1-zc))/(sqrt(sqr(x3-xc)+sqr(y3-yc)+sqr(z3-zc))*sqrt(sqr(x1-xc)+sqr(y1-yc)+sqr(z1-zc)))); 
      if (ac1+ac2+ac3=pi) then bol:=true else bol:=false; //Если сума етих углов=360 градусов значит точка в треугольнике
      //Если точка пересечения найдена тогда bol=true и ее координаты Xc Yc Zc                              
    end;

    А всё потому, что векторную алгебру надо знать, любить и уважать, ибо иначе такая хрень выходит.
    Источник: http://www.gamedev.ru/code/forum/?id=148128

    Запостил: TarasB, 31 Мая 2011

    Комментарии (13) RSS

    • Да вообще линал, не только векторную. Работать с матрицами тоже порой бываеь полезно.
      Ответить
    • Кстати, точку пересечения луча и полигона он вычисляет правильно. Но дальше (после слова "лежыт") начинается лютая хрень.
      Видимо, код писало два разных человека.
      Ответить
      • > Точка отправления луча
        уже символизирует
        Ответить
      • А разве не договаривались постить только реальный код, а не лабы и пасту с форумов?
        Ответить
        • Я буду говорить только с твоим хозяином.
          Ответить
          • - Кто тут инвалид?
            - Ну, я инвалид.
            Ответить
            • неправильно.

              - Где этот чертов инвалид?
              - Не шуми, я инвалид!
              Ответить
      • Либо имела место копипаста до слова "лежыт". Дальше, видимо, дописывал своими руками.
        Ответить
    • >http://www.gamedev.ru/code/forum/?id=148128
      а с первого взгляда сильно похоже на чью-то лабу.
      Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий