WPF 画一个3D矩形并旋转
具体的代码还是线性代数。
主要是旋转和平移。
这个例子的中模型是在世界原点建立。所以旋转会以自身轴心旋转。
如果不在世界原点建立模型,还想以自身为旋转轴旋转。
则是需要以下步骤:
模型的中心点为V1(100,100,0)假设中心为轴(平行于Y轴),旋转A度,也就是说自身中心点的Y轴旋转。
步骤:
(1)v1平移到世界原点后其他八个顶点的坐标。(中心点坐标的三个参数如果是大于0就是(每个)顶点减去相对应XYZ,如果中心点坐标的三个参数如果是小于0,则是(每个)顶点加上相对应XYZ,或者使用平移矩阵)
(2)(每个)顶点先是平移到V1在原点时的所在的位置,再使用旋转矩阵经行旋转
(3) (每个)旋转后的顶点在平移回中心点原先所在位置。
ATP 附加属性类
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Data;
- using System.Windows.Media;
- using System.Windows.Media.Media3D;
- using System.Windows.Shapes;
- namespace ATP
- {
- public class ATP_Y
- {
- public static readonly DependencyProperty P_YProperty = DependencyProperty.RegisterAttached("P_Y", typeof(double), typeof(ATP.ATP_Y), new PropertyMetadata(0.0, new PropertyChangedCallback(OnP_YChanged)));
- private static void OnP_YChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- PY = (double)e.NewValue;
- Draw(d, X, Y, Z);
- }
- public static void SetP_Y(DependencyObject d, double v) => d.SetValue(P_YProperty, v);
- public static double GetP_Y(DependencyObject d) => (double)d.GetValue(P_YProperty);
- public static readonly DependencyProperty P_XProperty = DependencyProperty.RegisterAttached("P_X", typeof(double), typeof(ATP.ATP_Y), new PropertyMetadata(0.0, new PropertyChangedCallback(OnP_XChanged)));
- private static void OnP_XChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- PX= (double)e.NewValue;
- Draw(d, X, Y, Z);
- }
- public static void SetP_X(DependencyObject d, double v) => d.SetValue(P_XProperty, v);
- public static double GetP_X(DependencyObject d) => (double)d.GetValue(P_XProperty);
- public static readonly DependencyProperty P_ZProperty = DependencyProperty.RegisterAttached("P_Z", typeof(double), typeof(ATP.ATP_Y), new PropertyMetadata(0.0, new PropertyChangedCallback(OnP_ZChanged)));
- private static void OnP_ZChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- PZ = (double)e.NewValue;
- Draw(d, X, Y, Z);
- }
- public static void SetP_Z(DependencyObject d, double v) => d.SetValue(P_ZProperty, v);
- public static double GetP_Z(DependencyObject d) => (double)d.GetValue(P_ZProperty);
- public static readonly DependencyProperty ModeDataProperty = DependencyProperty.RegisterAttached("ModeData", typeof(Point3D), typeof(ATP_Y), new PropertyMetadata(new Point3D(, , ), new PropertyChangedCallback(OnModeDataChanged)));
- public static void SetModeData(DependencyObject d, Point3D v) => d.SetValue(ModeDataProperty, v);
- public static Point3D GetModeData(DependencyObject d) => (Point3D)d.GetValue(ModeDataProperty);
- private static void OnModeDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var data = (Point3D)e.NewValue;
- ModeWidth = data.X;
- ModeHeight = data.Y;
- ModeZWidth = data.Z;
- Draw(d,X,Y,Z);
- }
- public static readonly DependencyProperty YProperty = DependencyProperty.RegisterAttached("Y", typeof(double), typeof(ATP.ATP_Y), new PropertyMetadata(-1.0, new PropertyChangedCallback(OnYChanged)));
- public static void SetY(DependencyObject d, double v) => d.SetValue(YProperty, v);
- public static double GetY(DependencyObject d) => (double)d.GetValue(YProperty);
- public static readonly DependencyProperty XProperty = DependencyProperty.RegisterAttached("X", typeof(double), typeof(ATP.ATP_Y), new PropertyMetadata(-1.0, new PropertyChangedCallback(OnXChanged)));
- private static void OnXChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var deg = Math.PI / * (double)e.NewValue;
- X = deg;
- Draw(d, deg, Y, Z);
- }
- public static void SetX(DependencyObject d, double v) => d.SetValue(XProperty, v);
- public static double GetX(DependencyObject d) => (double)d.GetValue(XProperty);
- public static readonly DependencyProperty ZProperty = DependencyProperty.RegisterAttached("Z", typeof(double), typeof(ATP.ATP_Y), new PropertyMetadata(-1.0, new PropertyChangedCallback(OnZChanged)));
- private static void OnZChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var deg = Math.PI / * (double)e.NewValue;
- Z = deg;
- Draw(d, X, Y, deg);
- }
- public static void SetZ(DependencyObject d, double v) => d.SetValue(ZProperty, v);
- public static double GetZ(DependencyObject d) => (double)d.GetValue(ZProperty);
- private static void OnYChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var deg = Math.PI / * (double)e.NewValue;
- Y = deg;
- Draw(d, X, deg, Z);
- }
- private static double PX, PY, PZ;
- private static double X, Y, Z;
- private static double ModeHeight, ModeWidth, ModeZWidth;
- private static void Draw(DependencyObject d, double X, double Y, double Z)
- {
- var ui = d as Grid;
- ui.Children.Clear();
- var rect = new Rect(new Size(ModeWidth,ModeHeight));
- Group[] = new Point3D(rect.Width / , rect.Height / , -(ModeZWidth/));
- Group[] = new Point3D( - (rect.Width / ), rect.Height / , -(ModeZWidth / ));
- Group[] = new Point3D( - (rect.Width / ), - (rect.Height / ), -(ModeZWidth / ));
- Group[] = new Point3D((rect.Width / ), - (rect.Height / ), -(ModeZWidth / ));
- Group[] = new Point3D(rect.Width / , rect.Height / , (ModeZWidth / ));
- Group[] = new Point3D( - (rect.Width / ), rect.Height / , (ModeZWidth / ));
- Group[] = new Point3D( - (rect.Width / ), - (rect.Height / ), (ModeZWidth / ));
- Group[] = new Point3D((rect.Width / ), - (rect.Height / ), (ModeZWidth / ));
- for (var i = ; i < ; i++)
- PP[i] = PSP(ReturnP3D(Y轴转置矩阵(X, Y, Z) * GetMatrixMP(Group[i])), new Rect(new Size(Math.Max(rect.Height, rect.Width),ModeZWidth)));
- Set(, , ui,Colors.Black);
- Set(, , ui,Colors.Blue);
- Set(, , ui, Colors.Red);
- Set(, , ui, Colors.Fuchsia);
- Set(, , ui, Colors.DarkSlateBlue);
- Set(, , ui, Colors.Red);
- Set(, , ui, Colors.Red);
- Set(, , ui, Colors.Red);
- Set(, , ui, Colors.Red);
- Set(, , ui, Colors.Red);
- Set(, , ui, Colors.Red);
- Set(, , ui, Colors.Red);
- }
- private static void Set(int g1, int g2, Grid g,Color A)
- {
- var c1 = new Line();
- c1.Stroke = new SolidColorBrush(A);
- c1.X1 = PP[g1].X;
- c1.Y1 = PP[g1].Y;
- c1.X2 = PP[g2].X;
- c1.Y2 = PP[g2].Y;
- g.Children.Add(c1);
- }
- private static Matrix GetMatrixMP(Point3D MP)
- {
- var D = new double[, ];
- D[, ] = MP.X;
- D[, ] = MP.Y;
- D[, ] = MP.Z;
- D[, ] = ;
- return new Matrix(D);
- }
- private static Point3D ReturnP3D(Matrix MP) => new Point3D(MP[, ], MP[, ], MP[, ]);
- private static Point PSP(Point3D ModePoint, Rect rect)
- {
- Point3D vp = new Point3D(PX, PY, Math.Max(rect.Height, rect.Width)+PZ);
- Point p;
- int x, y;
- x = (int)(vp.X + (ModePoint.X - vp.X) * vp.Z / (vp.Z - ModePoint.Z + 0.5));
- y = (int)(vp.Y + (ModePoint.Y - vp.Y) * vp.Z / (vp.Z - ModePoint.Z + 0.5));
- p = new Point(x, y);
- return p;
- }
- private static Point3D[] Group = new Point3D[];
- private static Point[] PP = new Point[];
- private static Matrix Y轴转置矩阵(double DegX, double DegY, double DegZ)
- {
- var A = new double[, ];
- A[, ] = ;
- A[, ] = ;
- A[, ] = ;
- A[, ] = ;
- A[, ] = Math.Cos(X);
- A[, ] = Math.Sin(X);
- A[, ] = ;
- A[, ] = - Math.Sin(X);
- A[, ] = Math.Cos(X);
- A[, ] = ;
- A[, ] = ;
- A[, ] = ;
- A[, ] = ;
- A[, ] = ;
- A[, ] = ;
- A[, ] = ;
- var B = new double[, ];
- B[, ] = Math.Cos(Y);
- B[, ] = ;
- B[, ] = -Math.Sin(Y);
- B[, ] = ;
- B[, ] = ;
- B[, ] = ;
- B[, ] = Math.Sin(Y);
- B[, ] = ;
- B[, ] = Math.Cos(Y);
- B[, ] = ;
- B[, ] = ;
- B[, ] = ;
- B[, ] = ;
- B[, ] = ;
- B[, ] = ;
- B[, ] = ;
- var C = new double[, ];
- C[, ] = Math.Cos(Z);
- C[, ] = Math.Sin(Z);
- C[, ] = ;
- C[, ] = - Math.Sin(Z);
- C[, ] = Math.Cos(Z);
- C[, ] = ;
- C[, ] = ;
- C[, ] = ;
- C[, ] = ;
- C[, ] = ;
- C[, ] = ;
- C[, ] = ;
- B[, ] = ;
- B[, ] = ;
- B[, ] = ;
- C[, ] = ;
- Matrix MT1 = new Matrix(A);
- Matrix MT2 = new Matrix(B);
- Matrix MT3 = new Matrix(C);
- var MT4 = MT1 * MT2;
- return MT4 * MT3;
- }
- }
- }
xaml代码
//其中ModeData的三个参数为矩形的长高宽
//X,Y,Z为轴的旋转角度
- <Window x:Class="ATP.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:local="clr-namespace:ATP"
- mc:Ignorable="d"
- Title="MainWindow" Height="" Width="">
- <Grid> <Grid.RowDefinitions>
- <RowDefinition Height="*"/>
- <RowDefinition Height="auto"/>
- </Grid.RowDefinitions>
- <Grid x:Name="G" local:ATP_Y.P_Z="{Binding ElementName=s4,Path=Value}" local:ATP_Y.ModeData="100,100,100" HorizontalAlignment="Center" VerticalAlignment="Center" local:ATP_Y.Y="{Binding ElementName=s2,Path=Value}" local:ATP_Y.X="{Binding ElementName=s1,Path=Value}" local:ATP_Y.Z="{Binding ElementName=s3,Path=Value}"/>
- <StackPanel Grid.Row="">
- <!--X轴旋转-->
- <Slider Minimum="" Maximum="" x:Name="s1"/>
- <!--Y轴旋转-->
- <Slider Minimum="" Maximum="" x:Name="s2"/>
- <!--Z轴旋转-->
- <Slider Minimum="" Maximum="" x:Name="s3"/>
- <!--视野远近-->
- <Slider Minimum="" Maximum="" x:Name="s4" />
- </StackPanel>
- </Grid>
- </Window>
矩阵类
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace ATP
- {
- [Serializable]
- public class Matrix
- {
- public double[] element;
- private int rows = ;
- private int cols = ;
- /// <summary>
- /// 获取矩阵行数
- /// </summary>
- public int Rows
- {
- get
- {
- return rows;
- }
- }
- /// <summary>
- /// 获取矩阵列数
- /// </summary>
- public int Cols
- {
- get
- {
- return cols;
- }
- }
- /// <summary>
- /// 获取或设置第i行第j列的元素值
- /// </summary>
- /// <param name="i">第i行</param>
- /// <param name="j">第j列</param>
- /// <returns>返回第i行第j列的元素值</returns>
- public double this[int i, int j]
- {
- get
- {
- if (i < Rows && j < Cols)
- {
- return element[i * cols + j];
- }
- else
- {
- throw new Exception("索引越界");
- }
- }
- set
- {
- element[i * cols + j] = value;
- }
- }
- /// <summary>
- /// 用二维数组初始化Matrix
- /// </summary>
- /// <param name="m">二维数组</param>
- public Matrix(double[][] m)
- {
- this.rows = m.GetLength();
- this.cols = m.GetLength();
- int count = ;
- this.element = new double[Rows * Cols];
- for (int i = ; i < rows; i++)
- {
- for (int j = ; j < cols; j++)
- {
- element[count++] = m[i][j];
- }
- }
- }
- public Matrix(double[,] m)
- {
- this.rows = m.GetLength();
- this.cols = m.GetLength();
- this.element = new double[this.rows * this.cols];
- int count = ;
- for (int i = ; i < rows; i++)
- {
- for (int j = ; j < cols; j++)
- {
- element[count++] = m[i, j];
- }
- }
- }
- public Matrix(List<List<double>> m)
- {
- this.rows = m.Count;
- this.cols = m[].Count;
- this.element = new double[Rows * Cols];
- for (int i = ; i < rows; i++)
- {
- for (int j = ; j < cols; j++)
- {
- this[i, j] = m[i][j];
- }
- }
- }
- #region 矩阵数学运算
- public static Matrix MAbs(Matrix a)
- {
- Matrix _thisCopy = a.DeepCopy();
- for (int i = ; i < a.Rows; i++)
- {
- for (int j = ; j < a.Cols; j++)
- {
- _thisCopy[i, j] = Math.Abs(a[i, j]);
- }
- }
- return _thisCopy;
- }
- /// <summary>
- /// 矩阵相加
- /// </summary>
- /// <param name="a">第一个矩阵,和b矩阵必须同等大小</param>
- /// <param name="b">第二个矩阵</param>
- /// <returns>返回矩阵相加后的结果</returns>
- public static Matrix operator +(Matrix a, Matrix b)
- {
- if (a.cols == b.cols && a.rows == b.rows)
- {
- double[,] res = new double[a.rows, a.cols];
- for (int i = ; i < a.Rows; i++)
- {
- for (int j = ; j < a.Cols; j++)
- {
- res[i, j] = a[i, j] + b[i, j];
- }
- }
- return new Matrix(res);
- }
- else
- {
- throw new Exception("两个矩阵行列不相等");
- }
- }
- /// <summary>
- /// 矩阵相减
- /// </summary>
- /// <param name="a">第一个矩阵,和b矩阵必须同等大小</param>
- /// <param name="b">第二个矩阵</param>
- /// <returns>返回矩阵相减后的结果</returns>
- public static Matrix operator -(Matrix a, Matrix b)
- {
- if (a.cols == b.cols && a.rows == b.rows)
- {
- double[,] res = new double[a.rows, a.cols];
- for (int i = ; i < a.Rows; i++)
- {
- for (int j = ; j < a.Cols; j++)
- {
- res[i, j] = a[i, j] - b[i, j];
- }
- }
- return new Matrix(res);
- }
- else
- {
- throw new Exception("两个矩阵行列不相等");
- }
- }
- /// <summary>
- /// 对矩阵每个元素取相反数
- /// </summary>
- /// <param name="a">二维矩阵</param>
- /// <returns>得到矩阵的相反数</returns>
- public static Matrix operator -(Matrix a)
- {
- Matrix res = a;
- for (int i = ; i < a.rows; i++)
- {
- for (int j = ; j < a.cols; j++)
- {
- res.element[i * a.cols + j] = -res.element[i * a.cols + j];
- }
- }
- return res;
- }
- /// <summary>
- /// 矩阵相乘
- /// </summary>
- /// <param name="a">第一个矩阵</param>
- /// <param name="b">第二个矩阵,这个矩阵的行要与第一个矩阵的列相等</param>
- /// <returns>返回相乘后的一个新的矩阵</returns>
- public static Matrix operator *(Matrix a, Matrix b)
- {
- if (a.cols == b.rows)
- {
- double[,] res = new double[a.rows, b.cols];
- for (int i = ; i < a.rows; i++)
- {
- for (int j = ; j < b.cols; j++)
- {
- for (int k = ; k < a.cols; k++)
- {
- res[i, j] += a[i, k] * b[k, j];
- }
- }
- }
- return new Matrix(res);
- }
- else
- {
- throw new Exception("两个矩阵行和列不等");
- }
- }
- /// <summary>
- /// 矩阵与数相乘
- /// </summary>
- /// <param name="a">第一个矩阵</param>
- /// <param name="num">一个实数</param>
- /// <returns>返回相乘后的新的矩阵</returns>
- public static Matrix operator *(Matrix a, double num)
- {
- Matrix res = a;
- for (int i = ; i < a.rows; i++)
- {
- for (int j = ; j < a.cols; j++)
- {
- res.element[i * a.cols + j] *= num;
- }
- }
- return res;
- }
- /// <summary>
- /// 矩阵转置
- /// </summary>
- /// <returns>返回当前矩阵转置后的新矩阵</returns>
- public Matrix Transpose()
- {
- double[,] res = new double[cols, rows];
- {
- for (int i = ; i < cols; i++)
- {
- for (int j = ; j < rows; j++)
- {
- res[i, j] = this[j, i];
- }
- }
- }
- return new Matrix(res);
- }
- /// <summary>
- /// 矩阵求逆
- /// </summary>
- /// <returns>返回求逆后的新的矩阵</returns>
- public Matrix Inverse()
- {
- //最后原始矩阵并不变,所以需要深拷贝一份
- Matrix _thisCopy = this.DeepCopy();
- if (cols == rows && this.Determinant() != )
- {
- //初始化一个同等大小的单位阵
- Matrix res = _thisCopy.EMatrix();
- for (int i = ; i < rows; i++)
- {
- //首先找到第i列的绝对值最大的数,并将该行和第i行互换
- int rowMax = i;
- double max = Math.Abs(_thisCopy[i, i]);
- for (int j = i; j < rows; j++)
- {
- if (Math.Abs(_thisCopy[j, i]) > max)
- {
- rowMax = j;
- max = Math.Abs(_thisCopy[j, i]);
- }
- }
- //将第i行和找到最大数那一行rowMax交换
- if (rowMax != i)
- {
- _thisCopy.Exchange(i, rowMax);
- res.Exchange(i, rowMax);
- }
- //将第i行做初等行变换,将第一个非0元素化为1
- double r = 1.0 / _thisCopy[i, i];
- _thisCopy.Exchange(i, -, r);
- res.Exchange(i, -, r);
- //消元
- for (int j = ; j < rows; j++)
- {
- //到本行后跳过
- if (j == i)
- continue;
- else
- {
- r = -_thisCopy[j, i];
- _thisCopy.Exchange(i, j, r);
- res.Exchange(i, j, r);
- }
- }
- }
- return res;
- }
- else
- {
- throw new Exception("矩阵不是方阵无法求逆");
- }
- }
- #region 重载比较运算符
- public static bool operator <(Matrix a, Matrix b)
- {
- bool issmall = true;
- for (int i = ; i < a.Rows; i++)
- {
- for (int j = ; j < a.Cols; j++)
- {
- if (a[i, j] >= b[i, j]) issmall = false;
- }
- }
- return issmall;
- }
- public static bool operator >(Matrix a, Matrix b)
- {
- bool issmall = true;
- for (int i = ; i < a.Rows; i++)
- {
- for (int j = ; j < a.Cols; j++)
- {
- if (a[i, j] <= b[i, j]) issmall = false;
- }
- }
- return issmall;
- }
- public static bool operator <=(Matrix a, Matrix b)
- {
- bool issmall = true;
- for (int i = ; i < a.Rows; i++)
- {
- for (int j = ; j < a.Cols; j++)
- {
- if (a[i, j] > b[i, j]) issmall = false;
- }
- }
- return issmall;
- }
- public static bool operator >=(Matrix a, Matrix b)
- {
- bool issmall = true;
- for (int i = ; i < a.Rows; i++)
- {
- for (int j = ; j < a.Cols; j++)
- {
- if (a[i, j] < b[i, j]) issmall = false;
- }
- }
- return issmall;
- }
- public static bool operator !=(Matrix a, Matrix b)
- {
- bool issmall = true;
- issmall = ReferenceEquals(a, b);
- if (issmall) return issmall;
- for (int i = ; i < a.Rows; i++)
- {
- for (int j = ; j < a.Cols; j++)
- {
- if (a[i, j] == b[i, j]) issmall = false;
- }
- }
- return issmall;
- }
- public static bool operator ==(Matrix a, Matrix b)
- {
- bool issmall = true;
- issmall = ReferenceEquals(a, b);
- if (issmall) return issmall;
- for (int i = ; i < a.Rows; i++)
- {
- for (int j = ; j < a.Cols; j++)
- {
- if (a[i, j] != b[i, j]) issmall = false;
- }
- }
- return issmall;
- }
- public override bool Equals(object obj)
- {
- Matrix b = obj as Matrix;
- return this == b;
- }
- public override int GetHashCode()
- {
- return base.GetHashCode();
- }
- #endregion
- public double Determinant()
- {
- if (cols == rows)
- {
- Matrix _thisCopy = this.DeepCopy();
- //行列式每次交换行,都需要乘以-1
- double res = ;
- for (int i = ; i < rows; i++)
- {
- //首先找到第i列的绝对值最大的数
- int rowMax = i;
- double max = Math.Abs(_thisCopy[i, i]);
- for (int j = i; j < rows; j++)
- {
- if (Math.Abs(_thisCopy[j, i]) > max)
- {
- rowMax = j;
- max = Math.Abs(_thisCopy[j, i]);
- }
- }
- //将第i行和找到最大数那一行rowMax交换,同时将单位阵做相同初等变换
- if (rowMax != i)
- {
- _thisCopy.Exchange(i, rowMax);
- res *= -;
- }
- //消元
- for (int j = i + ; j < rows; j++)
- {
- double r = -_thisCopy[j, i] / _thisCopy[i, i];
- _thisCopy.Exchange(i, j, r);
- }
- }
- //计算对角线乘积
- for (int i = ; i < rows; i++)
- {
- res *= _thisCopy[i, i];
- }
- return res;
- }
- else
- {
- throw new Exception("不是行列式");
- }
- }
- #endregion
- #region 初等变换
- /// <summary>
- /// 初等变换:交换第r1和第r2行
- /// </summary>
- /// <param name="r1">第r1行</param>
- /// <param name="r2">第r2行</param>
- /// <returns>返回交换两行后的新的矩阵</returns>
- public Matrix Exchange(int r1, int r2)
- {
- if (Math.Min(r2, r1) >= && Math.Max(r1, r2) < rows)
- {
- for (int j = ; j < cols; j++)
- {
- double temp = this[r1, j];
- this[r1, j] = this[r2, j];
- this[r2, j] = temp;
- }
- return this;
- }
- else
- {
- throw new Exception("超出索引");
- }
- }
- /// <summary>
- /// 初等变换:将r1行乘以某个数加到r2行
- /// </summary>
- /// <param name="r1">第r1行乘以num</param>
- /// <param name="r2">加到第r2行,若第r2行为负,则直接将r1乘以num并返回</param>
- /// <param name="num">某行放大的倍数</param>
- /// <returns></returns>
- public Matrix Exchange(int r1, int r2, double num)
- {
- if (Math.Min(r2, r1) >= && Math.Max(r1, r2) < rows)
- {
- for (int j = ; j < cols; j++)
- {
- this[r2, j] += this[r1, j] * num;
- }
- return this;
- }
- else if (r2 < )
- {
- for (int j = ; j < cols; j++)
- {
- this[r1, j] *= num;
- }
- return this;
- }
- else
- {
- throw new Exception("超出索引");
- }
- }
- /// <summary>
- /// 得到一个同等大小的单位矩阵
- /// </summary>
- /// <returns>返回一个同等大小的单位矩阵</returns>
- public Matrix EMatrix()
- {
- if (rows == cols)
- {
- double[,] res = new double[rows, cols];
- for (int i = ; i < rows; i++)
- {
- for (int j = ; j < cols; j++)
- {
- if (i == j)
- res[i, j] = ;
- else
- res[i, j] = ;
- }
- }
- return new Matrix(res);
- }
- else
- throw new Exception("不是方阵,无法得到单位矩阵");
- }
- #endregion
- /// <summary>
- /// 深拷贝,仅仅将值拷贝给一个新的对象
- /// </summary>
- /// <returns>返回深拷贝后的新对象</returns>
- public Matrix DeepCopy()
- {
- double[,] ele = new double[rows, cols];
- for (int i = ; i < rows; i++)
- {
- for (int j = ; j < cols; j++)
- {
- ele[i, j] = this[i, j];
- }
- }
- return new Matrix(ele);
- }
- public override string ToString()
- {
- string str = "";
- for (int i = ; i < Rows; i++)
- {
- for (int j = ; j < Cols; j++)
- {
- str += this[i, j].ToString();
- if (j != Cols - )
- str += " ";
- else if (i != Rows - )
- str += Environment.NewLine;
- }
- }
- return str;
- }
- }
- }
截图
WPF 画一个3D矩形并旋转的更多相关文章
- vb代码之------画一个半透明矩形
入吾QQ群183435019 (学习 交流+唠嗑). 废话不说,咱们来看代码吧 程序结果运行如下 需要如下API 1:GdipCreateFromHDC 功能:创建设备场景相对应的绘图区域(相当于给设 ...
- Qt 怎么画一个圆角矩形对话框,或者圆角控件
1. 2. 在自定义控件的 构造函数中加入如下一段断码 this->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint); //隐藏对话框标题 ...
- Directx11学习笔记【十二】 画一个旋转的彩色立方体
上一次我们学习了如何画一个2D三角形,现在让我们进一步学习如何画一个旋转的彩色立方体吧. 具体流程同画三角形类似,因此不再给出完整代码了,不同的部分会再说明. 由于我们要画彩色的立方体,所以顶点结构体 ...
- CSS3D动画制作一个3d旋转的筛子
希望这个demo能让大家理解CSS3的3d空间动画(其实是个假3D) 首先给一个3d的解剖图,x/y/z轴线轴线已经标出 下面附上添加特效的动画旋转 可以根据demo并参考上面解剖图进行理解 < ...
- 使用纯CSS3实现一个3D旋转的书本
有一些前沿的电商站点已经開始使用3D模型来展示商品并支持在线定制,而当中图书的展示是最为简单的一种, 无需复杂的建模过程,使用图片和CSS3的一些变换就可以实现更好的展示效果,简洁而有用. 书本的3D ...
- WPF中的3D特性和常见的几个类
原文:WPF中的3D特性和常见的几个类 WPF 3D 常用的几个类及其关系 1. Visual 类 所有二维可视化元素的基类,为 WPF 中的呈现提供支持,其中包括命中测试.坐标转换和边界 ...
- 在WPF中添加3D特性
原文:在WPF中添加3D特性 35.4 在WPF中添加3D特性 本节介绍WPF中的3D特性,其中包含了开始使用该特性的信息. 提示: WPF中的3D特性在System.Windows.Media.M ...
- 一个3D ar打飞机的游戏iOS源码
这是国内目前第一款集合了AR实景,3D游戏和人脸识别的射击游戏,通过旋转和改变手机的角度与位置,所有的射击操作都靠手势来完成,目前所有的源码全部都在这里.appStore地址:https://itun ...
- wpf做的3d滑动gallery
原文:wpf做的3d滑动gallery wpf做的3d滑动gallery 随着iphone\ipad的流行及热捧,现在做移动产品不管是什么平台的,领导总想做成像ios系统的样子.自从微软发布了wind ...
随机推荐
- Typescript I: 遍历Array的方法:for, forEach, every等
Typescript的官方文档 Iterators and Geneators (https://www.typescriptlang.org/docs/handbook/iterators-and- ...
- 启动Spring Tool Suite 4时出现 could not find tools.jar spring boot live hovers....弹窗
第一步:检查一下STS启动时的加载环境 Help —› About Spring Tool Suite 4 —› Installation Details —› Configuration 本人已经 ...
- Jquery 处理返回的 Json 数组
Jquery 处理返回的 Json 数组 <script> for (var i = 0; i < photos.length; ++ i) { console.log(photos ...
- WordPress 去掉功能中的 wordpress.org
WordPress 去掉功能中的 wordpress.org
- nyoj 163 Phone List(动态字典树<trie>) poj Phone List (静态字典树<trie>)
Phone List 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 Given a list of phone numbers, determine if it i ...
- 如何在当前文件夹打开cmd(基于win10)
如何在当前文件夹打开cmd(基于win10) 方法一: 1.先打开你要进入的文件夹 2.在标记的位置输入cmd,就可以进入当前文件的cmd 方法二: 1.打开你要进入的文件夹 2.通过shift + ...
- DAL
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Data;u ...
- 领扣(LeetCode)字母大小写全排列 个人题解
给定一个字符串S,通过将字符串S中的每个字母转变大小写,我们可以获得一个新的字符串.返回所有可能得到的字符串集合. 示例: 输入: S = "a1b2" 输出: ["a1 ...
- 自制反汇编逆向分析工具 与hopper逆向输出对比
经过一个阶段5次迭代之后,本逆向分析工具功能基本成形.工具的基本功能介绍请参看前面的posts. 现在就和hopper的逆向函数伪代码的功能对比一下效果.在这里并非定胜劣,因为差异可以拿来对比参照,通 ...
- RxJS入门
一.RxJS是什么? 官方文档使用了一句话总结RxJS: Think of RxJS as Lodash for events.那么Lodash主要解决了什么问题?Lodash主要集成了一系列关于数组 ...