示例#1
0
/*!
    Finds the \a minimum_t and \a maximum_t values where \a ray intersects
    this sphere.  Returns true if intersections were found; or false if there
    is no intersection.

    If \a minimum_t and \a maximum_t are set to the same value, then \a ray
    touches the surface of the sphere at a single point.  If the t values are
    negative, then the intersection occurs before the ray's origin point
    in the reverse direction of the ray.

    The \a minimum_t and \a maximum_t values can be passed to QRay3D::point()
    to determine the actual intersection points, as shown in the following
    example:

    \code
    qreal minimum_t, maximum_t;
    if (sphere.intersection(ray, &minimum_t, &maximum_t)) {
        qDebug() << "intersections at"
                 << ray.point(minimum_t) << "and"
                 << ray.point(maximum_t);
    }
    \endcode

    \sa intersects(), QRay3D::point()
*/
bool QSphere3D::intersection(const QRay3D &ray, qreal *minimum_t, qreal *maximum_t) const
{
    QVector3D centerToOrigin = ray.origin() - m_center;
    qreal term1 = ray.direction().lengthSquared();
    qreal term2 = 2.0f * QVector3D::dotProduct(centerToOrigin, ray.direction());
    qreal term3 = centerToOrigin.lengthSquared() - m_radius * m_radius;
    qreal det = term2 * term2 - (4.0f * term1 * term3);
    if (term1 == 0.0f || det < 0.0f) {
        *minimum_t = qSNaN();
        *maximum_t = qSNaN();
        return false;
    } else if (det == 0.0f) {
        *minimum_t = *maximum_t = -term2 / (2.0f * term1);
    } else {
        qreal sqrtDet = qSqrt(det);
        qreal t1 = (-term2 - sqrtDet) / (2.0f * term1);
        qreal t2 = (-term2 + sqrtDet) / (2.0f * term1);
        if (t1 < t2) {
            *minimum_t = t1;
            *maximum_t = t2;
        } else {
            *minimum_t = t2;
            *maximum_t = t1;
        }
    }
    return true;
}
示例#2
0
cv::Vec3f AreaLight::getIntensity(QVector3D direction) const
{
    float c = QVector3D::dotProduct(direction.normalized(), normal.normalized()) / direction.lengthSquared() * normal.length();
    assert(!isnan(c));
    if(c < 0) c = 0;
    return c * intensity;
}
示例#3
0
/*!
    \since 5.5

    Returns the shortest arc quaternion to rotate from the direction described by the vector \a from
    to the direction described by the vector \a to.

    \sa fromDirection()
*/
QQuaternion QQuaternion::rotationTo(const QVector3D &from, const QVector3D &to)
{
    // Based on Stan Melax's article in Game Programming Gems

    const QVector3D v0(from.normalized());
    const QVector3D v1(to.normalized());

    float d = QVector3D::dotProduct(v0, v1) + 1.0f;

    // if dest vector is close to the inverse of source vector, ANY axis of rotation is valid
    if (qFuzzyIsNull(d)) {
        QVector3D axis = QVector3D::crossProduct(QVector3D(1.0f, 0.0f, 0.0f), v0);
        if (qFuzzyIsNull(axis.lengthSquared()))
            axis = QVector3D::crossProduct(QVector3D(0.0f, 1.0f, 0.0f), v0);
        axis.normalize();

        // same as QQuaternion::fromAxisAndAngle(axis, 180.0f)
        return QQuaternion(0.0f, axis.x(), axis.y(), axis.z());
    }

    d = std::sqrt(2.0f * d);
    const QVector3D axis(QVector3D::crossProduct(v0, v1) / d);

    return QQuaternion(d * 0.5f, axis).normalized();
}
示例#4
0
/**
 * @brief gives Quaternion to transform between 2 vectors
 * @param v1 first vector
 * @param v2 second vector
 * @return Quaternion
 *
 * based on http://stackoverflow.com/a/11741520
 */
