本文整理汇总了C++中Ray::PointAlongRay方法的典型用法代码示例。如果您正苦于以下问题:C++ Ray::PointAlongRay方法的具体用法?C++ Ray::PointAlongRay怎么用?C++ Ray::PointAlongRay使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Ray
的用法示例。
在下文中一共展示了Ray::PointAlongRay方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: Intersect
bool Sphere::Intersect(const Ray& p_ray, DifferentialSurface& p_record) const
{
Vector3 temp = p_ray.origin - centre;
double a = Vector3::Dot(p_ray.direction, p_ray.direction);
double b = 2 * Vector3::Dot(p_ray.direction, temp);
double c = Vector3::Dot(temp, temp) - radius * radius;
double discriminant = b * b - 4.0f * a * c;
if (discriminant < 0.0f) return false;
discriminant = sqrt(discriminant);
float q;
if (b < 0) q = -0.5f * (b - discriminant);
else q = -0.5f * (b + discriminant);
float t0 = q / a;
float t1 = c / q;
if (t0 > t1)
{
std::swap(t0, t1);
}
/* Check for valid interval */
if (t0 > p_ray.tmax || t1 < p_ray.tmin) return false;
float thit = t0;
if (t0 < p_ray.tmin)
{
thit = t1;
if (thit > p_ray.tmax) return false;
}
auto phit = p_ray.PointAlongRay(thit);
if (phit.x == 0.0f && phit.y == 0.0f)
{
phit.x = 1e-5f * radius;
}
auto phi = atan2f(phit.y, phit.x);
if (phi < 0.0f)
{
phi += Maths::PiTwo;
}
/* Test sphere intersection against clipping parameters */
if ((z_min > -radius && phit.z < z_min) ||
(z_max < radius && phit.z > z_max) || phi > phi_max) {
if (thit == t1) return false;
if (t1 > p_ray.tmax)
{
return false;
}
thit = t1;
// Compute sphere hit position and $\phi$
phit = p_ray.PointAlongRay(thit);
if (phit.x == 0.f && phit.y == 0.f) phit.x = 1e-5f * radius;
phi = atan2f(phit.y, phit.x);
if (phi < 0.0f) phi += Maths::PiTwo;
if ((z_min > -radius && phit.z < z_min) ||
(z_max < radius && phit.z > z_max) || phi > phi_max)
return false;
}
/* Find parametric representation of sphere hit */
float u = phi / phi_max;
float theta = acosf(Maths::Clamp(phit.z / radius, -1.0f, -1.0f));
float v = (theta - theta_min) / (theta_max - theta_min);
/* Compute sphere dp/du and dp/dv */
float z_radius = sqrtf(phit.x * phit.x + phit.y * phit.y);
float inv_z_radius = 1.0f / z_radius;
float cos_phi = phit.x * inv_z_radius;
float sin_phi = phit.y * inv_z_radius;
Vector3 dpdu{ -phi_max * phit.y, phi_max * phit.x, 0 };
Vector3 dpdv = (theta_max - theta_min) * Vector3 { phit.z * cos_phi, phit.z * sin_phi, -radius * sinf(theta) };
/* Compute sphere dn/du and dn/dv */
Vector3 d2Pduu = -phi_max * phi_max * Vector3{ phit.x, phit.y, 0.0f };
Vector3 d2Pduv = (theta_max - theta_min) * phit.z * phi_max * Vector3{ -sin_phi, cos_phi, 0.0f };
Vector3 d2Pdvv = -(theta_max - theta_min) * (theta_max - theta_min) * Vector3(phit.x, phit.y, phit.z);
/* Compute coefficients for fundamental form */
float E = Vector3::Dot(dpdu, dpdu);
float F = Vector3::Dot(dpdu, dpdv);
float G = Vector3::Dot(dpdv, dpdv);
Vector3 nn = (Vector3::Cross(dpdu, dpdv)).Normalize();
float e = Vector3::Dot(nn, d2Pduu);
float f = Vector3::Dot(nn, d2Pduv);
float g = Vector3::Dot(nn, d2Pdvv);
/* Compute dn/du and dn/dv from fundamental form coefficients */
float invEGF2 = 1.0f / (E * G - F * F);
Vector3 dndu = (Vector3{ (f * F - e * G) * invEGF2 * dpdu +
(e * F - f * E) * invEGF2 * dpdv }).Normalize();
Vector3 dndv = (Vector3{ (g * F - f * G) * invEGF2 * dpdu +
(f * F - g * E) * invEGF2 * dpdv }).Normalize();
/* We have a valid hit */
/* Populate the differential surface object */
p_record.shape = this;
p_record.t = thit;
//.........这里部分代码省略.........
示例2: IntersectP
bool Sphere::IntersectP(const Ray& p_ray) const
{
Vector3 temp = p_ray.origin - centre;
double a = Vector3::Dot(p_ray.direction, p_ray.direction);
double b = 2 * Vector3::Dot(p_ray.direction, temp);
double c = Vector3::Dot(temp, temp) - radius * radius;
double discriminant = b * b - 4 * a * c;
if (discriminant < 0.0f) return false;
discriminant = sqrt(discriminant);
float q;
if (b < 0)
{
q = -0.5f * (b - discriminant);
}
else
{
q = -0.5f * (b + discriminant);
}
float t0 = q / a;
float t1 = c / q;
if (t0 > t1)
{
std::swap(t0, t1);
}
/* Check for valid interval */
if (t0 > p_ray.tmax || t1 < p_ray.tmin)
{
return false;
}
float thit = t0;
if (t0 < p_ray.tmin)
{
thit = t1;
if (thit > p_ray.tmax)
{
return false;
}
}
auto phit = p_ray.PointAlongRay(thit);
if (phit.x == 0.0f && phit.y == 0.0f)
{
phit.x = 1e-5f * radius;
}
auto phi = atan2f(phit.y, phit.x);
if (phi < 0.0f)
{
phi += Maths::PiTwo;
}
/* Test sphere intersection against clipping parameters */
if ((z_min > -radius && phit.z < z_min) ||
(z_max < radius && phit.z > z_max) || phi > phi_max) {
if (thit == t1) return false;
if (t1 > p_ray.tmax)
{
return false;
}
thit = t1;
// Compute sphere hit position and $\phi$
phit = p_ray.PointAlongRay(thit);
if (phit.x == 0.f && phit.y == 0.f) phit.x = 1e-5f * radius;
phi = atan2f(phit.y, phit.x);
if (phi < 0.) phi += Maths::PiTwo;
if ((z_min > -radius && phit.z < z_min) ||
(z_max < radius && phit.z > z_max) || phi > phi_max)
return false;
}
return true;
}