bool CustomImplicitSurface2::intersectsLocal(const Ray2D& ray) const { BoundingBoxRayIntersection2D intersection = _domain.closestIntersection(ray); if (intersection.isIntersecting) { double tStart, tEnd; if (intersection.tFar == kMaxD) { tStart = 0.0; tEnd = intersection.tNear; } else { tStart = intersection.tNear; tEnd = intersection.tFar; } double t = tStart; Vector2D pt = ray.pointAt(t); double prevPhi = _func(pt); while (t <= tEnd) { pt = ray.pointAt(t); const double newPhi = _func(pt); const double newPhiAbs = std::fabs(newPhi); if (newPhi * prevPhi < 0.0) { return true; } t += std::max(newPhiAbs, _rayMarchingResolution); prevPhi = newPhi; } } return false; }
/*! */ int Circle2D::intersection( const Ray2D & ray, Vector2D * sol1, Vector2D * sol2 ) const { Line2D line( ray.origin(), ray.dir() ); Vector2D tsol1, tsol2; int n_sol = intersection( line, &tsol1, &tsol2 ); if ( n_sol > 1 && ! ray.inRightDir( tsol2, 1.0 ) ) { --n_sol; } if ( n_sol > 0 && ! ray.inRightDir( tsol1, 1.0 ) ) { tsol1 = tsol2; // substituted by second solution --n_sol; } if ( n_sol > 0 && sol1 ) { *sol1 = tsol1; } if ( n_sol > 1 && sol2 ) { *sol2 = tsol2; } return n_sol; }
SurfaceRayIntersection2 CustomImplicitSurface2::closestIntersectionLocal( const Ray2D& ray) const { SurfaceRayIntersection2 result; BoundingBoxRayIntersection2D intersection = _domain.closestIntersection(ray); if (intersection.isIntersecting) { double tStart, tEnd; if (intersection.tFar == kMaxD) { tStart = 0.0; tEnd = intersection.tNear; } else { tStart = intersection.tNear; tEnd = intersection.tFar; } double t = tStart; Vector2D pt = ray.pointAt(t); double prevPhi = _func(pt); while (t <= tEnd) { pt = ray.pointAt(t); const double newPhi = _func(pt); const double newPhiAbs = std::fabs(newPhi); if (newPhi * prevPhi < 0.0) { const double frac = prevPhi / (prevPhi - newPhi); const double tSub = t + _rayMarchingResolution * frac; result.isIntersecting = true; result.distance = tSub; result.point = ray.pointAt(tSub); result.normal = gradientLocal(result.point); if (result.normal.length() > 0.0) { result.normal.normalize(); } return result; } t += std::max(newPhiAbs, _rayMarchingResolution); prevPhi = newPhi; } } return result; }
TEST(Ray2, PointAt) { Ray2D ray; EXPECT_EQ(Vector2D(4.5, 0.0), ray.pointAt(4.5)); }
glm::vec2 Ray2DIntersectionPoint(const Ray2D & a, const Ray2D & b, bool & exists) { return Ray2DIntersectionPoint(a.origin(), a.direction(), b.origin(), b.direction(), exists); }
float PointRay2DHalfspace(const glm::vec2 & point, const Ray2D & ray) { return PointRay2DHalfspace(point, ray.origin(), ray.direction()); }