public static double IntersectBall(Ball ball, Ray ray) { //Переменные для возврата корней квадратного уравнения double root1, root2; //Расчет коэффициентов решения системы уравнений сферы и луча var a = ray.Direction.MultiplyScalar(ray.Direction); //Вспомогательный вектор var location = new Point3D(ball.GetAbsoluteLocation().X, ball.GetAbsoluteLocation().Y, ball.GetAbsoluteLocation().Z + ball.Radius); var vec = ray.Origin - location; var b = 2 * ray.Direction.MultiplyScalar(vec); var c = vec.MultiplyScalar(vec) - Math.Pow(ball.Radius, 2); //Обработка решения if ((QuadEquation.Solution(a, b, c, out root1, out root2)) && ((root1 >= 0) | (root2 >= 0))) { if (root1 >= 0) { return(ray.DistanceTo(root1)); } else { return(ray.DistanceTo(root2)); } } return(Double.PositiveInfinity); }
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); } }