public Point GetNextPoint(Point warpPoint)
        {
            Rectangle screenSize = PrecisionGazeMouseForm.GetScreenSize();

            switch (mode)
            {
            case (PrecisionPointerMode.ROTATION):
                rot = this.getRotation();
                if (rot != null)
                {
                    // When a person looks to the edge of the screen, they rotate their head slightly. It'd be annoying if
                    // the pointer was always offset down when we looked down, for example. So we need to correct for it.
                    // Assuming a neutral head position is the middle of the screen, and the edge rotation is the number of
                    // pixels of head rotation we'd get when looking at the edge of the screen, calculate the ratio we expect
                    // at the given warp point.
                    double basePitch = (warpPoint.Y - screenSize.Height / 2.0) / (screenSize.Height / 2.0) * EDGE_Y_ROTATION;

                    // subtract the pixels due to looking at the warp point, and scale the offset by the sensitivity setting
                    int yOffset = (int)((rot.pitch - basePitch) * sensitivity / BASELINE_SENSITIVITY);

                    double baseYaw = (warpPoint.X - screenSize.Width / 2.0) / (screenSize.Width / 2.0) * EDGE_X_ROTATION;
                    int    xOffset = (int)((-1 * rot.yaw - baseYaw) * sensitivity / BASELINE_SENSITIVITY);

                    warpPoint.Offset(xOffset, yOffset);

                    return(warpPoint);
                }
                break;

            case (PrecisionPointerMode.TRANSLATION):
                trans = this.getTranslation();
                if (trans != null)
                {
                    warpPoint.Offset((int)(trans.x / 1.5), (int)(trans.y / 1.5));
                    return(warpPoint);
                }
                break;

            case (PrecisionPointerMode.BOTH):
                trans = this.getTranslation();
                if (trans != null)
                {
                    warpPoint.Offset((int)(trans.x / 1.5), 0);     // set y to zero because translating head/up down is difficult, and it throws off the rotation
                }
                rot = this.getRotation();
                if (rot != null)
                {
                    double basePitch = (warpPoint.Y - screenSize.Height / 2.0) / (screenSize.Height / 2.0) * EDGE_Y_ROTATION;
                    int    yOffset   = (int)((rot.pitch - basePitch) * sensitivity / BASELINE_SENSITIVITY);

                    double baseYaw = (warpPoint.X - screenSize.Width / 2.0) / (screenSize.Width / 2.0) * EDGE_X_ROTATION;
                    int    xOffset = (int)((-1 * rot.yaw - baseYaw) * sensitivity / BASELINE_SENSITIVITY);

                    warpPoint.Offset(xOffset, yOffset);
                }
                return(warpPoint);
            }

            return(warpPoint);
        }
        HeadRotation getRotation()
        {
            HeadRotation o = new HeadRotation();

            o.pitch = tid.fNPPitch;
            o.yaw   = tid.fNPYaw;
            return(o);
        }
        public Point GetNextPoint(Point warpPoint)
        {
            Rectangle screenSize = PrecisionGazeMouseForm.GetScreenSize();

            switch (mode)
            {
            case (PrecisionPointerMode.ROTATION):
                rot = this.getRotation();
                if (rot != null)
                {
                    double basePitch = (warpPoint.Y - screenSize.Height / 2.0) / (screenSize.Height / 2.0) * 200.0;
                    int    yOffset   = (int)((rot.pitch - basePitch) * sensitivity / 20);

                    double baseYaw = (warpPoint.X - screenSize.Width / 2.0) / (screenSize.Width / 2.0) * 600.0;
                    int    xOffset = (int)((-1 * rot.yaw - baseYaw) * sensitivity / 20);

                    warpPoint.Offset(xOffset, yOffset);

                    return(warpPoint);
                }
                break;

            case (PrecisionPointerMode.TRANSLATION):
                trans = this.getTranslation();
                if (trans != null)
                {
                    warpPoint.Offset((int)(trans.x / 1.5), (int)(trans.y / 1.5));
                    return(warpPoint);
                }
                break;

            case (PrecisionPointerMode.BOTH):
                trans = this.getTranslation();
                if (trans != null)
                {
                    warpPoint.Offset((int)(trans.x / 1.5), 0);     // set y to zero because translating head/up down is difficult, and it throws off the rotation
                }
                rot = this.getRotation();
                if (rot != null)
                {
                    double basePitch = (warpPoint.Y - screenSize.Height / 2.0) / (screenSize.Height / 2.0) * 200.0;
                    int    yOffset   = (int)((rot.pitch - basePitch) * sensitivity / 20);

                    double baseYaw = (warpPoint.X - screenSize.Width / 2.0) / (screenSize.Width / 2.0) * 600.0;
                    int    xOffset = (int)((-1 * rot.yaw - baseYaw) * sensitivity / 20);

                    warpPoint.Offset(xOffset, yOffset);
                }
                return(warpPoint);
            }

            return(warpPoint);
        }
        public Point GetNextPoint(Point warpPoint)
        {
            Rectangle screenSize = PrecisionGazeMouseForm.GetScreenSize();

            switch (mode)
            {
            case (PrecisionPointerMode.ROTATION):
                rot = this.getRotation();
                if (rot != null)
                {
                    double basePitch = (warpPoint.Y - screenSize.Height / 2.0) / (screenSize.Height / 2.0) * 200.0;
                    int    yOffset   = (int)((rot.pitch - basePitch) * sensitivity / 20);

                    double baseYaw = (warpPoint.X - screenSize.Width / 2.0) / (screenSize.Width / 2.0) * 600.0;
                    int    xOffset = (int)((-1 * rot.yaw - baseYaw) * sensitivity / 20);

                    warpPoint.Offset(xOffset, yOffset);

                    return(warpPoint);
                }
                break;

            case (PrecisionPointerMode.TRANSLATION):
                trans = this.getTranslation();
                if (trans != null)
                {
                    warpPoint.Offset((int)(trans.x / 1.5), (int)(trans.y / 1.5));
                    return(warpPoint);
                }
                break;

            case (PrecisionPointerMode.BOTH):
                trans = this.getTranslation();
                if (trans != null)
                {
                    warpPoint.Offset((int)(trans.x / 1.5), 0);       // set y to zero because translating head/up down is difficult, and it throws off the rotation
                }
                rot = this.getRotation();
                if (rot != null)
                {
                    double basePitch = (warpPoint.Y - screenSize.Height / 2.0) / (screenSize.Height / 2.0) * 200.0;
                    int    yOffset   = (int)((rot.pitch - basePitch) * sensitivity / 20);

                    double baseYaw = (warpPoint.X - screenSize.Width / 2.0) / (screenSize.Width / 2.0) * 600.0;
                    int    xOffset = (int)((-1 * rot.yaw - baseYaw) * sensitivity / 20);

                    warpPoint.Offset(xOffset, yOffset);
                }
                return(warpPoint);

            case (PrecisionPointerMode.JOYSTICK):
                rot = this.getRotation();

                float xValue = -1 * rot.yaw / 100;
                float yValue = rot.pitch / 100;

                if (xJoystickMode = (Math.Abs(xValue) <= 20))
                {
                    float referenceValue = 40;     // when value is referenceValue, right of screen, -referenceValue left of screen
                    float normalized     = (xValue + referenceValue) / (referenceValue * 2);
                    warpPoint.X = (int)Math.Floor(normalized * screenSize.Width);
                }
                else
                {
                    warpPoint.X = (int)Math.Floor(xValue);
                }

                if (yJoystickMode = (Math.Abs(yValue) <= 20))
                {
                    float referenceValue = 40;     // when value is referenceValue, top of screen, -referenceValue bottom of screen
                    float normalized     = (yValue + referenceValue) / (referenceValue * 2);
                    warpPoint.Y = (int)Math.Floor(normalized * screenSize.Width);
                }
                else
                {
                    warpPoint.Y = (int)Math.Floor(yValue);
                }

                return(warpPoint);
            }

            return(warpPoint);
        }