Quaternion Quaternion::between(const QVector3D &v1, const QVector3D &v2)
{

	float kCosTheta = QVector3D::dotProduct(v1, v2);
	float k = sqrt(v1.lengthSquared() * v2.lengthSquared());

	if (kCosTheta / k == -1)
	{
		// 180 degree rotation around any orthogonal vector

		QVector3D other = (abs(QVector3D::dotProduct(v1, QVector3D(1, 0, 0))) < 1.0) ? QVector3D(1, 0, 0) : QVector3D(0, 1, 0);
		return Quaternion(QQuaternion::fromAxisAndAngle((QVector3D::crossProduct(v1, other).normalized()), 180));
	}

	return Quaternion(kCosTheta + k, QVector3D::crossProduct(v1, v2)).normalized();
}
示例#5
0
void Material::fresnelDielectric(const QVector3D &d, const QVector3D &normal, float ni, float nt, QVector<QPair<float, QVector3D> > &rays)
{
    QVector3D n = normal;
    float ndd = QVector3D::dotProduct(n, d);
    if (ndd > -Config::Epsilon && ndd < Config::Epsilon) {
        return ;
    }
    if (ndd > 0) {
        n *= -1;
        ndd *= -1;
    }
    QVector3D r = d - 2.0f * ndd * n;
    r.normalize();

    QVector3D z = (d - ndd * n) * ni / nt;
    float z2 = z.lengthSquared();

    if (z2 >= 1.0f) {
        rays.append(QPair<float, QVector3D>(1.0f, r));
        return ;
    }

    QVector3D t = z - qSqrt(1.0f - z2) * n;
    t.normalize();

    float ndt = QVector3D::dotProduct(n, t);
    float rPar = (nt * ndd - ni * ndt) / (nt * ndd + ni * ndt);
    float rPerp = (ni * ndd - nt * ndt) / (ni * ndd + nt * ndt);
    float fr = 0.5f * (rPar * rPar + rPerp * rPerp);

    rays.append(QPair<float, QVector3D>(fr, r));
    rays.append(QPair<float, QVector3D>(1.0f - fr, t));
}
示例#6
0
static double squaredDistanceToAABB(const QVector3D& point,
    const AxisAlignedBox& box) {
  const QVector3D center = (box.Max() + box.Min()) / 2;
  const QVector3D half_sz = (box.Max() - box.Min()) / 2;
  const QVector3D vec(max(0.0, fabs(center.x() - point.x()) - half_sz.x()),
                      max(0.0, fabs(center.y() - point.y()) - half_sz.y()),
                      max(0.0, fabs(center.z() - point.z()) - half_sz.z()));
  return vec.lengthSquared();
}
void SpringMesh::integrate(int algorithm /*= 0*/)
{
	// Apply internal force and integrate
	
	for (auto vertex : mesh->vertSet)
	{
		if (fixedPoint.find(vertex->index) != fixedPoint.end())
		{
			continue;
		}
		//cout << vertex->in_force.length() << endl;
		vertex->vel += vertex->in_force * timestep;
		vertex->pos += 0.5 * (vertex->pre_vel + vertex->vel) * timestep;
		/*cout << (vertex->in_force * timestep).length() << endl;
		vector<QVector3D> K0, K1, K2, K3, K4;
		K0.push_back(vertex->pre_pos); K0.push_back(vertex->pre_vel);
		K1.push_back(vertex->in_force * timestep); K1.push_back(vertex->in_force);
		K1 = stateMul(K1, timestep);
		//K2 = statePlus(K0, K1, 1, 0.5);
		K2 = stateMul(stateDeriv(K0, statePlus(K0, K1, 1, 0.5)), timestep);
		K3 = stateMul(stateDeriv(K0, statePlus(K0, K2, 1, 0.5)), timestep);
		K4 = stateMul(stateDeriv(K0, statePlus(K0, K3)), timestep);

		K0 = statePlus(K0,
			statePlus(statePlus(K1, K2, 1, 2), statePlus(K3, K4, 2, 1)) ,
			1, 1.0 / 6.0);
		vertex->pos = K0.front();
		vertex->vel = K0.back();*/

		if ((vertex->pos - sphere_pos).length() < sphere_r)
			//&& (vertex->pre_pos - sphere_pos).length() > sphere_r)
		{
			QVector3D v10 = (vertex->pre_pos - vertex->pos).normalized();
			QVector3D cv0 = sphere_pos - vertex->pre_pos;
			QVector3D h = cv0 - (cv0 * v10) * v10;
			QVector3D hitp = sphere_pos + h
				+ sqrt(sphere_r * sphere_r - h.lengthSquared()) * v10;
			QVector3D n = (hitp - sphere_pos).normalized();
			/*vertex->pos = hitp + n * 0.01;// +vertex->pos - ((vertex->pos - hitp) * n) * n;*/
			vertex->vel = vertex->pre_vel - 2 * (vertex->pre_vel * n) * n;
			vertex->pos = vertex->pre_pos;
			//vertex->vel = 0.5 * (vertex->vel + vertex->pre_vel) * friction;
		}
		if (vertex->pos.y() < plane_height)
		{
			vertex->vel.setY(-vertex->vel.y());
			vertex->vel *= friction;
			vertex->pos.setY(plane_height * 2 - vertex->pos.y());
		}
	}
}
示例#8
0
float NavigationMath::distanceToClosestPoint(
	const QVector3D & eye
,	const QVector3D & center
,	const QVector3D & point)
{
	const QVector3D ray(center - eye);
	const QVector3D b(point - eye);

	const float m = ray.lengthSquared(); // magnitude of ray
	const float theta = QVector3D::dotProduct(b, ray);

	if(m == 0.0)
		return 0.0;

    return theta / m; // distance from camera to closest point c;
}
示例#9
0
文件: view.cpp 项目: 0rps/3dmanager
void View::mouseMoveEvent(QMouseEvent *event)
{
    if(m_isTouchEvent)
        return;

    const qreal c_mouseFactor = 0.2;
    QPoint newPos = event->pos();

    if((event->buttons() & Qt::LeftButton) && (event->modifiers() & Qt::ControlModifier))
    {
        QPoint center(width()/2, height()/2);
        QLineF oldLine( center, m_mousePos);
        QLineF newLine( center, newPos);

        qreal angle = oldLine.angleTo(newLine);
        if(angle > 180.0)
            angle = angle - 360.0;
        setRoll( roll() +  angle*c_mouseFactor*2  );
    }
    else if(event->buttons() & Qt::LeftButton)
    {
        QVector3D diffRotate = QVector3D(newPos.y() - m_mousePos.y(),
                                         0,
                                         newPos.x() - m_mousePos.x()) * c_mouseFactor;

        setRotate( rotate() + diffRotate );

        const qreal c_treshold = 15.0;
        const qreal c_speedFactor = 0.5;
        if(diffRotate.lengthSquared() > c_treshold)
            camera()->setAnimatedRotation( -diffRotate*c_speedFactor );
        else
            camera()->setAnimatedRotation( QVector3D() );
    }
    else if((event->buttons() & Qt::MidButton) && isFreeMode())
    {
        QVector3D diffShift = c_mouseFactor* QVector3D(newPos.x() - m_mousePos.x(),
                                         newPos.y() - m_mousePos.y(),
                                         0 );//newPos.x() - m_mousePos.x()) * c_mouseFactor;
        shift(diffShift);
    }

    m_mousePos = newPos;
}
示例#10
0
QT_BEGIN_NAMESPACE

