Esempio n. 1
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);
                }
            }

        }
Esempio n. 2
0
 public void RayTest(Ray ray, Point3D point, double distance)
 {
     {
         Assert.AreEqual(ray.Origin, new Point3D(0, 0, 0));
         Assert.AreEqual(ray.Direction, point);
      //   Console.WriteLine("Ray: " + ray);
     }
 }
 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;
     }
 }
Esempio n. 4
0
 /// <summary>
 /// Возвращает точку пересечения луча и круга параллельного плоскости z = 0
 /// </summary>
 /// <param name="center">Вершина</param>
 /// <param name="radius">Радиус</param>
 /// <param name="ray">Луч</param>
 /// <returns></returns>
 public static Point3D? IntersectCircle(Point3D center, double radius, Ray ray)
 {
     var p1 = new Point3D(center.X - radius, center.Y, center.Z);
     var p2 = new Point3D(center.X, center.Y - radius, center.Z);
     var plane = new ePlane(center, p1, p2);
     
     Point3D? point1 = IntersectPlane(plane, ray);
     
     if ((point1 != null) &&
         (center.Hypot(point1.Value) <= radius))
     {
         return point1;
     }
     else
     {
         return null;
     }
 }
Esempio n. 5
0
 /// <summary>
 /// Возвращает точку пересечения луча и треугольника p0p1p2
 /// </summary>
 /// <param name="p0">Вершина</param>
 /// <param name="p1">Вершина</param>
 /// <param name="p2">Вершина</param>
 /// <param name="ray">Луч</param>
 /// <returns></returns>
 public static Point3D? IntersectTriangle(Point3D p0, Point3D p1, Point3D p2, Ray ray)
 {
     var plane = new ePlane(p0, p1, p2); //Плоскость содержащая треугольник
     Point3D? point1 = IntersectPlane(plane, ray);
     if (point1 == null)
     {
         return null;
     }
     else
     {
         int i = ProjectPlane(plane); //Определяем куда проецировать треугольник
         Point2D point = ProjectPoint(i, point1.Value);
         Point2D v0 = ProjectPoint(i, p0);
         Point2D v1 = ProjectPoint(i, p1);
         Point2D v2 = ProjectPoint(i, p2);
         Point2D[] regionPoints = new Point2D[] {v0, v2, v1};
         return Geometry.IsFromRegion(point, regionPoints) ? point1 : null;
     }
 }
Esempio n. 6
0
 public static double IntersectBox(Box box, Ray ray)
 {
     Ball ball = GetExternalSphere(box);
     if (double.IsPositiveInfinity(IntersectBall(ball, ray)))
         return double.PositiveInfinity;
     else
     {
         var points = new List<Point3D>();
         var vertex = GetVertex(box);
         int[][] order = new int[12][];
         order[0] = new[] {0, 2, 1};
         order[1] = new[] {1, 2, 4};
         order[2] = new[] {0, 5, 2};
         order[3] = new[] {0, 3, 5};
         order[4] = new[] {0, 3, 1};
         order[5] = new[] {1, 3, 6};
         order[6] = new[] {3, 5, 6};
         order[7] = new[] {6, 5, 7};
         order[8] = new[] {1, 6, 7};
         order[9] = new[] {1, 7, 4};
         order[10] = new[] {2, 5, 7};
         order[11] = new[] {2, 7, 4};
         for (int i = 0; i < 12; i++)
         {
             Point3D? point = TriangleIntersection.IntersectTriangle(vertex[order[i][0]], vertex[order[i][1]],
                                                                     vertex[order[i][2]], ray);
             if (point != null)
                 points.Add(point.Value);
             else 
             {
                 point = TriangleIntersection.IntersectTriangle(vertex[order[i][0]], vertex[order[i][2]],
                                                                     vertex[order[i][1]], ray);
                 if (point != null)
                     points.Add(point.Value);
             }
         }
         if (points.Capacity == 0)
         {
             return double.PositiveInfinity;
         }
         return points.Min(a => ray.Origin.Hypot(a));
     }
 }
Esempio n. 7
0
 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;
 }
Esempio n. 8
0
 public static double Intersect(Body body, Ray ray)
 {
     if (body is Box)
         return IntersectBox(body as Box, ray);
     if (body is Ball)
         return IntersectBall(body as Ball, ray);
     if (body is Cylinder)
         return IntersectCylinder(body as Cylinder, ray);
     return double.PositiveInfinity;
     //throw new Exception("Unknown body");
 }
Esempio n. 9
0
 public void RayTest(Point3D v0, Point3D v1, Point3D v2, Ray ray, Point3D? point)
 {
     var computedPoint = Intersector.TriangleIntersection.IntersectTriangle(v0, v1, v2, ray);
     Assert.AreEqual(point, computedPoint);
   //  Console.WriteLine("Expected: {0}. But was: {1}", point, computedPoint);
 }
Esempio n. 10
0
 public void RayTest(Ray ray, Point3D center, double radius, Point3D? point)
 {
     Point3D? computedPoint = Intersector.IntersectCircle(center, radius, ray);
     Assert.AreEqual(point, computedPoint);
     {
         //Console.WriteLine("Point:  {0}. Expected: {1}", computedPoint, point);
     }
 }
 public void RayTest(Ray ray, Cylinder cylinder, double distance)
 {
     var computedDistance = Intersector.IntersectCylinder(cylinder, ray);
     Assert.AreEqual(distance, computedDistance);
    // Console.WriteLine("Expected: {0}. But was: {1}", distance, computedDistance);
 }
Esempio n. 12
0
 public void RayTest(Ray ray, Box box, double distance)
 {
     var computedDistance = Intersector.IntersectBox(box, ray);
     Assert.AreEqual(distance, computedDistance);
     {
         Console.WriteLine("Distance:  {0}. expected: {1}", computedDistance, distance);
     }
 }
Esempio n. 13
0
 public void RayTest(Ray ray, Plane plane, Point3D? point)
 {
     Point3D? computedPoint = Intersector.IntersectPlane(plane, ray);
     Assert.AreEqual(point, computedPoint);
     {
       //  Console.WriteLine("Point:  {0}. Expected: {1}", computedPoint, point);
     }
 }
Esempio n. 14
0
 public void RayTest(Ray ray, Ball ball, double distance)
 {
     var computedDistance = Intersector.IntersectBall(ball, ray);
     Assert.AreEqual(distance, computedDistance);
     {
         //Console.WriteLine("Distance:  {0}. Expected: {1}", computedDistance, distance);
     }
 }