Пример #1
0
 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;
     }
 }
Пример #2
0
        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));
                }
            }
        }
Пример #3
0
        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);
                }
            }

        }
Пример #4
0
        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);
            }
        }