Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: Firefox от Май 26, 2023, 14:28



Название: Пересечение луча и целиндра.
Отправлено: Firefox от Май 26, 2023, 14:28
Добрый день всем.
Встала необходимость работать с графикой 3д. Задача такая:необходимо найти пересечение луча( с началом в точке N (xn,yn,zn), углом относительно оси у) и целиндра. Ось целиндра параллелена плоскости x0y. я знаю геометрический центр целиндра C(xc,yc,zc), радиус R, длину L, и угол оси целиндра с осью у. Тесть целиндр горизонтальный как бы. Нашла на просторах интернета функцию пересечения луча и бесконечного целиндра
Цитировать
boolean GLWidget::intcyl(QVector3D raybase, QVector3D raycos, QVector3D base, QVector3D axis, double radius, double *in, double *out)
{
    boolean     hit;        /* True if ray intersects cyl   */
    QVector3D   RC;     /* Ray base to cylinder base    */
    double      d;      /* Shortest distance between    */
                    /*   the ray and the cylinder   */
    double      t, s;       /* Distances along the ray  */
    QVector3D   n, D, O;
    double      ln;
const   double  pinf = HUGE;    /* Positive infinity        */
 
    RC.setX(raybase.x() - base.x());
    RC.setY(raybase.y() - base.y());
    RC.setZ(raybase.z() - base.z());
    n = QVector3D::crossProduct(raycos,axis);
 
    if  ( (ln = n.length()) == 0 ) {    /* ray parallel to cyl  */
        d    = QVector3D::dotProduct(RC,axis);
        D.setX(RC.x() - d*axis.x());
        D.setY(RC.y() - d*axis.y());
        D.setZ(RC.z() - d*axis.z());
        d    = D.length();
        *in  = -pinf;
        *out =  pinf;
        return (d <= radius);       /* true if ray is in cyl*/
    }
    n.normalize();
 
    d    = fabs (QVector3D::dotProduct(RC,n));      /* shortest distance    */
    hit  = (d <= radius);
    if  (hit) {             /* if ray hits cylinder */
        O = QVector3D::crossProduct(RC,axis);
        t = - QVector3D::dotProduct(O,n) / ln;
        O = QVector3D::crossProduct(n,axis);
        O.normalize();
        s = fabs (sqrt(radius*radius - d*d) / QVector3D::dotProduct(raycos,O));
        *in  = t - s;           /* entering distance    */
        *out = t + s;           /* exiting  distance    */
    }
 
    return (hit);
}
Как раз то что мне надо, возвращает расстояние и пересекает ли луч целиндр. Как правильно заполнить входящие вектора параметрами целиндра, подскажите.