Beispiel #1
0
        private static Point3D?CastRay_Line(out double clickDistanceSquared, Point3D point, Vector3D direction, RayHitTestParameters mouseDownClickRay, RayHitTestParameters mouseDownCenterRay, RayHitTestParameters currentClickRay)
        {
            // This is the offset along the drag line from the center to mouse down click
            Vector3D offset;

            Point3D?point1, point2, point3, point4;

            if (Math3D.GetClosestPoints_Line_Line(out point1, out point2, point, direction, mouseDownClickRay.Origin, mouseDownClickRay.Direction) &&
                Math3D.GetClosestPoints_Line_Line(out point3, out point4, point, direction, mouseDownCenterRay.Origin, mouseDownCenterRay.Direction))
            {
                offset = point3.Value - point1.Value;           // clickpoint on drag line minus centerpoint on drag line
            }
            else
            {
                // The click ray is parallel to the drag axis.  This should be extremely rare
                offset = new Vector3D(0, 0, 0);
            }

            // Now that the offset is known, project the current click ray onto the drag line
            if (Math3D.GetClosestPoints_Line_Line(out point1, out point2, point, direction, currentClickRay.Origin, currentClickRay.Direction))
            {
                clickDistanceSquared = (point2.Value - point1.Value).LengthSquared;
                return(point1.Value + offset);
            }
            else
            {
                clickDistanceSquared = 0;
                return(null);
            }
        }
Beispiel #2
0
        private static Point3D?CastRay_LinesCircles(IEnumerable <RayHitTestParameters> lines, IEnumerable <CircleDefinition> circles, RayHitTestParameters ray)
        {
            Point3D?retVal   = null;
            double  distance = double.MaxValue;

            if (lines != null)
            {
                // Cast onto each line, and return the point that's closest to the ray's origin
                foreach (RayHitTestParameters line in lines)
                {
                    Point3D?point1, point2;
                    if (Math3D.GetClosestPoints_Line_Line(out point1, out point2, line.Origin, line.Direction, ray.Origin, ray.Direction))
                    {
                        double localDistance = (point2.Value - point1.Value).LengthSquared;
                        if (retVal == null || localDistance < distance)
                        {
                            retVal   = point1.Value;
                            distance = localDistance;
                        }
                    }
                }
            }

            if (circles != null)
            {
                // Cast onto each circle, and return the point that's closest to the ray's origin
                foreach (CircleDefinition circle in circles)
                {
                    Point3D[] points1, points2;
                    if (Math3D.GetClosestPoints_Circle_Line(out points1, out points2, circle.Plane, circle.Center, circle.Radius, ray.Origin, ray.Direction, Math3D.RayCastReturn.ClosestToRay))
                    {
                        double localDistance = (points2[0] - points1[0]).LengthSquared;
                        if (retVal == null || localDistance < distance)
                        {
                            retVal   = points1[0];
                            distance = localDistance;
                        }
                    }
                }
            }

            return(retVal);
        }
Beispiel #3
0
        /// <summary>
        /// This overload is a straight ray cast, nothing extra
        /// </summary>
        public Point3D?CastRay(RayHitTestParameters ray)
        {
            Point3D?retVal = null;

            switch (_shape)
            {
            case ShapeType.Line:
                #region Line

                Point3D?point1, point2;
                if (Math3D.GetClosestPoints_Line_Line(out point1, out point2, _point, _direction, ray.Origin, ray.Direction))
                {
                    retVal = point1.Value;
                }

                #endregion
                break;

            case ShapeType.Lines:
                #region Lines

                retVal = CastRay_LinesCircles(_lines, null, ray);

                #endregion
                break;

            case ShapeType.Plane:
                #region Plane

                retVal = Math3D.GetIntersection_Plane_Line(_plane, ray.Origin, ray.Direction);

                #endregion
                break;

            case ShapeType.Circle:
                #region Circle

                Point3D[] nearestCirclePoints, nearestLinePoints;
                if (Math3D.GetClosestPoints_Circle_Line(out nearestCirclePoints, out nearestLinePoints, _plane, _point, _radius, ray.Origin, ray.Direction, Math3D.RayCastReturn.ClosestToRay))
                {
                    retVal = nearestCirclePoints[0];
                }

                #endregion
                break;

            case ShapeType.Circles:
                #region Circles

                retVal = CastRay_LinesCircles(null, _circles, ray);

                #endregion
                break;

            case ShapeType.LinesCircles:
                #region LinesCircles

                retVal = CastRay_LinesCircles(_lines, _circles, ray);

                #endregion
                break;

            case ShapeType.Cylinder:
                #region Cylinder

                Point3D[] nearestCylinderPoints, nearestLinePoints2;
                if (Math3D.GetClosestPoints_Cylinder_Line(out nearestCylinderPoints, out nearestLinePoints2, _point, _direction, _radius, ray.Origin, ray.Direction, Math3D.RayCastReturn.ClosestToRay))
                {
                    retVal = nearestCylinderPoints[0];
                }

                #endregion
                break;

            case ShapeType.Sphere:
                #region Sphere

                Point3D[] nearestSpherePoints, nearestLinePoints3;
                Math3D.GetClosestPoints_Sphere_Line(out nearestSpherePoints, out nearestLinePoints3, _point, _radius, ray.Origin, ray.Direction, Math3D.RayCastReturn.ClosestToRay);
                {
                    retVal = nearestSpherePoints[0];
                }

                #endregion
                break;

            case ShapeType.Mesh:
                throw new ApplicationException("finish this");

            case ShapeType.None:
                retVal = null;
                break;

            default:
                throw new ApplicationException("Unknown ShapeType: " + _shape.ToString());
            }

            return(retVal);
        }