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); } } }
//Определение плоскости для проецирования треугольника private static int ProjectPlane(ePlane plane) { var n = plane.Normal; //Вектор нормали if ((Math.Abs(n.X) >= Math.Abs(n.Y)) && (Math.Abs(n.X) >= Math.Abs(n.Z))) return 0; //0 - наибольшая Nx - проецирование на yOz else if ((Math.Abs(n.Y) >= Math.Abs(n.Z)) && (Math.Abs(n.Y) >= Math.Abs(n.X))) return 1; //1 - наибольшая Ny - проецирование на xOz else return 2; //2 - наибольшая Nz - проецирование на xOy }
/// <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); } }
/// <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; } }
//Определение плоскости для проецирования треугольника private static int ProjectPlane(ePlane plane) { var n = plane.Normal; //Вектор нормали if ((Math.Abs(n.X) >= Math.Abs(n.Y)) && (Math.Abs(n.X) >= Math.Abs(n.Z))) { return(0); //0 - наибольшая Nx - проецирование на yOz } else if ((Math.Abs(n.Y) >= Math.Abs(n.Z)) && (Math.Abs(n.Y) >= Math.Abs(n.X))) { return(1); //1 - наибольшая Ny - проецирование на xOz } else { return(2); //2 - наибольшая Nz - проецирование на xOy } }
/// <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; } }
/// <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); } }
public Point3D ProjectionOnPlane(Plane plane) { return this - ProjectionOnAxis(plane.Normal); }
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); } }
public static Point3D Projection(Point3D toProject, Plane plane) { return toProject - Projection(toProject, plane.Normal); }
public Plane Apply(Plane arg) { return new Plane(Apply(arg.V1), Apply(arg.V2), Apply(arg.V3)); }