HalkaR, угу, так и у меня 
Цитата(marcusmae @ 30.5.2007, 12:26 ) | это действительно выглядит странновато. Сколько я видел и сам писал линейной алгебры, всюду матрица - это составной объект, использующий вектора, а не наоборот, . Обычно, они даже не связаны наследованием (если только матрица не хранится, как вектор), так что "скрывать" придётся очень многое. Впрочем, Вам виднее. |
Я дулул так как нас учил препод по алгебре - вектора - это всего лишь подвид матриц
Цитата(marcusmae @ 30.5.2007, 12:26 ) | Абстрагируемся от этого примера smile Конечно, наследующийся класс сигнатуру изменить не может. Некоторую гибкость способен предоставить базовый класс. Может, Вам подойдёт модификатор internal? = Работает он так : если проставить internal какому-нибудь члену класса, то он будет виден только классам внутри данной сборки, а из других сборок будет, как private. Таким образом, проектирование будет заключаться в объединении базовых классов в отдельную сборку с internal где надо, а наследники - в отдельной сборке. Подробнее... |
Пожалуй я не буду с этим возится 
Код | public class MyMatrix : ICloneable { private float[,] array;
public MyMatrix(float[,] matrix) { array = matrix; }
public MyMatrix(int m, int n) { array = new float[m, n]; }
public float this[int i, int j] { set { array[i, j] = value; } get { return array[i, j]; } }
public int Rows { get { return array.GetLength(0); } }
public int Columns { get { return array.GetLength(1); } }
public override int GetHashCode() { int hash = 0; for (int i = 0; i < Rows; i++) for (int j = 0; j < Columns; j++) hash ^= this[i, j].GetHashCode(); return hash; }
public override bool Equals(object obj) { if (obj is MyMatrix) { MyMatrix v = (MyMatrix)obj; if (v.Rows == Rows && v.Columns == Columns) { bool equal = true; for(int i = 0; i < Rows; i++) for (int j = 0; j < Columns; j++) { if (v[i, j] != this[i, j]) equal = false; } return equal; } else { return false; } } return false; }
public static bool operator ==(MyMatrix u, MyMatrix v) { if (Object.Equals(u, null)) { return Object.Equals(v, null); }
if (Object.Equals(v, null)) { return Object.Equals(u, null); }
return u.Equals(v); }
public static bool operator !=(MyMatrix u, MyMatrix v) { if (Object.Equals(u, null)) { return !Object.Equals(v, null); }
if (Object.Equals(v, null)) { return !Object.Equals(u, null); }
return !u.Equals(v); }
public static MyMatrix operator -(MyMatrix v) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = v[i, j]; return new MyMatrix(array); }
public static MyMatrix operator +(MyMatrix u, MyMatrix v) { if (u.Rows == v.Rows && u.Columns == v.Columns) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = u[i, j] + v[i, j]; return new MyMatrix(array); } else { throw new Exception("Матрицы имеют не одинаковый размер!"); } }
public static MyMatrix operator +(MyMatrix v, float s) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = v[i, j] + s; return new MyMatrix(array); }
public static MyMatrix operator +(float s, MyMatrix v) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = v[i, j] + s; return new MyMatrix(array); }
public static MyMatrix operator -(MyMatrix u, MyMatrix v) { if (u.Rows == v.Rows && u.Columns == v.Columns) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = u[i, j] - v[i, j]; return new MyMatrix(array); } else { throw new Exception("Матрицы имеют не одинаковый размер!"); } }
public static MyMatrix operator -(MyMatrix v, float s) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = v[i, j] - s; return new MyMatrix(array); }
public static MyMatrix operator -(float s, MyMatrix v) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = s - v[i, j]; return new MyMatrix(array); }
public static MyMatrix operator *(MyMatrix v, float s) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = s * v[i, j]; return new MyMatrix(array); }
public static MyMatrix operator *(float s, MyMatrix v) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = s * v[i, j]; return new MyMatrix(array); }
public static MyMatrix operator /(MyMatrix v, float s) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = v[i, j] / s; return new MyMatrix(array); }
public static MyMatrix operator /(float s, MyMatrix v) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = s / v[i, j]; return new MyMatrix(array); }
public static explicit operator float[,](MyMatrix v) { float[,] array = new float[v.Rows, v.Columns]; for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) array[i, j] = v[i, j]; return array; }
public static MyMatrix MatrixMultiplication(MyMatrix u, MyMatrix v) { if (u.Columns == v.Rows) { MyMatrix matrix = new MyMatrix(u.Rows, v.Columns); for (int i = 0; i < u.Rows; i++) for (int j = 0; j < v.Columns; j++) { matrix[i,j] = 0; for (int k = 0; k < u.Columns; k++) matrix[i,j] += u[i,k] * v[k,j]; } return matrix; } else { throw new Exception("Такие матрицы не возможно перемножить!"); } }
public static MyMatrix operator *(MyMatrix u, MyMatrix v) { return MyMatrix.MatrixMultiplication(u, v); }
public static MyMatrix Transposition(MyMatrix v) { MyMatrix matrix = new MyMatrix(v.Columns, v.Rows); for (int i = 0; i < v.Rows; i++) for (int j = 0; j < v.Columns; j++) matrix[j,i] = v[i,j]; return matrix; }
public object Clone() { MyMatrix matrix = new MyMatrix(Rows, Columns); for (int i = 0; i < Rows; i++) for (int j = 0; j < Columns; j++) matrix[i, j] = this[i, j]; return matrix; }
public override string ToString() { string str = ""; for (int i = 0; i < Rows; i++) { str += "{"; for (int j = 0; j < Columns; j++) { if (j != 0) str += ","; str += this[i,j]; } str += "}"; } return str; } }
|
Код | public class Vector : MyMatrix { public Vector(float x, float y, float z) : base(new float[1, 3] { { x, y, z } }) { }
public float this[int i] { get { return this[0, i]; } set { this[0, i] = value; } }
public float X { get { return this[0]; } set { this[0] = value; } }
public float Y { get { return this[1]; } set { this[1] = value; } }
public float Z { get { return this[2]; } set { this[2] = value; } }
public float GetLength() { return (float)Math.Sqrt(X * X + Y * Y + Z * Z); }
public float GetLengthSquared() { return (X * X + Y * Y + Z * Z); }
public void Normalize() { float length = GetLength(); if (length == 0) { throw new DivideByZeroException("Невожможно нормализовать нулевой вектор."); }
X /= length; Y /= length; Z /= length; }
public static float Angle(Vector u, Vector v) { return (float)Math.Acos(Vector.ScalarProduct(u, v) / (u.GetLength() * v.GetLength())); }
public static float ScalarProduct(Vector u, Vector v) { return u.X * v.X + u.Y * v.Y + u.Z * v.Z; }
public static Vector CrossProduct(Vector u, Vector v) { return new Vector(u.Y * v.Z - u.Z * v.Y, u.Z * v.X - u.X * v.Z, u.X * v.Y - u.Y * v.X); }
public static Vector operator *(Vector u, Vector v) { return Vector.CrossProduct(u, v); }
public static explicit operator float[](Vector v) { float[] array = new float[v.Columns]; for (int i = 0; i < v.Columns; i++) array[i] = v[i]; return array; } }
|
|