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 / 5this._currentCenter);
                
this._currentUpVector = Matrix3D.RotateZ(this._currentUpVector, xDelta * ONE_DEGREE / 5this._defaultCenter);

                
float i = -Math.Abs(this._currentEye.y) / this._currentEye.y;
                
//y方向移动翻转
                IList<Point3DF> upPosition;
                upPosition 
= Matrix3D.RotateXY(this._currentEye, this._currentUpVector, i * yDelta * ONE_DEGREE / 5this._currentCenter);
                
this._currentEye = (Point3DF)upPosition[0];
                
this._currentUpVector = (Point3DF)upPosition[1];

                
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 / 100this._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 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 static IList<Point3DF> RotateXY(Point3DF position, Point3DF up, float angle, Point3DF currentCenter)
        {
            IList
<Point3DF> positionUpList = new List<Point3DF>();
            IList
<Point3DF> tagPositionUpList = new List<Point3DF>();

            
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;

            tagPositionUpList 
= RotateXY(tagPosition, up, angle);

            Point3DF newPosition 
= new Point3DF();
            newPosition.x 
= ((Point3DF)tagPositionUpList[0]).x + deltaX;
            newPosition.y 
= ((Point3DF)tagPositionUpList[0]).y + deltaY;
            newPosition.z 
= ((Point3DF)tagPositionUpList[0]).z;

            positionUpList.Add(newPosition);
            positionUpList.Add(tagPositionUpList[
1]);

            
return positionUpList;
        }

    }

    
public struct Point3DF
    {
        
public float x;
        
public float y;
        
public float z;
posted @ 2009-10-03 18:29  Revive and Strive  阅读(1940)  评论(0编辑  收藏  举报