zoukankan      html  css  js  c++  java
  • 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(10, 10, 10), 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 / 180 * (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 / 180 * (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 / 180 * (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[0] = new Point3D(rect.Width / 2, rect.Height / 2, -(ModeZWidth/2));
                Group[1] = new Point3D(0 - (rect.Width / 2), rect.Height / 2, -(ModeZWidth / 2));
                Group[2] = new Point3D(0 - (rect.Width / 2), 0 - (rect.Height / 2), -(ModeZWidth / 2));
                Group[3] = new Point3D((rect.Width / 2), 0 - (rect.Height / 2), -(ModeZWidth / 2));
                Group[4] = new Point3D(rect.Width / 2, rect.Height / 2, (ModeZWidth / 2));
                Group[5] = new Point3D(0 - (rect.Width / 2), rect.Height / 2, (ModeZWidth / 2));
                Group[6] = new Point3D(0 - (rect.Width / 2), 0 - (rect.Height / 2), (ModeZWidth / 2));
                Group[7] = new Point3D((rect.Width / 2), 0 - (rect.Height / 2), (ModeZWidth / 2));
    
                for (var i = 0; i < 8; i++)
                    PP[i] = PSP(ReturnP3D(Y轴转置矩阵(X, Y, Z) * GetMatrixMP(Group[i])), new Rect(new Size(Math.Max(rect.Height, rect.Width),ModeZWidth)));
    
    
                Set(0, 1, ui,Colors.Black);
                Set(1, 2, ui,Colors.Blue);
                Set(2, 3, ui, Colors.Red);
                Set(3, 0, ui, Colors.Fuchsia);
                Set(4, 5, ui, Colors.DarkSlateBlue);
                Set(5, 6, ui, Colors.Red);
                Set(6, 7, ui, Colors.Red);
                Set(7, 4, ui, Colors.Red);
                Set(0, 4, ui, Colors.Red);
                Set(1, 5, ui, Colors.Red);
                Set(2, 6, ui, Colors.Red);
                Set(3, 7, 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[4, 1];
                D[0, 0] = MP.X;
                D[1, 0] = MP.Y;
                D[2, 0] = MP.Z;
                D[3, 0] = 1;
                return new Matrix(D);
            }
            private static Point3D ReturnP3D(Matrix MP) => new Point3D(MP[0, 0], MP[1, 0], MP[2, 0]);
    
            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[8];
            private static Point[] PP = new Point[8];
            private static Matrix Y轴转置矩阵(double DegX, double DegY, double DegZ)
            {
                var A = new double[4, 4];
                A[0, 0] = 1;
                A[0, 1] = 0;
                A[0, 2] = 0;
                A[1, 0] = 0;
                A[1, 1] = Math.Cos(X);
                A[1, 2] = Math.Sin(X);
                A[2, 0] = 0;
                A[2, 1] = 0 - Math.Sin(X);
                A[2, 2] = Math.Cos(X);
                A[0, 3] = 0;
                A[1, 3] = 0;
                A[2, 3] = 0;
                A[3, 0] = 1;
                A[3, 1] = 1;
                A[3, 2] = 1;
                A[3, 3] = 1;
                var B = new double[4, 4];
                B[0, 0] = Math.Cos(Y);
                B[0, 1] = 0;
                B[0, 2] = -Math.Sin(Y);
                B[1, 0] = 0;
                B[1, 1] = 1;
                B[1, 2] = 0;
                B[2, 0] = Math.Sin(Y);
                B[2, 1] = 0;
                B[2, 2] = Math.Cos(Y);
                B[0, 3] = 1;
                B[1, 3] = 1;
                B[2, 3] = 1;
                B[3, 0] = 1;
                B[3, 1] = 1;
                B[3, 2] = 1;
                B[3, 3] = 1;
                var C = new double[4, 4];
                C[0, 0] = Math.Cos(Z);
                C[0, 1] = Math.Sin(Z);
                C[0, 2] = 0;
                C[1, 0] = 0 - Math.Sin(Z);
                C[1, 1] = Math.Cos(Z);
                C[1, 2] = 0;
                C[2, 0] = 0;
                C[2, 1] = 0;
                C[2, 2] = 1;
                C[0, 3] = 1;
                C[1, 3] = 1;
                C[2, 3] = 1;
                B[3, 0] = 1;
                B[3, 1] = 1;
                B[3, 2] = 1;
                C[3, 3] = 1;
                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="450" Width="800">
        <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="1">
                <!--X轴旋转-->
                <Slider Minimum="0"  Maximum="360" x:Name="s1"/>
                <!--Y轴旋转-->
                <Slider Minimum="0"  Maximum="360" x:Name="s2"/>
                <!--Z轴旋转-->
                <Slider Minimum="0"  Maximum="360" x:Name="s3"/>
                <!--视野远近-->
                <Slider Minimum="0"  Maximum="360" 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 = 0;
                private int cols = 0;
                /// <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(0);
                    this.cols = m.GetLength(1);
                    int count = 0;
                    this.element = new double[Rows * Cols];
                    for (int i = 0; i < rows; i++)
                    {
                        for (int j = 0; j < cols; j++)
                        {
                            element[count++] = m[i][j];
                        }
                    }
                }
                public Matrix(double[,] m)
                {
                    this.rows = m.GetLength(0);
                    this.cols = m.GetLength(1);
                    this.element = new double[this.rows * this.cols];
                    int count = 0;
                    for (int i = 0; i < rows; i++)
                    {
                        for (int j = 0; j < cols; j++)
                        {
                            element[count++] = m[i, j];
                        }
                    }
                }
                public Matrix(List<List<double>> m)
                {
                    this.rows = m.Count;
                    this.cols = m[0].Count;
                    this.element = new double[Rows * Cols];
                    for (int i = 0; i < rows; i++)
                    {
                        for (int j = 0; j < cols; j++)
                        {
                            this[i, j] = m[i][j];
                        }
                    }
                }
                #region 矩阵数学运算
                public static Matrix MAbs(Matrix a)
                {
                    Matrix _thisCopy = a.DeepCopy();
                    for (int i = 0; i < a.Rows; i++)
                    {
                        for (int j = 0; 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 = 0; i < a.Rows; i++)
                        {
                            for (int j = 0; 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 = 0; i < a.Rows; i++)
                        {
                            for (int j = 0; 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 = 0; i < a.rows; i++)
                    {
                        for (int j = 0; 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 = 0; i < a.rows; i++)
                        {
                            for (int j = 0; j < b.cols; j++)
                            {
                                for (int k = 0; 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 = 0; i < a.rows; i++)
                    {
                        for (int j = 0; 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 = 0; i < cols; i++)
                        {
                            for (int j = 0; 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() != 0)
                    {
                        //初始化一个同等大小的单位阵
                        Matrix res = _thisCopy.EMatrix();
                        for (int i = 0; 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, -1, r);
                            res.Exchange(i, -1, r);
                            //消元
                            for (int j = 0; 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 = 0; i < a.Rows; i++)
                    {
                        for (int j = 0; 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 = 0; i < a.Rows; i++)
                    {
                        for (int j = 0; 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 = 0; i < a.Rows; i++)
                    {
                        for (int j = 0; 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 = 0; i < a.Rows; i++)
                    {
                        for (int j = 0; 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 = 0; i < a.Rows; i++)
                    {
                        for (int j = 0; 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 = 0; i < a.Rows; i++)
                    {
                        for (int j = 0; 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 = 1;
                        for (int i = 0; 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 *= -1;
                            }
                            //消元
                            for (int j = i + 1; j < rows; j++)
                            {
                                double r = -_thisCopy[j, i] / _thisCopy[i, i];
                                _thisCopy.Exchange(i, j, r);
                            }
                        }
                        //计算对角线乘积
                        for (int i = 0; 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) >= 0 && Math.Max(r1, r2) < rows)
                    {
                        for (int j = 0; 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) >= 0 && Math.Max(r1, r2) < rows)
                    {
                        for (int j = 0; j < cols; j++)
                        {
                            this[r2, j] += this[r1, j] * num;
                        }
                        return this;
                    }
                    else if (r2 < 0)
                    {
                        for (int j = 0; 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 = 0; i < rows; i++)
                        {
                            for (int j = 0; j < cols; j++)
                            {
                                if (i == j)
                                    res[i, j] = 1;
                                else
                                    res[i, j] = 0;
                            }
                        }
                        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 = 0; i < rows; i++)
                    {
                        for (int j = 0; j < cols; j++)
                        {
                            ele[i, j] = this[i, j];
                        }
                    }
                    return new Matrix(ele);
                }
    
                public override string ToString()
                {
                    string str = "";
                    for (int i = 0; i < Rows; i++)
                    {
                        for (int j = 0; j < Cols; j++)
                        {
                            str += this[i, j].ToString();
                            if (j != Cols - 1)
                                str += " ";
                            else if (i != Rows - 1)
                                str += Environment.NewLine;
                        }
                    }
                    return str;
                }
            }
    }

    截图

  • 相关阅读:
    让程序用自定义的菜单自定义菜单AVKON_VIEW,CBA,MENU_BAR,MENU_PANE
    symbian 菜单不显示的原因
    子类中调用父类的带参数的构造函数|子类构造函数调用父类构造函数 的说明
    symbian 设置 透明背景
    IOS App资源路径
    Nonblock I/O 及其使用
    CEikStatusPane MakeVisible kernexec 3错误
    把mapinfo图层的经纬度信息导出来的办法
    解决安装macports,不能更新的问题
    jpg结构解析
  • 原文地址:https://www.cnblogs.com/T-ARF/p/12045857.html
Copyright © 2011-2022 走看看