/*!
    \class QSphere3D
    \brief The QSphere3D class represents a mathematical sphere in 3D space.
    \since 4.8
    \ingroup qt3d
    \ingroup qt3d::math

    QSphere3D can be used to represent the bounding regions of objects
    in a 3D scene so that they can be easily culled if they are out of view.
    It can also be used to assist with collision testing.

    \sa QBox3D
*/

/*!
    \fn QSphere3D::QSphere3D()

    Constructs a default sphere with a center() of (0, 0, 0)
    and radius() of 1.
*/

/*!
    \fn QSphere3D::QSphere3D(const QVector3D &center, qreal radius)

    Constructs a sphere with the specified \a center and \a radius.
*/

/*!
    \fn QVector3D QSphere3D::center() const

    Returns the center of this sphere.

    \sa setCenter(), radius()
*/

/*!
    \fn void QSphere3D::setCenter(const QVector3D &center)

    Sets the \a center of this sphere.

    \sa center(), setRadius()
*/

/*!
    \fn qreal QSphere3D::radius() const

    Returns the radius of this sphere.

    \sa setRadius(), center()
*/

/*!
    \fn void QSphere3D::setRadius(qreal radius)

    Sets the \a radius of this sphere.

    \sa radius(), setCenter()
*/

/*!
    \fn bool QSphere3D::contains(const QVector3D &point) const

    Returns true if \a point is contained within the bounds of
    this sphere; false otherwise.
*/

/*!
    Returns true if this sphere intersects \a ray; false otherwise.

    \sa intersection()
*/
bool QSphere3D::intersects(const QRay3D &ray) const
{
    QVector3D centerToOrigin = ray.origin() - m_center;
    qreal term1 = ray.direction().lengthSquared();
    qreal term2 = 2.0f * QVector3D::dotProduct(centerToOrigin, ray.direction());
    qreal term3 = centerToOrigin.lengthSquared() - m_radius * m_radius;
    qreal det = term2 * term2 - (4.0f * term1 * term3);
    return term1 != 0.0f && det >= 0.0f;
}
示例#11
0
QVector3D Connections::proj(QVector3D a, QVector3D b, QVector3D p) {
    QVector3D ba = b-a;
    QVector3D pa = p-a;
    return a + ba*QVector3D::dotProduct(ba,pa) / ba.lengthSquared();
}