Example #1
0
        /// <summary>
        /// Returns the point of intersection with the ray and the plane.
        /// </summary>
        /// <param name="ray"></param>
        /// <returns>Point(NaN, NaN, Nan) if the ray is parallel to the plane or the plane is behind the ray</returns>
        public bool IntersectionPoint(Ray ray, out Point3D intersectionPoint)
        {
            //Check to see if the plane and the ray are parallel, if so then
            //they will not intersect
            double d = Vector3D.DotProduct(this.Normal, ray.Direction);
            if ((d > -1e-12) && (d < 1e-12))
            {
                intersectionPoint = new Point3D(double.NaN, double.NaN, double.NaN);
                return false;
            }

            // P = P0 + tV
            // P . N + d = 0
            //
            // (P0 + tV) . N + d = 0
            // P0 . N + tV . N + d = 0
            // t = -(P0 . N + d) / V . N

            double t = -(Vector3D.DotProduct((Vector3D)ray.Origin, this.Normal) + this.D) / d;
            if (t < 0)
            {
                intersectionPoint = new Point3D(double.NaN, double.NaN, double.NaN);
                return false;
            }
            intersectionPoint = ray.Origin + t * ray.Direction;
            return true;
        }
        private double IntersectsWithTriangle(Ray ray, Point3D p0, Point3D p1, Point3D p2)
        {
            Vector3D e1 = p1 - p0;
            Vector3D e2 = p2 - p0;
            Vector3D p = Vector3D.CrossProduct(ray.Direction, e2);

            double a = Vector3D.DotProduct(e1, p);
            if (MathHelper.IsZero(a))
            {
                //The ray and the triangle are parallel, they will not cross
                return -1;
            }

            double f = 1.0 / a;
            Vector3D s = ray.Origin - p0;
            double u = f * Vector3D.DotProduct(s, p);
            if ((u < 0) || (u > 1))
            {
                //Outside of the triangle
                return -1;
            }

            Vector3D q = Vector3D.CrossProduct(s, e1);
            double v = f * Vector3D.DotProduct(ray.Direction, q);
            if ((v < 0) || (u + v > 1))
            {
                //Outside of the triangle
                return -1;
            }

            //Need to check the ray intersection is in the direction of the ray
            double t = f * Vector3D.DotProduct(e2, q);
            if (t < 0)
            {
                //Outside of the triangle
                return -1;
            }
            return t;
        }
        public Ray GetRayPlane(double X, double Y)
        {
            Point3D pt1 = new Point3D(X, Y, -max_x);
            Point3D pt2 = new Point3D(X, Y, 0);
            Vector3D dir = pt2 - pt1;

            Ray ray = new Ray(pt1, dir);
            return ray;
        }
        public Ray GetRay(double angle, double Z, Vector3D offset)
        {
            AxisAngleRotation3D myRotation = new AxisAngleRotation3D(new Vector3D(0, 0, 1), angle);
            RotateTransform3D myRotateTransform = new RotateTransform3D(myRotation);

            Point3D pt1 = myRotateTransform.Transform(new Point3D(-max_x, 0, Z) + offset);
            Point3D pt2 = myRotateTransform.Transform(new Point3D(0, 0, Z) + offset);
            Vector3D dir = pt2 - pt1;

            Ray ray = new Ray(pt1, dir);
            return ray;
        }
        public IntersectionType GetIntersectionPlane(double X, double Y, out Point3D intersection)
        {
            IntersectionType ret = IntersectionType.E_OUT;
            intersection = new Point3D();

            Ray[] rays = new Ray[4];

            double x_offset = m_dFreza.X / 2;
            double y_offset = m_dFreza.Y / 2;
            rays[0] = GetRayPlane(X, Y + y_offset);
            rays[1] = GetRayPlane(X + x_offset, Y);
            rays[2] = GetRayPlane(X, Y - y_offset);
            rays[3] = GetRayPlane(X - x_offset, Y);
            Ray ray_base = GetRayPlane(X, Y);

            double dist = Double.MaxValue;

            for (int i = 0; i < m_Model3DGroup.Children.Count; i++)
            {
                GeometryModel3D model = m_Model3DGroup.Children[i] as GeometryModel3D;

                if (model == null || model == meshCubeModel)
                {
                    continue;
                }
                MeshGeometry3D geometry = model.Geometry as MeshGeometry3D;
                if (geometry == null)
                {
                    continue;
                }

                //if (!model.Bounds.Contains(new Point3D(X, Y, 0)))
                //{
                //    continue;
                //}
                ret = IntersectionType.E_NOTHING;
                Point3DCollection points = geometry.Positions;

                for (int j = 0; j < points.Count; j += 3)
                {
                     for (int k = 0; k < rays.Length; k++)
                    {
                        double t = IntersectsWithTriangle(rays[k], points[j], points[j + 1], points[j + 2]);
                        if (t < 0)
                        {
                            continue;
                        }
                        if (t < dist && t >= 0)
                        {
                            dist = t;
                        }
                    }
                }
            }

            if (dist >= 0)
            {
                intersection = ray_base.Origin + dist * ray_base.Direction;
                return IntersectionType.E_INTERSECTION;
            }

            return ret;
        }
        public IntersectionType GetIntersection(double angle, double Z, out Point3D intersection)
        {
            IntersectionType ret = IntersectionType.E_OUT;
            intersection = new Point3D();
            AxisAngleRotation3D myRotation = new AxisAngleRotation3D(new Vector3D(0, 0, 1), angle);
            RotateTransform3D myRotateTransform = new RotateTransform3D(myRotation);

            Ray[] rays = new Ray[4];

            Vector3D offset = new Vector3D(0, -m_dFreza.Y/2, 0);
            rays[0] = GetRay(angle, Z, offset);

            offset = new Vector3D(0, m_dFreza.Y/2, 0);
            rays[1] = GetRay(angle, Z, offset);

            offset = new Vector3D(0, 0, -m_dFreza.Z/2);
            rays[2] = GetRay(angle, Z, offset);

            offset = new Vector3D(0, 0, m_dFreza.Z/2);
            rays[3] = GetRay(angle, Z, offset);

            offset = new Vector3D(0, 0, 0);
            Ray ray_base = GetRay(angle, Z, offset);

            double dist = -1;

            for (int i = 0; i < m_Model3DGroup.Children.Count; i++)
            {
                GeometryModel3D model = m_Model3DGroup.Children[i] as GeometryModel3D;

                if (model == null || model == meshCubeModel)
                {
                    continue;
                }
                MeshGeometry3D geometry = model.Geometry as MeshGeometry3D;
                if (geometry == null)
                {
                    continue;
                }

                if (!model.Bounds.Contains(new Point3D(0, 0, Z)))
                {
                    continue;
                }
                ret = IntersectionType.E_NOTHING;
                Point3DCollection points = geometry.Positions;

                for (int j = 0; j < points.Count; j += 3)
                {
                    if (points[j].Z > (Z+3) && points[j + 1].Z > (Z+3) && points[j + 2].Z > (Z+3))
                    {
                        break;
                    }
                    if (points[j].Z < (Z - 3) && points[j + 1].Z < (Z - 3) && points[j + 2].Z < (Z - 3))
                    {
                        continue;
                    }

                    for (int k = 0; k < rays.Length; k++)
                    {
                        double t = IntersectsWithTriangle(rays[k], points[j], points[j + 1], points[j + 2]);
                        if (t < 0)
                        {
                            continue;
                        }
                        if (t > dist && t < max_x)
                        {
                            dist = t;
                        }
                    }
                }
            }

            if (dist >= 0)
            {
                intersection = ray_base.Origin + dist * ray_base.Direction;
                return IntersectionType.E_INTERSECTION;
            }

            return ret;
        }