private Matrix4x4 mProjection; //投影矩阵 public Form1() { InitializeComponent(); mScale = new Matrix4x4(); mRotationX = new Matrix4x4(); mRotationY = new Matrix4x4(); mRotationZ = new Matrix4x4(); mView = new Matrix4x4(); mProjection = new Matrix4x4(); //初始化缩放矩阵 mScale[1, 1] = 250; mScale[2, 2] = 250; mScale[3, 3] = 250; mScale[4, 4] = 1; //初始化视图矩阵 mView[1, 1] = 1; mView[2, 2] = 1; mView[3, 3] = 1; mView[4, 3] = camDistance; //相机距离 mView[4, 4] = 1; //初始化投影矩阵 mProjection[1, 1] = 1; mProjection[2, 2] = 1; mProjection[3, 3] = 1; mProjection[3, 4] = 1f / camDistance; }
/// <summary> /// 计算光照 /// </summary> /// <param name="obj2World">模型矩阵</param> /// <param name="light">光方向</param> public void CalculateLighting(Matrix4x4 obj2World, Vector4 light) { // 应用模型矩阵,转换到世界坐标 Transform(obj2World); //求两个边 Vector4 u = b - a; Vector4 v = c - a; //叉乘得法向量 normal = u.Cross(v); //标准化法向量和灯光向量 Vector4 normalNor = normal.Normalized; Vector4 lightNor = light.Normalized; //计算灯光和法向量的点积 dot = normalNor.Dot(lightNor); //限制在0-1范围 dot = Math.Max(0, dot); //视线向量,z的反方向 Vector4 sight = new Vector4(0, 0, -1, 0); //计算是否背面剔除 cullBack = normalNor.Dot(sight) < 0; }
/// <summary> /// 计算光照 /// </summary> /// <param name="obj2World">模型矩阵</param> /// <param name="light">光方向</param> public void CalculateLighting(Matrix4x4 obj2World, Vector4 light) { foreach (Triangle3D t in triangles) { t.CalculateLighting(obj2World, light); } }
private void timer1_Tick(object sender, EventArgs e) { // 角度变化 angle += 3; double rAngle = angle / 360f * Math.PI; // 更新绕x旋转矩阵 mRotationX[1, 1] = 1; mRotationX[2, 2] = Math.Cos(rAngle); mRotationX[2, 3] = Math.Sin(rAngle); mRotationX[3, 2] = -Math.Sin(rAngle); mRotationX[3, 3] = Math.Cos(rAngle); mRotationX[4, 4] = 1; // 更新绕y旋转矩阵 mRotationY[1, 1] = Math.Cos(rAngle); mRotationY[1, 3] = Math.Sin(rAngle); mRotationY[2, 2] = 1; mRotationY[3, 1] = -Math.Sin(rAngle); mRotationY[3, 3] = Math.Cos(rAngle); mRotationY[4, 4] = 1; //// 更新绕z旋转矩阵 mRotationZ[1, 1] = Math.Cos(rAngle); mRotationZ[1, 2] = Math.Sin(rAngle); mRotationZ[2, 1] = -Math.Sin(rAngle); mRotationZ[2, 2] = Math.Cos(rAngle); mRotationZ[3, 3] = 1; mRotationZ[4, 4] = 1; //撤销X轴旋转效果 if (checkBox_x.Checked) { //乘以转置矩阵等效于乘以逆矩阵 Matrix4x4 tx = mRotationX.Transpose(); mRotationX = mRotationX.Mul(tx); } //撤销Y轴旋转效果 if (checkBox_y.Checked) { //乘以转置矩阵等效于乘以逆矩阵 Matrix4x4 ty = mRotationY.Transpose(); mRotationY = mRotationY.Mul(ty); } //撤销Z轴旋转效果 if (checkBox_z.Checked) { //乘以转置矩阵等效于乘以逆矩阵 Matrix4x4 tz = mRotationZ.Transpose(); mRotationZ = mRotationZ.Mul(tz); } Matrix4x4 mall = mRotationX.Mul(mRotationY.Mul(mRotationZ)); // 组合模型矩阵 Matrix4x4 m = mScale.Mul(mall); if (drawCube){ cube.CalculateLighting(m, new Vector4(-1, 1, -1, 0)); } else{ triangle3D.CalculateLighting(m, new Vector4(-1, 1, -1, 0)); } // 应用视图矩阵 Matrix4x4 mv = m.Mul(mView); // 应用投影矩阵 Matrix4x4 mvp = mv.Mul(mProjection); // 应用变换矩阵 if (drawCube){ cube.Transform(mvp); } else{ triangle3D.Transform(mvp); } this.Invalidate(); }
/// <summary> /// 三角形利用矩阵的乘法进行变换 /// </summary> /// <param name="m">变换矩阵的组合</param> public void Transform(Matrix4x4 m) { a = m.Mul(A); b = m.Mul(B); c = m.Mul(C); }
/// <summary> /// 矩阵变换 /// </summary> public void Transform(Matrix4x4 m) { foreach (Triangle3D t in triangles){ t.Transform(m); } }