public bool Raycast(Ray3D ray, out float t) { if (ray.IntersectsPlane(_plane, out t)) { Vector3 intersectionPoint = ray.GetPoint(t); return(ContainsPoint(intersectionPoint)); } return(false); }
public bool IntersectsRay(Ray3D ray, out float t) { Plane circlePlane = Plane; Vector3 circleCenter = Center; float scaledRadius = ScaledRadius; // Note: 'IntersectsPlane' not enough. Also check for containment???? if (ray.IntersectsPlane(circlePlane, out t)) { return(true); } else if (ray.Direction.IsPerpendicularTo(circlePlane.normal)) { // Project the circle center onto the ray direction segment. If the distance between the circle center // and the projected center is <= the circle's radius, the ray might intersect the circle. Otherwise, // the ray can not possibly intersect the circle. Segment3D segment = new Segment3D(ray); Vector3 centerProjectedOnRayDir = circleCenter.CalculateProjectionPointOnSegment(segment.StartPoint, segment.EndPoint); Vector3 fromCenterToProjectedCenter = centerProjectedOnRayDir - circleCenter; float triAdjSideLength1 = fromCenterToProjectedCenter.magnitude; if (triAdjSideLength1 > scaledRadius) { return(false); } // At this point it is possible that the ray might intersect the circle. Calcluate how much // we have to move from the center projection to a point on the circle along the reverse of // the ray direction vector. We will store this amount in 'triAdjSideLength2'. float triAdjSideLength2 = Mathf.Sqrt(scaledRadius * scaledRadius - triAdjSideLength1 * triAdjSideLength1); // Now check if moving from the projected center along the reverse ray direction by an amount equal to // 'triAdjSideLength2', we end up on a point which resides on the ray direction segment. Vector3 normalizedRayDirection = ray.Direction; normalizedRayDirection.Normalize(); Vector3 targetPoint = centerProjectedOnRayDir - triAdjSideLength2 * normalizedRayDirection; if (targetPoint.IsOnSegment(segment.StartPoint, segment.EndPoint)) { // The point sits on the segment, which means that the ray intersects the circle. // Now we need to calculate the intersection offset. t = (targetPoint - ray.Origin).magnitude / ray.Direction.magnitude; return(true); } } return(false); }
public bool IntersectsTriangle(Triangle3D triangle, out Triangle3DIntersectInfo intersectInfo) { intersectInfo = new Triangle3DIntersectInfo(); if (triangle.Normal.IsAlignedWith(Normal)) { return(false); } float t; List <Segment3D> otherTriSegments = triangle.GetSegments(); var firstTriIntersectionPoints = new List <Vector3>(); foreach (var segment in otherTriSegments) { Ray3D ray = new Ray3D(segment.StartPoint, segment.EndPoint); if (Raycast(ray, out t)) { firstTriIntersectionPoints.Add(ray.GetPoint(t)); } } List <Segment3D> thisTriSegments = GetSegments(); var secondTriIntersectionPoints = new List <Vector3>(); foreach (var segment in thisTriSegments) { Ray3D ray = new Ray3D(segment.StartPoint, segment.EndPoint); if (triangle.Raycast(ray, out t)) { secondTriIntersectionPoints.Add(ray.GetPoint(t)); } } if (firstTriIntersectionPoints.Count != 0 || secondTriIntersectionPoints.Count != 0) { intersectInfo = new Triangle3DIntersectInfo(this, triangle, firstTriIntersectionPoints, secondTriIntersectionPoints); return(true); } return(false); }
/// <summary> /// Calculates and returns the edge rays which connect the points of the specified camera /// view volume. /// </summary> public static Ray3D[] CalculateWorldSpaceVolumeEdgeRays(CameraViewVolume cameraViewVolume) { var worldSpaceVolumeEdgeRays = new Ray3D[12]; // Calculate the rays that connect the points on the near plane worldSpaceVolumeEdgeRays[0] = new Ray3D(cameraViewVolume.TopLeftPointOnNearPlane, cameraViewVolume.TopRightPointOnNearPlane - cameraViewVolume.TopLeftPointOnNearPlane); worldSpaceVolumeEdgeRays[1] = new Ray3D(cameraViewVolume.TopRightPointOnNearPlane, cameraViewVolume.BottomRightPointOnNearPlane - cameraViewVolume.TopRightPointOnNearPlane); worldSpaceVolumeEdgeRays[2] = new Ray3D(cameraViewVolume.BottomRightPointOnNearPlane, cameraViewVolume.BottomLeftPointOnNearPlane - cameraViewVolume.BottomRightPointOnNearPlane); worldSpaceVolumeEdgeRays[3] = new Ray3D(cameraViewVolume.BottomLeftPointOnNearPlane, cameraViewVolume.TopLeftPointOnNearPlane - cameraViewVolume.BottomLeftPointOnNearPlane); // Calculate the rays that connect the points on the far plane worldSpaceVolumeEdgeRays[4] = new Ray3D(cameraViewVolume.TopLeftPointOnFarPlane, cameraViewVolume.TopRightPointOnFarPlane - cameraViewVolume.TopLeftPointOnFarPlane); worldSpaceVolumeEdgeRays[5] = new Ray3D(cameraViewVolume.TopRightPointOnFarPlane, cameraViewVolume.BottomRightPointOnFarPlane - cameraViewVolume.TopRightPointOnFarPlane); worldSpaceVolumeEdgeRays[6] = new Ray3D(cameraViewVolume.BottomRightPointOnFarPlane, cameraViewVolume.BottomLeftPointOnFarPlane - cameraViewVolume.BottomRightPointOnFarPlane); worldSpaceVolumeEdgeRays[7] = new Ray3D(cameraViewVolume.BottomLeftPointOnFarPlane, cameraViewVolume.TopLeftPointOnFarPlane - cameraViewVolume.BottomLeftPointOnFarPlane); // Calculate the rays that connect the points between the near and far planes worldSpaceVolumeEdgeRays[8] = new Ray3D(cameraViewVolume.TopLeftPointOnNearPlane, cameraViewVolume.TopLeftPointOnFarPlane - cameraViewVolume.TopLeftPointOnNearPlane); worldSpaceVolumeEdgeRays[9] = new Ray3D(cameraViewVolume.TopRightPointOnNearPlane, cameraViewVolume.TopRightPointOnFarPlane - cameraViewVolume.TopRightPointOnNearPlane); worldSpaceVolumeEdgeRays[10] = new Ray3D(cameraViewVolume.BottomRightPointOnNearPlane, cameraViewVolume.BottomRightPointOnFarPlane - cameraViewVolume.BottomRightPointOnNearPlane); worldSpaceVolumeEdgeRays[11] = new Ray3D(cameraViewVolume.BottomLeftPointOnNearPlane, cameraViewVolume.BottomLeftPointOnFarPlane - cameraViewVolume.BottomLeftPointOnNearPlane); return(worldSpaceVolumeEdgeRays); }
private Ray3D TransformRayInEllipseCircleSpace(Ray3D ray) { return(new Ray3D(TransformPointInEllipseCircleLocalSpace(ray.Origin), TransformVectorInEllipseCircleLocalSpace(ray.Direction))); }
public bool IntersectsRay(Ray3D ray) { float t; return(IntersectsRay(ray, out t)); }