OpenGL视角控制

 public class View
{
        private void OGLView_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case Keys.D:
                    this._currentEye = Matrix3D.RotateY(this._currentEye, -ONE_DEGREE, this._currentCenter);
                    this._currentUpVector = Matrix3D.RotateY(this._currentUpVector, -ONE_DEGREE, this._defaultCenter);
                    break;
                case Keys.A:
                    this._currentEye = Matrix3D.RotateY(this._currentEye, ONE_DEGREE, this._currentCenter);
                    this._currentUpVector = Matrix3D.RotateY(this._currentUpVector, ONE_DEGREE, this._defaultCenter);
                    break;
                case Keys.W:
                    this._currentEye = Matrix3D.RotateX(this._currentEye, -ONE_DEGREE, this._currentCenter);
                    this._currentUpVector = Matrix3D.RotateX(this._currentUpVector, -ONE_DEGREE, this._defaultCenter);
                    break;
                case Keys.S:
                    this._currentEye = Matrix3D.RotateX(this._currentEye, ONE_DEGREE, this._currentCenter);
                    this._currentUpVector = Matrix3D.RotateX(this._currentUpVector, ONE_DEGREE, this._defaultCenter);
                    break;
                case Keys.Q:
                    this._currentEye = Matrix3D.RotateZ(this._currentEye, ONE_DEGREE, this._currentCenter);
                    this._currentUpVector = Matrix3D.RotateZ(this._currentUpVector, ONE_DEGREE, this._defaultCenter);
                    break;
                case Keys.E:
                    this._currentEye = Matrix3D.RotateZ(this._currentEye, -ONE_DEGREE, this._currentCenter);
                    this._currentUpVector = Matrix3D.RotateZ(this._currentUpVector, -ONE_DEGREE, this._defaultCenter);
                    break;
                case Keys.R:
                    ResetUserView();
                    break;
                default:
                    break;
            }
            this.Refresh();
        }
        private void OGLView_MouseMove(object sender, MouseEventArgs e)
        {
            float xDelta = _mouseState.X - e.X;
            float yDelta = _mouseState.Y - e.Y;
            _mouseState.X = e.X;
            _mouseState.Y = e.Y;
            if (e.Button == MouseButtons.Left && e.Button != MouseButtons.Right && e.Button != MouseButtons.Middle)
            {
                //x方向移动旋转
                this._currentEye = Matrix3D.RotateZ(this._currentEye, xDelta * ONE_DEGREE / 5, this._currentCenter);
                this._currentUpVector = Matrix3D.RotateZ(this._currentUpVector, xDelta * ONE_DEGREE / 5, this._defaultCenter);
                float i = -Math.Abs(this._currentEye.y) / this._currentEye.y;
                //y方向移动翻转
                this._currentEye = Matrix3D.RotateXY(this._currentEye, i * yDelta * ONE_DEGREE / 5, this._currentCenter);
                this._currentUpVector = Matrix3D.RotateXY(this._currentUpVector, i * yDelta * ONE_DEGREE / 5, this._defaultCenter);
                this.Refresh();
            }
            else if (e.Button != MouseButtons.Left && e.Button == MouseButtons.Right && e.Button != MouseButtons.Middle)
            {
                Point3DF parTag = Matrix3D.MoveParallel(this._currentUpVector, xDelta);
                this._currentEye.x += parTag.x;
                this._currentEye.y += parTag.y;
                this._currentCenter.x += parTag.x;
                this._currentCenter.y += parTag.y;
                Point3DF verTag = Matrix3D.MoveVertical(this._currentUpVector, yDelta);
                this._currentEye.x += verTag.x;
                this._currentEye.y += verTag.y;
                this._currentCenter.x += verTag.x;
                this._currentCenter.y += verTag.y;
                this.Refresh();
            }
        }
        private void OGLView_MouseWheel(object sender, MouseEventArgs e)
        {
            this._currentEye = Matrix3D.Zoom(this._currentEye, -e.Delta / 100, this._currentCenter);
            this.Refresh();
        }
}
using System;
using System.Collections.Generic;
using System.Text;
namespace A
{
    public static class Matrix3D
    {
        /// <summary>
        /// Moves parallelly.
        /// </summary>
        /// <param name="currentUpVector">The current up vector.</param>
        /// <param name="delta">The delta.</param>
        /// <returns></returns>
        public static Point3DF MoveParallel(Point3DF currentUpVector, float delta)
        {
            float i = currentUpVector.x / (Math.Abs(currentUpVector.x));
            Point3DF newPositionDelta = new Point3DF();
            float k = currentUpVector.y / currentUpVector.x;
            float temp = symbol * (float)(1 / Math.Sqrt(k * k + 1));
            newPositionDelta.x =  delta * k * temp;
            newPositionDelta.y = - delta * temp;
            newPositionDelta.z = currentUpVector.z;
            return newPositionDelta;
        }
        /// <summary>
        /// Moves vertically.
        /// </summary>
        /// <param name="currentUpVector">The current up vector.</param>
        /// <param name="delta">The delta.</param>
        /// <returns></returns>
        public static Point3DF MoveVertical(Point3DF currentUpVector, float delta)
        {
            float symbol = -currentUpVector.x / (Math.Abs(currentUpVector.x));
            Point3DF newPositionDelta = new Point3DF();
            float k = currentUpVector.y / currentUpVector.x;
            float temp = symbol * (float)(1 / Math.Sqrt(k * k + 1));
            newPositionDelta.x = delta * temp;
            newPositionDelta.y = delta * k * temp;
            newPositionDelta.z = currentUpVector.z;
            return newPositionDelta;
        }
        /// <summary>
        /// Rotates around the X axis.
        /// </summary>
        /// <param name="oldPosition">The old position.</param>
        /// <param name="angle">The angle.</param>
        /// <returns></returns>
        public static Point3DF RotateX(Point3DF position, float angle)
        {
            Point3DF newPosition = new Point3DF();
            newPosition.y = position.y * (float)Math.Cos(angle) - position.z * (float)Math.Sin(angle);
            newPosition.z = position.y * (float)Math.Sin(angle) + position.z * (float)Math.Cos(angle);
            newPosition.x = position.x;
            return newPosition;
        }
        /// <summary>
        /// Rotates around the X axis.
        /// </summary>
        /// <param name="oldPosition">The old position.</param>
        /// <param name="angle">The angle.</param>
        /// <param name="center">The center.</param>
        /// <returns></returns>
        public static Point3DF RotateX(Point3DF position, float angle, Point3DF center)
        {
            float deltaY = center.y;
            float deltaZ = center.z;
            Point3DF tagPosition = new Point3DF();
            tagPosition.x = position.x;
            tagPosition.y = position.y - deltaY;
            tagPosition.z = position.z - deltaZ;
            tagPosition = Matrix3D.RotateX(tagPosition, angle);
            Point3DF newPosition = new Point3DF();
            newPosition.x = tagPosition.x;
            newPosition.y = tagPosition.y + deltaY;
            newPosition.z = tagPosition.z + deltaZ;
            return newPosition;
        }
        /// <summary>
        /// Rotates around the Y axis.
        /// </summary>
        /// <param name="oldPosition">The old position.</param>
        /// <param name="angle">The angle.</param>
        /// <returns></returns>
        public static Point3DF RotateY(Point3DF position, float angle)
        {
            Point3DF newPosition = new Point3DF();
            newPosition.z = position.z * (float)Math.Cos(angle) - position.x * (float)Math.Sin(angle);
            newPosition.x = position.z * (float)Math.Sin(angle) + position.x * (float)Math.Cos(angle);
            newPosition.y = position.y;
            return newPosition;
        }
        /// <summary>
        /// Rotates around the Y axis.
        /// </summary>
        /// <param name="oldPosition">The old position.</param>
        /// <param name="angle">The angle.</param>
        /// <param name="center">The center.</param>
        /// <returns></returns>
        public static Point3DF RotateY(Point3DF position, float angle, Point3DF center)
        {
            float deltaX = center.x;
            float deltaZ = center.z;
            Point3DF tagPositon = new Point3DF();
            tagPositon.x = position.x - deltaX;
            tagPositon.y = position.y;
            tagPositon.z = position.z - deltaZ;
            tagPositon = Matrix3D.RotateY(tagPositon, angle);
            Point3DF newPosition = new Point3DF();
            newPosition.x = tagPositon.x + deltaX;
            newPosition.y = tagPositon.y;
            newPosition.z = tagPositon.z + deltaZ;
            return newPosition;
        }
        /// <summary>
        /// Rotates around the z saxis.
        /// </summary>
        /// <param name="oldPosition">The old position.</param>
        /// <param name="angle">The angle.</param>
        /// <returns></returns>
        public static Point3DF RotateZ(Point3DF position, float angle)
        {
            Point3DF newPosition = new Point3DF();
            newPosition.x = position.x * (float)Math.Cos(angle) - position.y * (float)Math.Sin(angle);
            newPosition.y = position.x * (float)Math.Sin(angle) + position.y * (float)Math.Cos(angle);
            newPosition.z = position.z;
            return newPosition;
        }
        /// <summary>
        /// Rotates around the Z axis.
        /// </summary>
        /// <param name="oldPosition">The old position.</param>
        /// <param name="angle">The angle.</param>
        /// <param name="center">The center.</param>
        /// <returns></returns>
        public static Point3DF RotateZ(Point3DF position, float angle, Point3DF center)
        {
            float deltaX = center.x;
            float deltaY = center.y;
            Point3DF tagPositon = new Point3DF();
            tagPositon.x = position.x - deltaX;
            tagPositon.y = position.y - deltaY;
            tagPositon.z = position.z;
            tagPositon = Matrix3D.RotateZ(tagPositon, angle);
            Point3DF newPosition = new Point3DF();
            newPosition.x = tagPositon.x + deltaX;
            newPosition.y = tagPositon.y + deltaY;
            newPosition.z = tagPositon.z;
            return newPosition;
        }
        /// <summary>
        /// Zooms your view.
        /// </summary>
        /// <param name="oldPosition">The current position.</param>
        /// <param name="factor">The factor.</param>
        /// <param name="center">The center.</param>
        /// <returns></returns>
        public static Point3DF Zoom(Point3DF position, float factor, Point3DF center)
        {
            Point3DF newPosition;
            float deltaX = position.x - center.x;
            float deltaY = position.y - center.y;
            float deltaZ = position.z - center.z;
            newPosition.x = center.x + deltaX * (1 + factor / 10);
            newPosition.y = center.y + deltaY * (1 + factor / 10);
            newPosition.z = center.z + deltaZ * (1 + factor / 10);
            return newPosition;
        }
        /// <summary>
        /// Rotate the xy surface
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        public static Point3DF RotateXY(Point3DF position, float angle)
        {
            float tagK = position.y / position.x;
            float k = -1 / tagK;
            float kAngle = (float)Math.Atan(k);
            Point3DF tagPosition = new Point3DF();
            tagPosition = RotateZ(position, -kAngle);
            Point3DF tagPosition1 = new Point3DF();
            tagPosition1 = RotateX(tagPosition, angle);
            Point3DF newPositioin = new Point3DF();
            newPositioin = RotateZ(tagPosition1, kAngle);
            return newPositioin;
        }
        /// <summary>
        /// Rotates the XY surface.
        /// </summary>
        /// <param name="position">The current position.</param>
        /// <param name="angle">The angle.</param>
        /// <param name="currentCenter">The current center.</param>
        /// <returns></returns>
        public static Point3DF RotateXY(Point3DF position, float angle, Point3DF currentCenter)
        {
            float deltaX = currentCenter.x;
            float deltaY = currentCenter.y;
            Point3DF tagPosition = new Point3DF();
            tagPosition.x = position.x - deltaX;
            tagPosition.y = position.y - deltaY;
            tagPosition.z = position.z;
            Point3DF tagPosition1 = new Point3DF();
            tagPosition1 = RotateXY(tagPosition, angle);
            Point3DF newPosition = new Point3DF();
            newPosition.x = tagPosition1.x + deltaX;
            newPosition.y = tagPosition1.y + deltaY;
            newPosition.z = tagPosition1.z;
            return newPosition;
        }
    }
    public struct Point3DF
    {
        public float x;
        public float y;
        public float z;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值