private void MoveHoverLight(MouseEventArgs e)
        {
            Point mousePos = e.GetPosition(pnlIconBorder);

            double width = pnlIconBorder.ActualWidth;
            double height = pnlIconBorder.ActualHeight;

            DoubleVector standard = new DoubleVector(
                ProjectToTrackball(width, height, new Point(width * .5d, height * .5d)),
                ProjectToTrackball(width, height, new Point(width * .5d, height)));

            Vector3D camPos = _camera.Position.ToVector();
            Vector3D cross1 = Vector3D.CrossProduct(camPos, _camera.UpDirection * -1d);
            Vector3D cross2 = Vector3D.CrossProduct(cross1, camPos);
            DoubleVector camera = new DoubleVector(camPos, cross2);		// can't use camera.up directly, because it's not nessassarily orthogonal

            // Attach the point to a sphere around the ship
            Vector3D projectedPos = ProjectToTrackball(width, height, mousePos);

            // Rotate this so that it's relative to the camera
            Quaternion rotation = standard.GetRotation(camera);

            _hoverLight.Position = rotation.GetRotatedVector(projectedPos * 2d).ToPoint();
        }
        private Quaternion GetRotationForDelta()
        {
            DoubleVector screenPlane = new DoubleVector(1, 0, 0, 0, 1, 0);
            DoubleVector cameraPlane = new DoubleVector(_camera1.LookDirection.GetRotatedVector(_camera1.UpDirection, -90), _camera1.UpDirection);

            return screenPlane.GetRotation(cameraPlane);
        }
        private void btnTestIt_Click(object sender, RoutedEventArgs e)
        {
            Vector3D defaultStand = new Vector3D(LINELENGTH_X * .75d, 0, 0);
            Vector3D defaultOrth = new Vector3D(0, 0, LINELENGTH_Z * .75d);

            DoubleVector from = new DoubleVector(_orientationTrackballFrom.Transform.Transform(defaultStand), _orientationTrackballFrom.Transform.Transform(defaultOrth));
            DoubleVector to = new DoubleVector(_orientationTrackballTo.Transform.Transform(defaultStand), _orientationTrackballTo.Transform.Transform(defaultOrth));

            // This is the method that this form is testing
            Quaternion quat = from.GetRotation(to);

            //DoubleVector rotated = new DoubleVector(quat.GetRotatedVector(defaultStand), quat.GetRotatedVector(defaultOrth));
            DoubleVector rotated = new DoubleVector(quat.GetRotatedVector(from.Standard), quat.GetRotatedVector(from.Orth));		// quat describes how to rotate from From to To (not from Default to To)

            //Vector3D axis = quat.Axis.ToUnit() * (LINELENGTH_X * 2d);
            Vector3D axis = _orientationTrackballFrom.Transform.Transform(quat.Axis.ToUnit() * (LINELENGTH_X * 1.5d));		// I rotate axis by from, because I want it relative to from (axis isn't in world coords)

            pnlReport.Children.Clear();
            ClearTempVisuals();
            ClearLines(_lineTransformed);
            _lineTransformed = AddLines(rotated, axis);
        }
        private static Transform3D GetTransformTo2D(ITriangle triangle)
        {
            Vector3D line1 = triangle.Point1 - triangle.Point0;

            DoubleVector from = new DoubleVector(line1, Math3D.GetOrthogonal(line1, triangle.Point2 - triangle.Point0));
            DoubleVector to = new DoubleVector(new Vector3D(1, 0, 0), new Vector3D(0, 1, 0));

            Quaternion rotation = from.GetRotation(to);

            Transform3DGroup retVal = new Transform3DGroup();

            // Rotate
            retVal.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotation)));

            // Then translate
            retVal.Children.Add(new TranslateTransform3D(0, 0, -triangle.Point0.Z));

            return retVal;
        }
        private void FireRaySprtShootBall()
        {
            Vector3D velocity = _rayDirection.ToUnit() * trkBulletSpeed.Value;
            DoubleVector directionFacing = new DoubleVector(velocity, Math3D.GetArbitraryOrhonganal(velocity));

            switch (cboLeftBallType.Text)
            {
                case "Nerf":
                    #region Nerf

                    AddCannonBall(
                        CollisionShapeType.Cylinder,
                        Colors.Coral,
                        new Vector3D(.75d, 5d, 0d),		// x is radius, y is height
                        .1d,
                        _rayPoint,
                        velocity,
                        new Vector3D(),
                        directionFacing);

                    #endregion
                    break;

                case "Pellet":
                    #region Pellet

                    AddCannonBall(
                        CollisionShapeType.Sphere,
                        Colors.SteelBlue,
                        new Vector3D(.5d, .5d, .5d),
                        2d,
                        _rayPoint,
                        velocity,
                        new Vector3D(),
                        directionFacing);

                    #endregion
                    break;

                case "Slug":
                    #region Slug

                    AddCannonBall(
                        CollisionShapeType.Cylinder,
                        Colors.DimGray,
                        new Vector3D(.5d, .8d, 0d),		// x is radius, y is height
                        6d,
                        _rayPoint,
                        velocity,
                        new Vector3D(),
                        directionFacing);

                    #endregion
                    break;

                case "Baseball":
                    #region Baseball

                    AddCannonBall(
                        CollisionShapeType.Sphere,
                        Colors.GhostWhite,
                        new Vector3D(2d, 2d, 2d),
                        5d,
                        _rayPoint,
                        velocity,
                        new Vector3D(),
                        directionFacing);

                    #endregion
                    break;

                case "Cannon":
                    #region Cannon

                    AddCannonBall(
                        CollisionShapeType.Sphere,
                        Color.FromArgb(255, 45, 45, 32),
                        new Vector3D(2d, 2d, 2d),
                        15d,
                        _rayPoint,
                        velocity,
                        new Vector3D(),
                        directionFacing);

                    #endregion
                    break;

                case "Wrecker":
                    #region Wrecker

                    AddCannonBall(
                        CollisionShapeType.Sphere,
                        Color.FromArgb(255, 50, 15, 15),
                        new Vector3D(4d, 4d, 4d),
                        60d,
                        _rayPoint,
                        velocity,
                        new Vector3D(),
                        directionFacing);

                    #endregion
                    break;

                case "Shotgun":
                    #region Shotgun

                    // Build a transform to go from origin to camera
                    DoubleVector originDirFacing = new DoubleVector(0, 0, 1, 0, 1, 0);
                    Quaternion rotationToCameraRay = originDirFacing.GetRotation(new DoubleVector(_rayDirection, Math3D.GetArbitraryOrhonganal(_rayDirection)));
                    Transform3DGroup transformToCamera = new Transform3DGroup();
                    transformToCamera.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotationToCameraRay)));
                    transformToCamera.Children.Add(new TranslateTransform3D(_rayPoint.ToVector()));

                    for (int cntr = 0; cntr < 10; cntr++)
                    {
                        Vector3D pos2D = Math3D.GetRandomVector_Circular(1d);
                        //Vector3D vel2D = new Vector3D(pos2D.X, pos2D.Y, trkBulletSpeed.Value * 2d);


                        //Point3D position = _rayPoint;
                        velocity = _rayDirection.ToUnit() * trkBulletSpeed.Value * 2d;		//TODO:  Diverge the shot

                        Point3D position = transformToCamera.Transform(pos2D.ToPoint());
                        //velocity = transformToCamera.Transform(vel2D);


                        directionFacing = new DoubleVector(velocity, Math3D.GetArbitraryOrhonganal(velocity));

                        AddCannonBall(
                            CollisionShapeType.Sphere,
                            Color.FromRgb(25, 25, 25),
                            new Vector3D(.1d, .1d, .1d),
                            .2d,
                            position,
                            velocity,
                            new Vector3D(),
                            directionFacing);

                    }

                    #endregion
                    break;

                default:
                    MessageBox.Show("Unknown ball type: " + cboLeftBallType.Text, this.Title, MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
            }


        }