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; } }