Represents a 3D ray.
        /// <summary>
        /// Unproject a point from the screen (2D) to a point on plane (3D)
        /// </summary>
        /// <param name="p">
        /// The 2D point.
        /// </param>
        /// <param name="position">
        /// plane position
        /// </param>
        /// <param name="normal">
        /// plane normal
        /// </param>
        /// <returns>
        /// A 3D point.
        /// </returns>
        public Point3D?UnProject(Point p, Point3D position, Vector3D normal)
        {
            Ray3D ray = this.GetRay(p);

            if (ray == null)
            {
                return(null);
            }

            return(ray.PlaneIntersection(position, normal));
        }
        /// <summary>
        /// Un projects a point from the screen (2D) to a point on plane (3D)
        /// </summary>
        /// <param name="p">
        /// The 2D point.
        /// </param>
        /// <param name="position">
        /// A point on the plane .
        /// </param>
        /// <param name="normal">
        /// The plane normal.
        /// </param>
        /// <returns>
        /// A 3D point.
        /// </returns>
        public Point3D? UnProject(Point p, Point3D position, Vector3D normal)
        {
            Ray3D ray = this.GetRay(p);
            if (ray == null)
            {
                return null;
            }

            Point3D i;
            return ray.PlaneIntersection(position, normal, out i) ? (Point3D?)i : null;
        }
示例#3
0
        /// <summary>
        /// Unproject a point from the screen (2D) to a point on plane (3D)
        /// </summary>
        /// <param name="viewport">
        /// The viewport.
        /// </param>
        /// <param name="p">
        /// The 2D point.
        /// </param>
        /// <param name="position">
        /// plane position
        /// </param>
        /// <param name="normal">
        /// plane normal
        /// </param>
        /// <returns>
        /// A 3D point.
        /// </returns>
        /// <remarks>
        /// Map window coordinates to object coordinates like gluUnProject.
        /// </remarks>
        public static Point3D?UnProject(Viewport3D viewport, Point p, Point3D position, Vector3D normal)
        {
            Ray3D ray = GetRay(viewport, p);

            if (ray == null)
            {
                return(null);
            }

            return(ray.PlaneIntersection(position, normal));
        }
        /// <summary>
        /// Gets the nearest point on the translation axis.
        /// </summary>
        /// <param name="position">
        /// The position (in screen coordinates).
        /// </param>
        /// <param name="hitPlaneOrigin">
        /// The hit plane origin (world coordinate system).
        /// </param>
        /// <param name="hitPlaneNormal">
        /// The hit plane normal (world coordinate system).
        /// </param>
        /// <returns>
        /// The nearest point (world coordinates) or null if no point could be found.
        /// </returns>
        private Point3D?GetNearestPoint(Point position, Point3D hitPlaneOrigin, Vector3D hitPlaneNormal)
        {
            var hpp = this.GetHitPlanePoint(position, hitPlaneOrigin, hitPlaneNormal);

            if (hpp == null)
            {
                return(null);
            }

            var ray = new Ray3D(this.ToWorld(this.Position), this.ToWorld(this.Direction));

            return(ray.GetNearest(hpp.Value));
        }
示例#5
0
        /// <summary>
        /// Gets the nearest point on the translation axis.
        /// </summary>
        /// <param name="position">
        /// The position (in screen coordinates).
        /// </param>
        /// <param name="hitPlaneOrigin">
        /// The hit plane origin (world coordinate system).
        /// </param>
        /// <param name="hitPlaneNormal">
        /// The hit plane normal (world coordinate system).
        /// </param>
        /// <returns>
        /// The nearest point (world coordinates) or null if no point could be found.
        /// </returns>
        private Point3D? GetNearestPoint(Point position, Point3D hitPlaneOrigin, Vector3D hitPlaneNormal)
        {
            var hpp = this.GetHitPlanePoint(position, hitPlaneOrigin, hitPlaneNormal);
            if (hpp == null)
            {
                return null;
            }

            var ray = new Ray3D(this.ToWorld(this.Position), this.ToWorld(this.Direction));
            return ray.GetNearest(hpp.Value);
        }
