private HitInfo FindHitObject(Ray ray, Geometry originator, HitMode mode) { Vector3D intersectionPoint = new Vector3D(double.MaxValue, double.MaxValue, double.MaxValue); HitInfo info = new HitInfo(null, intersectionPoint, ray); double distance = double.MaxValue; foreach (Geometry geometry in Scene.Geometries) { if (geometry != originator && geometry.Intersects(ray, ref intersectionPoint)) { double distanceToObject = Vector3D.Subtract(ray.Source, intersectionPoint).Length; if (distanceToObject < distance) { info.hitPoint = intersectionPoint; distance = distanceToObject; info.hitObject = geometry; if (mode == HitMode.Any) { break; } } } } return(info); }
private bool InShadow(HitInfo info, Vector3D lightLocation, Vector3D lightNormal) { Ray shadowRay = new Ray(lightLocation, lightNormal); HitInfo shadingInfo = FindHitObject(shadowRay, info.hitObject, HitMode.Closest); if (shadingInfo.hitObject != null && Vector3D.Subtract(lightLocation, info.hitPoint).Length > Vector3D.Subtract(lightLocation, shadingInfo.hitPoint).Length) { return(true); } return(false); }
/// <summary> /// Calculate the intesection point between the ray and the plane of the rectangle. /// </summary> /// <param name="ray">The ray to check</param> /// <param name="intersectionPoint">The result intersection point</param> /// <returns>True if the intersection is in the rectangle</returns> override public bool Intersects(Ray ray, ref Vector3D intersectionPoint) { var normalDotProduct = Vector3D.DotProduct(Normal, ray.Direction); // Do the intersection test as for a Plane. if (normalDotProduct != 0) { //Give the right orientation to the normal vector if (normalDotProduct > 0) { normal = -Normal; normalDotProduct = -normalDotProduct; } Vector3D Point = (Vector3D)Point1; double t = (Vector3D.DotProduct(Normal, (Vector3D.Subtract(Point, ray.Source)))) / normalDotProduct; if (t >= 0) { intersectionPoint = ray.Source + (ray.Direction * t); var vec1 = (Point3D)intersectionPoint - Point1; var vec2 = Point2 - Point1; var vec3 = Point4 - Point1; var alpha = Vector3D.DotProduct(vec1, vec2) / vec2.LengthSquared; var beta = Vector3D.DotProduct(vec1, vec3) / vec3.LengthSquared; if (alpha >= 0 && alpha <= 1 && beta >= 0 && beta <= 1) { return(true); } } } return(false); }
/// <summary> /// Calculate the intesection point between the ray and the plane of the rectangle. /// </summary> /// <param name="ray">The ray to check</param> /// <param name="intersectionPoint">The result intersection point</param> /// <returns>True if the intersection is in the rectangle</returns> override public bool Intersects(Ray ray, ref Vector3D intersectionPoint) { Vector3D tempIntersectionPoint = new Vector3D(double.MaxValue, double.MaxValue, double.MaxValue); double distance = double.MaxValue; bool doesIntersect = false; foreach (Rectangle rectangle in faces) { if (rectangle.Intersects(ray, ref tempIntersectionPoint)) { doesIntersect = true; double distanceToFace = Vector3D.Subtract(ray.Source, tempIntersectionPoint).Length; if (distanceToFace < distance) { distance = distanceToFace; normalsDictionary.TryAdd(intersectionPoint, rectangle.Normal); } } } return(doesIntersect); }
public static Ray FromStartAndEndPoints(Vector3D start, Vector3D end) { return(new Ray(start, Vector3D.Subtract(end, start))); }