From df96fea5b84f90d5472702a946d86d256aa21172 Mon Sep 17 00:00:00 2001 From: Masha Date: Wed, 26 May 2021 23:58:38 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B7=D0=B0=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5=203?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BoringVector.Tests.csproj | 26 ++++ .../BoringVector.Tests/TestVector.cs | 60 +++++++ .../BoringVector/BoringVector.sln | 12 +- .../BoringVector/BoringVector/Vector.cs | 147 ++++++++++++++---- .../BoringVector/VectorExtensions.cs | 57 ++++++- 5 files changed, 268 insertions(+), 34 deletions(-) create mode 100644 course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/BoringVector.Tests.csproj create mode 100644 course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/TestVector.cs diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/BoringVector.Tests.csproj b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/BoringVector.Tests.csproj new file mode 100644 index 00000000..6551b245 --- /dev/null +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/BoringVector.Tests.csproj @@ -0,0 +1,26 @@ + + + + netcoreapp3.1 + + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/TestVector.cs b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/TestVector.cs new file mode 100644 index 00000000..cf8aafd7 --- /dev/null +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.Tests/TestVector.cs @@ -0,0 +1,60 @@ +using System; +using Xunit; +using BoringVector; + +namespace BoringVector.Tests +{ + public class TestVector + { + [Fact] + public void TestEmptyVectorLength() + { + Vector v = new Vector(); + Assert.Equal(0.0, v.SquareLength()); + } + + [Theory] + [InlineData(3, 4, 25)] + [InlineData(5, -6, 25 + 36)] + public void TestVectorLength(double x, double y, double length) + { + Vector v = new Vector() { X = x, Y = y }; + Assert.Equal(length, v.SquareLength()); + } + + [Fact] + public void TestVectorAdd() + { + Vector v1 = new Vector() { X = 3, Y = 4 }; + Vector v2 = new Vector() { X = 2, Y = -2 }; + Vector sum = v1.Add(v2); + Assert.Equal(5.0, sum.X); + Assert.Equal(2.0, sum.Y); + } + + [Fact] + public void TestVectorScale() + { + Vector v = new Vector() { X = 3, Y = -4 }; + Vector scaled = v.Scale(-2); + Assert.Equal(-6, scaled.X); + Assert.Equal(8.0, scaled.Y); + } + + [Fact] + public void TestVectorDotProduct() + { + Vector v1 = new Vector() { X = 3, Y = 4 }; + Vector v2 = new Vector() { X = 2, Y = -2 }; + Assert.Equal(3 * 2 - 4 * 2, v1.DotProduct(v2)); + } + + [Fact] + public void TestVectorCrossProduct() + { + Vector v1 = new Vector() { X = 3, Y = 4 }; + Vector v2 = new Vector() { X = 2, Y = -2 }; + Assert.Equal(-3 * 2 - 4 * 2, v1.CrossProduct(v2)); + } + } +} diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.sln b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.sln index ef06cdd5..25cbbc26 100644 --- a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.sln +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector.sln @@ -1,9 +1,11 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27004.2002 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31005.135 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BoringVector", "BoringVector\BoringVector.csproj", "{7B438112-6A12-47BC-B494-FF8850924783}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BoringVector", "BoringVector\BoringVector.csproj", "{7B438112-6A12-47BC-B494-FF8850924783}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BoringVector.Tests", "BoringVector.Tests\BoringVector.Tests.csproj", "{4E727AC5-1465-493E-9A2D-07D951651867}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +17,10 @@ Global {7B438112-6A12-47BC-B494-FF8850924783}.Debug|Any CPU.Build.0 = Debug|Any CPU {7B438112-6A12-47BC-B494-FF8850924783}.Release|Any CPU.ActiveCfg = Release|Any CPU {7B438112-6A12-47BC-B494-FF8850924783}.Release|Any CPU.Build.0 = Release|Any CPU + {4E727AC5-1465-493E-9A2D-07D951651867}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E727AC5-1465-493E-9A2D-07D951651867}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E727AC5-1465-493E-9A2D-07D951651867}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E727AC5-1465-493E-9A2D-07D951651867}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs index bb9db585..4edc5cf9 100644 --- a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/Vector.cs @@ -1,4 +1,7 @@ using System; +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("BoringVector.Tests")] namespace BoringVector { @@ -10,55 +13,138 @@ Реализуй структуру Vector - см. комментарии вну internal struct Vector { - /* - Vector задается парой вещественных координат X и Y. - */ - + /// + /// Координаты вектора + /// + public double X, Y; - /* - На месте заглушек добавь реализацию базовых методов вектора: - - квадрат длины - - сумма векторов - - умножение на коэффициент - - скалярное произведение - - векторное произведение (= площадь параллелограмма) - */ + /// + /// Квадрат длины вектора + /// + /// квадрат длины вектора public double SquareLength() { - throw new NotImplementedException(); + return X * X + Y * Y; } + + /// + /// Прибавляет вектор v к данному + /// + /// Вектор, который нужно прибавать + /// Сумму текущего вектора с v public Vector Add(Vector v) { - throw new NotImplementedException(); + return new Vector { X = X + v.X, Y = Y + v.Y }; } + /// + /// Умножает текущий вектор на число + /// + /// Множитель + /// Произведение вектора на k public Vector Scale(double k) { - throw new NotImplementedException(); + return new Vector { X = X * k, Y = Y * k }; } + /// + /// Скалярное произведение вектора с v + /// + /// Второй вектор в скалярном произвдении + /// Число, равное скалярному произведению public double DotProduct(Vector v) { - throw new NotImplementedException(); + return X * v.X + Y * v.Y; } + /// + /// Векторное произведение вектора с v + /// + /// Второй вектор в векторном произвдении + /// Число, равное Z компоненте векторномго произведения public double CrossProduct(Vector v) { - throw new NotImplementedException(); + return X * v.Y - Y * v.X; } - /* - Переопредели ниже метод ToString - пусть выводит (X; Y) - */ + /// + /// Котиковое представление вектора + /// + /// Строковое представление вектора для котика + public override string ToString() + { + return string.Format("({0:f}; {1:f})", X, Y); + } - #region operators + /// + /// Сложение двух векторов + /// + /// Вектор a + /// Вектор b + /// Вектор равный a+b + public static Vector operator +(Vector a, Vector b) + { + return a.Add(b); + } - /* - Реализуй также следущие операторы (Vector v, u и double k): - - v + u, v - u - - k * v, v * k, v / k - - +v, -v - */ + /// + /// Вычитание двух векторов + /// + /// Вектор a + /// Вектор b + /// Вектор равный a-b + public static Vector operator -(Vector a, Vector b) + { + return new Vector { X = a.X - b.X, Y = a.Y - b.Y }; + } + + /// + /// Умножение вектора на число + /// + /// Вектор + /// Число + /// Вектор равный a*k + public static Vector operator *(Vector a, double k) + { + return a.Scale(k); + } + + /// + /// Умножение вектора на число + /// + /// Число + /// Вектор + /// Вектор равный k*a + public static Vector operator *(double k, Vector a) + { + return a.Scale(k); + } + + /// + /// Деление вектора на число + /// + /// Вектор + /// Число, не должно быть нулем + /// Вектор равный a/k + public static Vector operator /(Vector a, double k) + { + return a.Scale(checked(1 / k)); + } + + + /// + /// Вектор, обратный данному + /// + /// Вектор + /// Вектор равный -a + public static Vector operator -(Vector a) + { + return a.Scale(-1); + } + + public static Vector operator +(Vector a) + { + return a; + } - #endregion } #endregion @@ -110,6 +196,7 @@ Ты мог(-ла) заметить, что в предыдущих задани Правилом хорошего тона считается писать комментарии к методам, классам и другим сущностям, используя данный синтаксис - так ты и комментируешь их, и документируешь. Внутри методов он не поддерживается, поэтому там только обычные (// или /*). + Ниже приведены примеры простейших комментариев. Если наведете мышкой на название метода DoNothing, увидишь, что студия отображает комментарий в подписи (в других IDE из коробки без плагинов это вряд ли будет работать). Если навести на аргумент метода DoNothing - something, увидишь комментарий к нему. @@ -174,6 +261,7 @@ который будет содержать класс с набором тес Особо не заморачивайся с тем, чтобы оттестировать все возможные специальные случаи - в данном задании важно, чтобы ты просто разобрался(-ась), как писать автотесты и как их запускать. Это задание НЕ на то, как писать хорошие тесты. + Примечание: структура Vector описана как internal структура, поэтому по умолчанию сборке BoringVector.Tests она не видна. Чтобы она была видна, существует специальная директива компилятору: [assembly: InternalsVisibleTo("XXX")] @@ -186,8 +274,7 @@ ты просто разобрался(-ась), как писать автот #endregion - /* На этом все. Время делать пулл реквест и наслаждаться заслуженным отдыхом :) */ -} +} \ No newline at end of file diff --git a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/VectorExtensions.cs b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/VectorExtensions.cs index 525be40f..a5e3ec2e 100644 --- a/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/VectorExtensions.cs +++ b/course-2021-1/exercises/03-boring-vector/BoringVector/BoringVector/VectorExtensions.cs @@ -1,4 +1,6 @@ -namespace BoringVector +using System; + +namespace BoringVector { /* Здесь тебе нужно написать класс с методами-расширениями структуры Vector: @@ -7,4 +9,57 @@ - GetAngleBetween: возвращает угол между двумя векторами в радианах. Примечание: нулевой вектор сонаправлен любому другому. - GetRelation: возвращает значение перечесления VectorRelation(General, Parallel, Orthogonal) - отношение между двумя векторами("общий случай", параллельны, перпендикулярны). Перечисление задавать тоже тебе) */ + + + internal enum VectorRelation + { + General, + Parallel, + Orthogonal + } + + internal static class VectorExtention + { + private const double Epsilon = 1e-6; + + internal static bool IsZero(this Vector v) + { + return Math.Abs(v.X) < Epsilon && Math.Abs(v.Y) < Epsilon; + } + + internal static Vector Normalize(this Vector v) + { + return v / Math.Sqrt(v.SquareLength()); + } + + internal static double GetAngleBetween(this Vector a, Vector b) + { + if (a.IsZero() || b.IsZero()) + { + return 0; + } + return Math.Acos(a.DotProduct(b) / Math.Sqrt(a.SquareLength() * b.SquareLength())); + } + + internal static VectorRelation GetRelation(this Vector a, Vector b) + { + double angle = a.GetAngleBetween(b); + if (Math.Abs(angle - Math.PI) < Epsilon) + { + return VectorRelation.Orthogonal; + } + else + { + if (angle < Epsilon || angle > Math.PI + Epsilon) + { + return VectorRelation.Parallel; + } + else + { + return VectorRelation.General; + } + } + } + } + }