示例#6
0
        /// <summary>
        /// Gets the intersection with the specified ray.
        /// </summary>
        /// <param name="ray">The ray.</param>
        /// <param name="result">The intersection point(s).</param>
        /// <returns>The intersection points sorted by distance from the ray origin.</returns>
        public bool RayIntersection(Ray3D ray, out Point3D[] result)
        {
            double cx = this.center.X;
            double cy = this.center.Y;
            double cz = this.center.Z;
            double r = this.radius;

            double x1 = ray.Origin.X;
            double y1 = ray.Origin.Y;
            double z1 = ray.Origin.Z;

            double dx = ray.Direction.X;
            double dy = ray.Direction.Y;
            double dz = ray.Direction.Z;

            // Quadratic solving
            double a = (dx * dx) + (dy * dy) + (dz * dz);
            double b = (2 * dx * (x1 - cx)) + (2 * dy * (y1 - cy)) + (2 * dz * (z1 - cz));
            double c = (x1 * x1) + (y1 * y1) + (z1 * z1) + (cx * cx) + (cz * cz) + (cy * cy) - (2 * ((cy * y1) + (cz * z1) + (cx * x1))) - (r * r);

            // Discriminant
            double q = (b * b) - (4 * a * c);

            // We have at least one possible intersection
            if (q >= 0)
            {
                double q2 = Math.Sqrt((b * b) - (4 * a * c));

                // First root
                double t1 = (-b + q2) / (2 * a);

                // Second root
                double t2 = (-b - q2) / (2 * a);

                if (t1 >= 0 && t2 >= 0 && !t1.Equals(t2))
                {
                    var i1 = new Point3D(x1 + (dx * t1), y1 + (dy * t1), z1 + (dz * t1));
                    var i2 = new Point3D(x1 + (dx * t2), y1 + (dy * t2), z1 + (dz * t2));

                    result = t1 < t2 ? new[] { i1, i2 } : new[] { i2, i1 };
                    return true;
                }

                if (t1 >= 0)
                {
                    var i1 = new Point3D(x1 + (dx * t1), y1 + (dy * t1), z1 + (dz * t1));
                    result = new[] { i1 };
                    return true;
                }

                if (t2 >= 0)
                {
                    var i2 = new Point3D(x1 + (dx * t2), y1 + (dy * t2), z1 + (dz * t2));
                    result = new[] { i2 };
                    return true;
                }
            }

            result = null;
            return false;
        }
        /// <summary>
        /// Updates the cursor position.
        /// </summary>
        /// <param name="pt">The position of the cursor (in viewport coordinates).</param>
        private void UpdateCursorPosition(Point pt)
        {
            this.CursorOnElementPosition = this.FindNearestPoint(pt);
            this.CursorPosition = this.Viewport.UnProject(pt);

            // Calculate the cursor ray
            Point3D cursorNearPlanePoint;
            Point3D cursorFarPlanePoint;
            var ok = this.Viewport.Point2DtoPoint3D(pt, out cursorNearPlanePoint, out cursorFarPlanePoint);
            if (ok)
            {
                var ray = new Ray3D(cursorFarPlanePoint, cursorNearPlanePoint);
                this.CursorRay = ray;
            }
            else
            {
                this.CursorOnConstructionPlanePosition = null;
                this.CursorRay = null;
            }

            // Calculate the intersection between the construction plane and the cursor ray
            if (this.CursorRay != null)
            {
                this.CursorOnConstructionPlanePosition = this.ConstructionPlane.LineIntersection(
                    this.CursorRay.Origin,
                    this.CursorRay.Origin + this.CursorRay.Direction);
            }
            else
            {
                this.CursorOnConstructionPlanePosition = null;
            }

            // TODO: remove this code when the CurrentPosition property is removed
            #pragma warning disable 618
            if (this.CursorOnElementPosition.HasValue)
            {
                this.CurrentPosition = this.CursorOnElementPosition.Value;
            }
            else
            {
                if (this.CursorPosition.HasValue)
                {
                    this.CurrentPosition = this.CursorPosition.Value;
                }
            }
            #pragma warning restore 618
        }
