具體的代碼還是線性代數。
主要是旋轉和平移。
這個例子的中模型是在世界原點建立。是以旋轉會以自身軸心旋轉。
如果不在世界原點建立模型,還想以自身為旋轉軸旋轉。
則是需要以下步驟:
模型的中心點為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;
}
}
}
截圖
