public static double IntersectCylinder(Cylinder cylinder, Ray ray) { //Переменные для возврата корней квадратного уравнения double root1, root2; var a = ray.Direction.X * ray.Direction.X + ray.Direction.Y * ray.Direction.Y; var center = cylinder.GetAbsoluteLocation().ToPoint3D(); var top = cylinder.GetAbsoluteLocation().ToPoint3D() + new Point3D(0, 0, cylinder.Height); //Вспомогательный вектор var vec = ray.Origin - center; var b = 2 * (ray.Direction.X * vec.X + ray.Direction.Y * vec.Y); var c = Math.Pow(ray.Origin.X - center.X, 2) + Math.Pow(ray.Origin.Y - center.Y, 2) - Math.Pow(cylinder.RBottom, 2); //Обработка решения if ((QuadEquation.Solution(a, b, c, out root1, out root2)) && ((root1 >= 0) | (root2 >= 0))) if (root1 >= 0) { Point3D point = ray.CalculatePoint(root1); //если координата z лежит на цилиндре, то это нам подходит if ((point.Z >= center.Z) && (point.Z <= center.Z + cylinder.Height)) { return ray.DistanceTo(root1); } //если координата z за пределами, то проверяем пересечения с верхней и нижней гранью else if (IntersectCircle(center, cylinder.RBottom, ray) != null) { return ray.Origin.Hypot(IntersectCircle(center, cylinder.RBottom, ray).Value); } else if (IntersectCircle(top, cylinder.RBottom, ray) != null) { return ray.Origin.Hypot(IntersectCircle(top, cylinder.RBottom, ray).Value); } else return double.PositiveInfinity; } else //все то же самое для другого корня { Point3D point = ray.CalculatePoint(root2); if ((point.Z >= center.Z) && (point.Z <= center.Z + cylinder.Height)) { return ray.DistanceTo(root2); } else if (IntersectCircle(center, cylinder.RBottom, ray) != null) { return ray.Origin.Hypot(IntersectCircle(center, cylinder.RBottom, ray).Value); } else if (IntersectCircle(top, cylinder.RBottom, ray) != null) { return ray.Origin.Hypot(IntersectCircle(top, cylinder.RBottom, ray).Value); } else return double.PositiveInfinity; } else { return double.PositiveInfinity; } }
public static Point3D?IntersectPlane(Plane plane, Ray ray) { var a = plane.Normal.X; var b = plane.Normal.Y; var c = plane.Normal.Z; var d = -a * plane.Center.X - b * plane.Center.Y - c * plane.Center.Z; //Console.WriteLine("{0} x , {1} y , {2} z , {3} ", a,b,c,d); if (Math.Abs(ray.Direction.MultiplyScalar(plane.Normal)) < Double.Epsilon) //Если N || лучу, то нет пересечения { return(null); } else { double t = -(d + ray.Origin.MultiplyScalar(plane.Normal)) / (ray.Direction.MultiplyScalar(plane.Normal)); if (t < 0) //Проверка на то, что точка пересечения лежит с нужной стороны от начала луча { return(null); } else { return(ray.CalculatePoint(t)); } } }
public static Point3D? IntersectPlane(Plane plane, Ray ray) { var a = plane.Normal.X; var b = plane.Normal.Y; var c = plane.Normal.Z; var d = -a*plane.Center.X - b*plane.Center.Y - c*plane.Center.Z; //Console.WriteLine("{0} x , {1} y , {2} z , {3} ", a,b,c,d); if (Math.Abs(ray.Direction.MultiplyScalar(plane.Normal)) < Double.Epsilon) //Если N || лучу, то нет пересечения { return null; } else { double t = -(d + ray.Origin.MultiplyScalar(plane.Normal))/(ray.Direction.MultiplyScalar(plane.Normal)); if (t < 0) //Проверка на то, что точка пересечения лежит с нужной стороны от начала луча { return null; } else { return ray.CalculatePoint(t); } } }
public static double IntersectCylinder(Cylinder cylinder, Ray ray) { //Переменные для возврата корней квадратного уравнения double root1, root2; var a = ray.Direction.X * ray.Direction.X + ray.Direction.Y * ray.Direction.Y; var center = cylinder.GetAbsoluteLocation().ToPoint3D(); var top = cylinder.GetAbsoluteLocation().ToPoint3D() + new Point3D(0, 0, cylinder.Height); //Вспомогательный вектор var vec = ray.Origin - center; var b = 2 * (ray.Direction.X * vec.X + ray.Direction.Y * vec.Y); var c = Math.Pow(ray.Origin.X - center.X, 2) + Math.Pow(ray.Origin.Y - center.Y, 2) - Math.Pow(cylinder.RBottom, 2); //Обработка решения if ((QuadEquation.Solution(a, b, c, out root1, out root2)) && ((root1 >= 0) | (root2 >= 0))) { if (root1 >= 0) { Point3D point = ray.CalculatePoint(root1); //если координата z лежит на цилиндре, то это нам подходит if ((point.Z >= center.Z) && (point.Z <= center.Z + cylinder.Height)) { return(ray.DistanceTo(root1)); } //если координата z за пределами, то проверяем пересечения с верхней и нижней гранью else if (IntersectCircle(center, cylinder.RBottom, ray) != null) { return(ray.Origin.Hypot(IntersectCircle(center, cylinder.RBottom, ray).Value)); } else if (IntersectCircle(top, cylinder.RBottom, ray) != null) { return(ray.Origin.Hypot(IntersectCircle(top, cylinder.RBottom, ray).Value)); } else { return(double.PositiveInfinity); } } else //все то же самое для другого корня { Point3D point = ray.CalculatePoint(root2); if ((point.Z >= center.Z) && (point.Z <= center.Z + cylinder.Height)) { return(ray.DistanceTo(root2)); } else if (IntersectCircle(center, cylinder.RBottom, ray) != null) { return(ray.Origin.Hypot(IntersectCircle(center, cylinder.RBottom, ray).Value)); } else if (IntersectCircle(top, cylinder.RBottom, ray) != null) { return(ray.Origin.Hypot(IntersectCircle(top, cylinder.RBottom, ray).Value)); } else { return(double.PositiveInfinity); } } } else { return(double.PositiveInfinity); } }