示例#8
0
        /// <summary>
        /// Gets the intersection with the specified ray.
        /// </summary>
        /// <param name="ray">
        /// The ray.
        /// </param>
        /// <param name="result">
        /// The result.
        /// </param>
        /// <returns>
        /// True if intersections were found.
        /// </returns>
        public bool RayIntersection(Ray3D ray, out Point3D[] result)
        {
            throw new NotImplementedException();

            // http://www.devmaster.net/wiki/Ray-sphere_intersection
        }
示例#9
0
        /// <summary>
        /// Gets the intersection with the specified ray.
        /// </summary>
        /// <param name="ray">
        /// The ray.
        /// </param>
        /// <param name="result">
        /// The result.
        /// </param>
        /// <returns>
        /// True if intersections were found.
        /// </returns>
        public bool RayIntersection(Ray3D ray, out Point3D[] result)
        {
            throw new NotImplementedException();

            // http://www.devmaster.net/wiki/Ray-sphere_intersection
        }
示例#10
0
        /// <summary>
        /// Gets the intersection with the specified ray.
        /// </summary>
        /// <param name="ray">The ray.</param>
        /// <param name="result">The intersection point(s).</param>
        /// <returns>The intersection points sorted by distance from the ray origin.</returns>
        public bool RayIntersection(Ray3D ray, out Point3D[] result)
        {
            double cx = this.center.X;
            double cy = this.center.Y;
            double cz = this.center.Z;
            double r  = this.radius;

            double x1 = ray.Origin.X;
            double y1 = ray.Origin.Y;
            double z1 = ray.Origin.Z;

            double dx = ray.Direction.X;
            double dy = ray.Direction.Y;
            double dz = ray.Direction.Z;

            // Quadratic solving
            double a = (dx * dx) + (dy * dy) + (dz * dz);
            double b = (2 * dx * (x1 - cx)) + (2 * dy * (y1 - cy)) + (2 * dz * (z1 - cz));
            double c = (x1 * x1) + (y1 * y1) + (z1 * z1) + (cx * cx) + (cz * cz) + (cy * cy) - (2 * ((cy * y1) + (cz * z1) + (cx * x1))) - (r * r);

            // Discriminant
            double q = (b * b) - (4 * a * c);

            // We have at least one possible intersection
            if (q >= 0)
            {
                double q2 = Math.Sqrt((b * b) - (4 * a * c));

                // First root
                double t1 = (-b + q2) / (2 * a);

                // Second root
                double t2 = (-b - q2) / (2 * a);

                if (t1 >= 0 && t2 >= 0 && !t1.Equals(t2))
                {
                    var i1 = new Point3D(x1 + (dx * t1), y1 + (dy * t1), z1 + (dz * t1));
                    var i2 = new Point3D(x1 + (dx * t2), y1 + (dy * t2), z1 + (dz * t2));

                    result = t1 < t2 ? new[] { i1, i2 } : new[] { i2, i1 };
                    return(true);
                }

                if (t1 >= 0)
                {
                    var i1 = new Point3D(x1 + (dx * t1), y1 + (dy * t1), z1 + (dz * t1));
                    result = new[] { i1 };
                    return(true);
                }

                if (t2 >= 0)
                {
                    var i2 = new Point3D(x1 + (dx * t2), y1 + (dy * t2), z1 + (dz * t2));
                    result = new[] { i2 };
                    return(true);
                }
            }

            result = null;
            return(false);
        }