From 4562f97dcf4e9737b16e41ecf8dde33a6e2f20e3 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Mon, 4 Dec 2023 11:21:08 +0500 Subject: [PATCH 01/21] =?UTF-8?q?=D0=9D=D0=B0=D0=BC=D0=B5=D1=82=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D1=80=D0=B8=D0=BC=D0=B5=D1=80=D0=BD=D0=BE=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=81=D1=82=D1=80=D1=83=D0=BA=D1=86=D0=B8?= =?UTF-8?q?=D1=8E=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0=20=D0=B8=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 17 +++++++++++++ .../TagsCloudVisualization.csproj | 18 ++++++++++++++ .../UnitTests/CircularCloudLayouter_Should.cs | 24 +++++++++++++++++++ .../UnitTests/TestData.cs | 19 +++++++++++++++ cs/tdd.sln | 6 +++++ 5 files changed, 84 insertions(+) create mode 100644 cs/TagsCloudVisualization/CircularCloudLayouter.cs create mode 100644 cs/TagsCloudVisualization/TagsCloudVisualization.csproj create mode 100644 cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs create mode 100644 cs/TagsCloudVisualization/UnitTests/TestData.cs diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs new file mode 100644 index 000000000..1abb47f8f --- /dev/null +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -0,0 +1,17 @@ +using System.Drawing; +using TagsCloudVisualization; + +class CircularCloudLayouter +{ + public CircularCloudLayouter(Point center) + { + + } + + public Rectangle PutNextRectangle(Size rectangleSize) + { + if (rectangleSize.Height <= 0 || rectangleSize.Width <= 0) + throw new ArgumentException("rectangleSize with zero or negative height or width is prohibited!"); + throw new NotImplementedException(); + } +} diff --git a/cs/TagsCloudVisualization/TagsCloudVisualization.csproj b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj new file mode 100644 index 000000000..38ea02659 --- /dev/null +++ b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj @@ -0,0 +1,18 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + diff --git a/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs new file mode 100644 index 000000000..6ef33cc58 --- /dev/null +++ b/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs @@ -0,0 +1,24 @@ +using System.Drawing; +using FluentAssertions; +using NUnit.Framework; + +namespace TagsCloudVisualization +{ + class CircularCloudLayouter_Should + { + [Test] + public void Create_Without_Exceptions() + { + var action = new Action(() => new CircularCloudLayouter(new Point())); + action.Should().NotThrow(); + } + + [TestCaseSource(typeof(TestData), nameof(TestData.ZeroOrLessHeightOrWidth_Size))] + public void Throw_WhenPutNewRectangle_WidthOrHeightLessEqualsZero(Size size) + { + var action = new Action(() => new CircularCloudLayouter(new Point()).PutNextRectangle(size)); + action.Should().Throw() + .Which.Message.Should().Contain("zero or negative height or width"); + } + } +} diff --git a/cs/TagsCloudVisualization/UnitTests/TestData.cs b/cs/TagsCloudVisualization/UnitTests/TestData.cs new file mode 100644 index 000000000..667b9357d --- /dev/null +++ b/cs/TagsCloudVisualization/UnitTests/TestData.cs @@ -0,0 +1,19 @@ +using System.Drawing; +using NUnit.Framework; + +namespace TagsCloudVisualization +{ + public class TestData + { + public static IEnumerable ZeroOrLessHeightOrWidth_Size() + { + yield return new TestCaseData(new Size(0, 1)).SetName("Zero_Width_Size"); + yield return new TestCaseData(new Size(1, 0)).SetName("Zero_Height_Size"); + yield return new TestCaseData(new Size(0, 0)).SetName("Zero_Width_And_Height_Size"); + yield return new TestCaseData(new Size(int.MinValue, 1)).SetName("Negative_Width_Size"); + yield return new TestCaseData(new Size(1, int.MinValue)).SetName("Negative_Height_Size"); + yield return new TestCaseData(new Size(int.MinValue, int.MinValue)) + .SetName("Negative_Width_And_Height_Size"); + } + } +} diff --git a/cs/tdd.sln b/cs/tdd.sln index c8f523d63..91e2f79e3 100644 --- a/cs/tdd.sln +++ b/cs/tdd.sln @@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BowlingGame", "BowlingGame\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "Samples\Samples.csproj", "{B5108E20-2ACF-4ED9-84FE-2A718050FC94}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TagsCloudVisualization", "TagsCloudVisualization\TagsCloudVisualization.csproj", "{5C6414B4-E16F-4DE3-974A-5CE1DBA055D2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ Global {B5108E20-2ACF-4ED9-84FE-2A718050FC94}.Debug|Any CPU.Build.0 = Debug|Any CPU {B5108E20-2ACF-4ED9-84FE-2A718050FC94}.Release|Any CPU.ActiveCfg = Release|Any CPU {B5108E20-2ACF-4ED9-84FE-2A718050FC94}.Release|Any CPU.Build.0 = Release|Any CPU + {5C6414B4-E16F-4DE3-974A-5CE1DBA055D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5C6414B4-E16F-4DE3-974A-5CE1DBA055D2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5C6414B4-E16F-4DE3-974A-5CE1DBA055D2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5C6414B4-E16F-4DE3-974A-5CE1DBA055D2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 8ddfe0648ce8f5c10ed27fb353ecc79ba3876d50 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Tue, 5 Dec 2023 16:44:07 +0500 Subject: [PATCH 02/21] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=90=D1=80=D1=85=D0=B8=D0=BC=D0=B5=D0=B4=D0=BE=D0=B2?= =?UTF-8?q?=D1=83=20=D1=81=D0=BF=D0=B8=D1=80=D0=B0=D0=BB=D1=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ArchimedeanSpiral.cs | 19 +++++++++++++ .../CircularCloudLayouter.cs | 7 ++--- .../UnitTests/ArchimedeanSpiral_Should.cs | 28 +++++++++++++++++++ .../UnitTests/CircularCloudLayouter_Should.cs | 4 +-- .../UnitTests/TestDataArchimedeanSpiral.cs | 26 +++++++++++++++++ ...ta.cs => TestDataCircularCloudLayouter.cs} | 4 +-- 6 files changed, 79 insertions(+), 9 deletions(-) create mode 100644 cs/TagsCloudVisualization/ArchimedeanSpiral.cs create mode 100644 cs/TagsCloudVisualization/UnitTests/ArchimedeanSpiral_Should.cs create mode 100644 cs/TagsCloudVisualization/UnitTests/TestDataArchimedeanSpiral.cs rename cs/TagsCloudVisualization/UnitTests/{TestData.cs => TestDataCircularCloudLayouter.cs} (89%) diff --git a/cs/TagsCloudVisualization/ArchimedeanSpiral.cs b/cs/TagsCloudVisualization/ArchimedeanSpiral.cs new file mode 100644 index 000000000..2b72be7db --- /dev/null +++ b/cs/TagsCloudVisualization/ArchimedeanSpiral.cs @@ -0,0 +1,19 @@ +using System.Drawing; + +namespace TagsCloudVisualization +{ + public class ArchimedeanSpiral(Point centralPoint, double scale = 1) + { + private double angle { get; set; } + private const double DeltaAngle = Math.PI / 180; + + public Point GetNextPoint() + { + var newX = (int)(centralPoint.X + scale * angle * Math.Cos(angle)); + var newY = (int)(centralPoint.Y + scale * angle * Math.Sin(angle)); + angle += DeltaAngle; + + return new Point(newX, newY); + } + } +} diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 1abb47f8f..c901ab0d3 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -1,12 +1,9 @@ using System.Drawing; using TagsCloudVisualization; -class CircularCloudLayouter +class CircularCloudLayouter(Point centerPoint) { - public CircularCloudLayouter(Point center) - { - - } + private ArchimedeanSpiral spiral = new(centerPoint); public Rectangle PutNextRectangle(Size rectangleSize) { diff --git a/cs/TagsCloudVisualization/UnitTests/ArchimedeanSpiral_Should.cs b/cs/TagsCloudVisualization/UnitTests/ArchimedeanSpiral_Should.cs new file mode 100644 index 000000000..50e7b51b4 --- /dev/null +++ b/cs/TagsCloudVisualization/UnitTests/ArchimedeanSpiral_Should.cs @@ -0,0 +1,28 @@ +using System.Drawing; +using FluentAssertions; +using NUnit.Framework; + +namespace TagsCloudVisualization.UnitTests +{ + [TestFixture] + public class ArchimedeanSpiral_Should + { + [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] + public void ReturnCenterPoint_WhenFirstTime_GetNextPoint(Point point) + { + var spiral = new ArchimedeanSpiral(point); + spiral.GetNextPoint().Should().BeEquivalentTo(point); + } + + [TestCaseSource(typeof(TestDataArchimedeanSpiral), + nameof(TestDataArchimedeanSpiral.DifferentIterationsAdded_ExpectedPoints))] + public void ReturnsCorrectPoint_When(int iterations, Point expectedPoint) + { + var spiral = new ArchimedeanSpiral(new Point()); + for (var i = 0; i < iterations; i++) + spiral.GetNextPoint(); + + spiral.GetNextPoint().Should().BeEquivalentTo(expectedPoint); + } + } +} diff --git a/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs index 6ef33cc58..e9bb3bd72 100644 --- a/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs @@ -2,7 +2,7 @@ using FluentAssertions; using NUnit.Framework; -namespace TagsCloudVisualization +namespace TagsCloudVisualization.UnitTests { class CircularCloudLayouter_Should { @@ -13,7 +13,7 @@ public void Create_Without_Exceptions() action.Should().NotThrow(); } - [TestCaseSource(typeof(TestData), nameof(TestData.ZeroOrLessHeightOrWidth_Size))] + [TestCaseSource(typeof(TestDataCircularCloudLayouter), nameof(TestDataCircularCloudLayouter.ZeroOrLessHeightOrWidth_Size))] public void Throw_WhenPutNewRectangle_WidthOrHeightLessEqualsZero(Size size) { var action = new Action(() => new CircularCloudLayouter(new Point()).PutNextRectangle(size)); diff --git a/cs/TagsCloudVisualization/UnitTests/TestDataArchimedeanSpiral.cs b/cs/TagsCloudVisualization/UnitTests/TestDataArchimedeanSpiral.cs new file mode 100644 index 000000000..ec915165d --- /dev/null +++ b/cs/TagsCloudVisualization/UnitTests/TestDataArchimedeanSpiral.cs @@ -0,0 +1,26 @@ +using System.Drawing; +using NUnit.Framework; + +namespace TagsCloudVisualization.UnitTests +{ + public class TestDataArchimedeanSpiral + { + public static IEnumerable Different_CenterPoints() + { + yield return new TestCaseData(new Point(0, 0)).SetName("(0, 0) center"); + yield return new TestCaseData(new Point(int.MinValue, int.MaxValue)).SetName("(minInt, maxInt) center"); + yield return new TestCaseData(new Point(int.MaxValue, int.MinValue)).SetName("(maxInt, minInt) center"); + } + + public static IEnumerable DifferentIterationsAdded_ExpectedPoints() + { + yield return new TestCaseData(0, new Point(0, 0)).SetName("0 iterations, central point"); + yield return new TestCaseData(90, new Point(0, (int)(Math.PI / 2))).SetName("90 iterations, half PI"); + yield return new TestCaseData(180, new Point((int)(-Math.PI), 0)).SetName("180 iterations, PI"); + yield return new TestCaseData(270, new Point(0, (int)(-Math.PI * 3 / 2))).SetName("270 iterations, 3/2 PI"); + yield return new TestCaseData(360, new Point((int)(2 * Math.PI), 0)).SetName("360 iterations, double PI"); + yield return new TestCaseData(450, new Point(0, (int)(Math.PI * 5 / 2))).SetName("450 iterations, 5/2 PI"); + yield return new TestCaseData(540, new Point((int)(-3 * Math.PI), 0)).SetName("540 iterations, triple PI"); + } + } +} diff --git a/cs/TagsCloudVisualization/UnitTests/TestData.cs b/cs/TagsCloudVisualization/UnitTests/TestDataCircularCloudLayouter.cs similarity index 89% rename from cs/TagsCloudVisualization/UnitTests/TestData.cs rename to cs/TagsCloudVisualization/UnitTests/TestDataCircularCloudLayouter.cs index 667b9357d..e6be7369a 100644 --- a/cs/TagsCloudVisualization/UnitTests/TestData.cs +++ b/cs/TagsCloudVisualization/UnitTests/TestDataCircularCloudLayouter.cs @@ -1,9 +1,9 @@ using System.Drawing; using NUnit.Framework; -namespace TagsCloudVisualization +namespace TagsCloudVisualization.UnitTests { - public class TestData + public class TestDataCircularCloudLayouter { public static IEnumerable ZeroOrLessHeightOrWidth_Size() { From 5b716cfbdb9dd239c46a52626098639cee11ed66 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Tue, 5 Dec 2023 17:28:27 +0500 Subject: [PATCH 03/21] =?UTF-8?q?=D0=98=D0=BD=D1=82=D0=B5=D0=B3=D1=80?= =?UTF-8?q?=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=20=D1=81=D0=BF=D0=B8=D1=80?= =?UTF-8?q?=D0=B0=D0=BB=D1=8C=20=D0=B2=20layouter=20=D0=B8=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=B4=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 31 +++++++---- .../UnitTests/CircularCloudLayouter_Should.cs | 52 ++++++++++++++++--- .../UnitTests/TestDataArchimedeanSpiral.cs | 4 +- cs/tdd.sln.DotSettings | 4 +- 4 files changed, 71 insertions(+), 20 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index c901ab0d3..c2100068a 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -1,14 +1,27 @@ using System.Drawing; -using TagsCloudVisualization; -class CircularCloudLayouter(Point centerPoint) +namespace TagsCloudVisualization { - private ArchimedeanSpiral spiral = new(centerPoint); - - public Rectangle PutNextRectangle(Size rectangleSize) + class CircularCloudLayouter(Point centerPoint) { - if (rectangleSize.Height <= 0 || rectangleSize.Width <= 0) - throw new ArgumentException("rectangleSize with zero or negative height or width is prohibited!"); - throw new NotImplementedException(); + private readonly List rectangles = new(); + private readonly ArchimedeanSpiral spiral = new(centerPoint); + + public Rectangle PutNextRectangle(Size rectangleSize) + { + if (rectangleSize.Height <= 0 || rectangleSize.Width <= 0) + throw new ArgumentException("rectangleSize with zero or negative height or width is prohibited!"); + while (true) + { + var rectangle = new Rectangle(spiral.GetNextPoint(), rectangleSize); + if (rectangles.Any(x => x.IntersectsWith(rectangle))) continue; + rectangles.Add(rectangle); + break; + } + + return rectangles[^1]; + } + + public IReadOnlyList GetRectangles() => rectangles.AsReadOnly(); } -} +} \ No newline at end of file diff --git a/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs index e9bb3bd72..fe743e8c8 100644 --- a/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs @@ -6,19 +6,55 @@ namespace TagsCloudVisualization.UnitTests { class CircularCloudLayouter_Should { - [Test] - public void Create_Without_Exceptions() - { - var action = new Action(() => new CircularCloudLayouter(new Point())); - action.Should().NotThrow(); - } - - [TestCaseSource(typeof(TestDataCircularCloudLayouter), nameof(TestDataCircularCloudLayouter.ZeroOrLessHeightOrWidth_Size))] + [TestCaseSource(typeof(TestDataCircularCloudLayouter), + nameof(TestDataCircularCloudLayouter.ZeroOrLessHeightOrWidth_Size))] public void Throw_WhenPutNewRectangle_WidthOrHeightLessEqualsZero(Size size) { var action = new Action(() => new CircularCloudLayouter(new Point()).PutNextRectangle(size)); action.Should().Throw() .Which.Message.Should().Contain("zero or negative height or width"); } + + [Test] + public void RectanglesEmpty_AfterCreation() + { + var layouter = new CircularCloudLayouter(new Point()); + layouter.GetRectangles().Should().BeEmpty(); + } + + [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] + public void Add_FirstRectangle_ToCenter(Point center) + { + var layouter = new CircularCloudLayouter(center); + layouter.PutNextRectangle(new Size(10, 2)); + layouter.GetRectangles().Should().HaveCount(1) + .And.BeEquivalentTo(new Rectangle(center, new Size(10, 2))); + } + + [Test] + public void AddSeveralRectangles_Correctly() + { + var layouter = new CircularCloudLayouter(new Point()); + for (var i = 1; i < 26; i++) + { + layouter.PutNextRectangle(new Size(i * 20, i * 10)); + } + + layouter.GetRectangles().Should().HaveCount(25).And.AllBeOfType(typeof(Rectangle)); + } + + [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] + public void AddSeveralRectangles_DoNotIntersect(Point point) + { + var layouter = new CircularCloudLayouter(point); + for (var i = 1; i < 26; i++) + { + layouter.PutNextRectangle(new Size(i * 20, i * 10)); + } + + var rectangles = layouter.GetRectangles(); + for (var i = 1; i < rectangles.Count; i++) + rectangles.Skip(i).All(x => !rectangles[i - 1].IntersectsWith(x)).Should().Be(true); + } } } diff --git a/cs/TagsCloudVisualization/UnitTests/TestDataArchimedeanSpiral.cs b/cs/TagsCloudVisualization/UnitTests/TestDataArchimedeanSpiral.cs index ec915165d..f71c466bf 100644 --- a/cs/TagsCloudVisualization/UnitTests/TestDataArchimedeanSpiral.cs +++ b/cs/TagsCloudVisualization/UnitTests/TestDataArchimedeanSpiral.cs @@ -8,8 +8,8 @@ public class TestDataArchimedeanSpiral public static IEnumerable Different_CenterPoints() { yield return new TestCaseData(new Point(0, 0)).SetName("(0, 0) center"); - yield return new TestCaseData(new Point(int.MinValue, int.MaxValue)).SetName("(minInt, maxInt) center"); - yield return new TestCaseData(new Point(int.MaxValue, int.MinValue)).SetName("(maxInt, minInt) center"); + yield return new TestCaseData(new Point(343, 868)).SetName("(343, 868) center"); + yield return new TestCaseData(new Point(-343, -868)).SetName("(-343, -868) center"); } public static IEnumerable DifferentIterationsAdded_ExpectedPoints() diff --git a/cs/tdd.sln.DotSettings b/cs/tdd.sln.DotSettings index 135b83ecb..b179e7882 100644 --- a/cs/tdd.sln.DotSettings +++ b/cs/tdd.sln.DotSettings @@ -80,4 +80,6 @@ public void SetUp() { $END$ } - \ No newline at end of file + + True + True \ No newline at end of file From a528b58d1f34473d30a698965795d039cbf21fdc Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Tue, 5 Dec 2023 20:04:55 +0500 Subject: [PATCH 04/21] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BE=D1=82=D1=80=D0=B8=D1=81=D0=BE=D0=B2=D0=BA=D1=83?= =?UTF-8?q?=20=D0=BE=D0=B1=D0=BB=D0=B0=D0=BA=D0=B0=20=D1=82=D0=B5=D0=B3?= =?UTF-8?q?=D0=BE=D0=B2,=20=D0=BF=D0=BE=D0=B4=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=80=D0=B0=D1=81=D0=BF=D0=BE=D0=BB=D0=BE=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D1=8F=D0=BC=D0=BE=D1=83?= =?UTF-8?q?=D0=B3=D0=BE=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 4 +- cs/TagsCloudVisualization/Drawer.cs | 17 ++++++ .../Drawings/CloudTag_DecreasingSize.png | Bin 0 -> 24599 bytes .../Drawings/CloudTag_RandomSize.png | Bin 0 -> 28138 bytes .../Drawings/CloudTag_SameSize.png | Bin 0 -> 26760 bytes cs/TagsCloudVisualization/Program.cs | 51 ++++++++++++++++++ .../TagsCloudVisualization.csproj | 3 +- .../UnitTests/CircularCloudLayouter_Should.cs | 3 +- 8 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 cs/TagsCloudVisualization/Drawer.cs create mode 100644 cs/TagsCloudVisualization/Drawings/CloudTag_DecreasingSize.png create mode 100644 cs/TagsCloudVisualization/Drawings/CloudTag_RandomSize.png create mode 100644 cs/TagsCloudVisualization/Drawings/CloudTag_SameSize.png create mode 100644 cs/TagsCloudVisualization/Program.cs diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index c2100068a..78e360914 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -13,7 +13,9 @@ public Rectangle PutNextRectangle(Size rectangleSize) throw new ArgumentException("rectangleSize with zero or negative height or width is prohibited!"); while (true) { - var rectangle = new Rectangle(spiral.GetNextPoint(), rectangleSize); + var nextPoint = spiral.GetNextPoint(); + var rectangle = new Rectangle(new Point(nextPoint.X - rectangleSize.Width / 2, nextPoint.Y - + rectangleSize.Height / 2), rectangleSize); if (rectangles.Any(x => x.IntersectsWith(rectangle))) continue; rectangles.Add(rectangle); break; diff --git a/cs/TagsCloudVisualization/Drawer.cs b/cs/TagsCloudVisualization/Drawer.cs new file mode 100644 index 000000000..c7c439118 --- /dev/null +++ b/cs/TagsCloudVisualization/Drawer.cs @@ -0,0 +1,17 @@ +using System.Drawing; + +namespace TagsCloudVisualization +{ + public class Drawer + { + public static Image GetImage(Point centerPoint, IEnumerable rectangles) + { + var image = new Bitmap(centerPoint.X * 2, centerPoint.Y * 2); + var gr = Graphics.FromImage(image); + gr.Clear(Color.Black); + gr.DrawRectangles(new Pen(Color.White), rectangles.ToArray()); + + return image; + } + } +} diff --git a/cs/TagsCloudVisualization/Drawings/CloudTag_DecreasingSize.png b/cs/TagsCloudVisualization/Drawings/CloudTag_DecreasingSize.png new file mode 100644 index 0000000000000000000000000000000000000000..f9140ad981d004a6fdac532e3cb2d4a2f8b17cb4 GIT binary patch literal 24599 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%0ATnI(L43WOcoIYAu1M$85V4IhWo!d+blmGZ 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 TB^4g?AF_1uN{6&XA0PM+fB6@; literal 0 HcmV?d00001 diff --git a/cs/TagsCloudVisualization/Drawings/CloudTag_RandomSize.png b/cs/TagsCloudVisualization/Drawings/CloudTag_RandomSize.png new file mode 100644 index 0000000000000000000000000000000000000000..db32137ad91b3f1de7c89135175cd653f3e14960 GIT binary patch literal 28138 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 Prx%}_G+sA$*7E-YJWmuD literal 0 HcmV?d00001 diff --git a/cs/TagsCloudVisualization/Program.cs b/cs/TagsCloudVisualization/Program.cs new file mode 100644 index 000000000..10cb9fa66 --- /dev/null +++ b/cs/TagsCloudVisualization/Program.cs @@ -0,0 +1,51 @@ +using System.Drawing; + +namespace TagsCloudVisualization +{ + internal class Program + { + private static void Main() + { + var decImage = DrawDecreasingSize(); + var rndImage = DrawRandomSize(); + var sameImage = DrawSameSize(); + + decImage.Save("CloudTag_DecreasingSize.png"); + rndImage.Save("CloudTag_RandomSize.png"); + sameImage.Save("CloudTag_SameSize.png"); + } + + private static Image DrawDecreasingSize() + { + var layouter = new CircularCloudLayouter(new Point(340, 340)); + layouter.PutNextRectangle(new Size(200, 80)); + + for (var i = 0; i < 20; i++) + layouter.PutNextRectangle(new Size(80, 40)); + + for (var i = 0; i < 200; i++) + layouter.PutNextRectangle(new Size(40, 20)); + + return Drawer.GetImage(new Point(340, 340), layouter.GetRectangles()); + } + + private static Image DrawSameSize() + { + var layouter = new CircularCloudLayouter(new Point(340, 340)); + for (var i = 0; i < 200; i++) + layouter.PutNextRectangle(new Size(30, 30)); + + return Drawer.GetImage(new Point(340, 340), layouter.GetRectangles()); + } + + private static Image DrawRandomSize() + { + var layouter = new CircularCloudLayouter(new Point(340, 340)); + var rnd = new Random(); + for (var i = 0; i < 200; i++) + layouter.PutNextRectangle(new Size(rnd.Next(5, 50), rnd.Next(5, 50))); + + return Drawer.GetImage(new Point(340, 340), layouter.GetRectangles()); + } + } +} diff --git a/cs/TagsCloudVisualization/TagsCloudVisualization.csproj b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj index 38ea02659..9f52f97ec 100644 --- a/cs/TagsCloudVisualization/TagsCloudVisualization.csproj +++ b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj @@ -1,7 +1,7 @@  - Exe + WinExe net8.0 enable enable @@ -13,6 +13,7 @@ + diff --git a/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs index fe743e8c8..b8a825deb 100644 --- a/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs @@ -28,7 +28,8 @@ public void Add_FirstRectangle_ToCenter(Point center) var layouter = new CircularCloudLayouter(center); layouter.PutNextRectangle(new Size(10, 2)); layouter.GetRectangles().Should().HaveCount(1) - .And.BeEquivalentTo(new Rectangle(center, new Size(10, 2))); + .And.BeEquivalentTo(new Rectangle( + new Point(center.X - 10 / 2, center.Y - 2 / 2), new Size(10, 2))); } [Test] From f220213dd90097918c58e4e831a44264956637df Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Tue, 5 Dec 2023 21:20:46 +0500 Subject: [PATCH 05/21] =?UTF-8?q?=D0=92=D1=8B=D0=BD=D0=B5=D1=81=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D1=8B=20=D0=B2=20=D0=BE=D1=82=D0=B4=D0=B5?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA?= =?UTF-8?q?=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 2 +- .../TagsCloudVisualization.csproj | 4 --- .../TagsCloudVisualizationTests.csproj | 25 +++++++++++++++++++ .../UnitTests/ArchimedeanSpiral_Should.cs | 0 .../UnitTests/CircularCloudLayouter_Should.cs | 0 .../UnitTests/TestDataArchimedeanSpiral.cs | 0 .../TestDataCircularCloudLayouter.cs | 0 cs/tdd.sln | 6 +++++ 8 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 cs/TagsCloudVisualizationTests/TagsCloudVisualizationTests.csproj rename cs/{TagsCloudVisualization => TagsCloudVisualizationTests}/UnitTests/ArchimedeanSpiral_Should.cs (100%) rename cs/{TagsCloudVisualization => TagsCloudVisualizationTests}/UnitTests/CircularCloudLayouter_Should.cs (100%) rename cs/{TagsCloudVisualization => TagsCloudVisualizationTests}/UnitTests/TestDataArchimedeanSpiral.cs (100%) rename cs/{TagsCloudVisualization => TagsCloudVisualizationTests}/UnitTests/TestDataCircularCloudLayouter.cs (100%) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 78e360914..1f6d2dc33 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -2,7 +2,7 @@ namespace TagsCloudVisualization { - class CircularCloudLayouter(Point centerPoint) + public class CircularCloudLayouter(Point centerPoint) { private readonly List rectangles = new(); private readonly ArchimedeanSpiral spiral = new(centerPoint); diff --git a/cs/TagsCloudVisualization/TagsCloudVisualization.csproj b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj index 9f52f97ec..6608fcd4c 100644 --- a/cs/TagsCloudVisualization/TagsCloudVisualization.csproj +++ b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj @@ -8,11 +8,7 @@ - - - - diff --git a/cs/TagsCloudVisualizationTests/TagsCloudVisualizationTests.csproj b/cs/TagsCloudVisualizationTests/TagsCloudVisualizationTests.csproj new file mode 100644 index 000000000..624f4c4a1 --- /dev/null +++ b/cs/TagsCloudVisualizationTests/TagsCloudVisualizationTests.csproj @@ -0,0 +1,25 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + diff --git a/cs/TagsCloudVisualization/UnitTests/ArchimedeanSpiral_Should.cs b/cs/TagsCloudVisualizationTests/UnitTests/ArchimedeanSpiral_Should.cs similarity index 100% rename from cs/TagsCloudVisualization/UnitTests/ArchimedeanSpiral_Should.cs rename to cs/TagsCloudVisualizationTests/UnitTests/ArchimedeanSpiral_Should.cs diff --git a/cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs similarity index 100% rename from cs/TagsCloudVisualization/UnitTests/CircularCloudLayouter_Should.cs rename to cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs diff --git a/cs/TagsCloudVisualization/UnitTests/TestDataArchimedeanSpiral.cs b/cs/TagsCloudVisualizationTests/UnitTests/TestDataArchimedeanSpiral.cs similarity index 100% rename from cs/TagsCloudVisualization/UnitTests/TestDataArchimedeanSpiral.cs rename to cs/TagsCloudVisualizationTests/UnitTests/TestDataArchimedeanSpiral.cs diff --git a/cs/TagsCloudVisualization/UnitTests/TestDataCircularCloudLayouter.cs b/cs/TagsCloudVisualizationTests/UnitTests/TestDataCircularCloudLayouter.cs similarity index 100% rename from cs/TagsCloudVisualization/UnitTests/TestDataCircularCloudLayouter.cs rename to cs/TagsCloudVisualizationTests/UnitTests/TestDataCircularCloudLayouter.cs diff --git a/cs/tdd.sln b/cs/tdd.sln index 91e2f79e3..dde884531 100644 --- a/cs/tdd.sln +++ b/cs/tdd.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "Samples\Samples. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TagsCloudVisualization", "TagsCloudVisualization\TagsCloudVisualization.csproj", "{5C6414B4-E16F-4DE3-974A-5CE1DBA055D2}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TagsCloudVisualizationTests", "TagsCloudVisualizationTests\TagsCloudVisualizationTests.csproj", "{C97CB590-FA78-4774-B594-28F26FAC15F0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -27,6 +29,10 @@ Global {5C6414B4-E16F-4DE3-974A-5CE1DBA055D2}.Debug|Any CPU.Build.0 = Debug|Any CPU {5C6414B4-E16F-4DE3-974A-5CE1DBA055D2}.Release|Any CPU.ActiveCfg = Release|Any CPU {5C6414B4-E16F-4DE3-974A-5CE1DBA055D2}.Release|Any CPU.Build.0 = Release|Any CPU + {C97CB590-FA78-4774-B594-28F26FAC15F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C97CB590-FA78-4774-B594-28F26FAC15F0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C97CB590-FA78-4774-B594-28F26FAC15F0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C97CB590-FA78-4774-B594-28F26FAC15F0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From b05e987d7070857b41292cbcd18b96479e02f13a Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Tue, 5 Dec 2023 21:29:02 +0500 Subject: [PATCH 06/21] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20readme=20=D0=BF=D0=BE=20=D1=82=D1=80=D0=B5=D0=B1=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D1=8E=20=D1=82=D0=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/README.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 cs/TagsCloudVisualization/README.md diff --git a/cs/TagsCloudVisualization/README.md b/cs/TagsCloudVisualization/README.md new file mode 100644 index 000000000..206add722 --- /dev/null +++ b/cs/TagsCloudVisualization/README.md @@ -0,0 +1,10 @@ +# Примеры работы программы: + +### Облако тегов уменьшающихся размеров тегов +![CloudTag_DecreasingSize.png](Drawings%2FCloudTag_DecreasingSize.png) + +### Облакр тегов рандомного размера +![CloudTag_RandomSize.png](Drawings%2FCloudTag_RandomSize.png) + +### Облако тегов одинаковых размеров +![CloudTag_SameSize.png](Drawings%2FCloudTag_SameSize.png) From 9e8abff33129eaa1289d4d7f34f8e72739e811eb Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Thu, 7 Dec 2023 01:35:23 +0500 Subject: [PATCH 07/21] =?UTF-8?q?=D0=9F=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=BB=20=D1=80=D0=B0=D1=81=D0=BA=D1=80=D0=B0=D1=81=D1=81=D0=BA?= =?UTF-8?q?=D1=83=20=D0=BD=D0=B0=20=D0=BF=D1=80=D1=8F=D0=BC=D0=BE=D1=83?= =?UTF-8?q?=D0=B3=D0=BE=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA=D0=B8=20=D1=81=D0=BF?= =?UTF-8?q?=D0=BB=D0=BE=D1=88=D0=BD=D0=BE=D0=B9=20=D0=B7=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B2=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/Drawer.cs | 7 ++++++- .../Drawings/CloudTag_DecreasingSize.png | Bin 24599 -> 16276 bytes .../Drawings/CloudTag_RandomSize.png | Bin 28138 -> 21008 bytes .../Drawings/CloudTag_SameSize.png | Bin 26760 -> 17024 bytes 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/cs/TagsCloudVisualization/Drawer.cs b/cs/TagsCloudVisualization/Drawer.cs index c7c439118..4fa9d5c7f 100644 --- a/cs/TagsCloudVisualization/Drawer.cs +++ b/cs/TagsCloudVisualization/Drawer.cs @@ -9,7 +9,12 @@ public static Image GetImage(Point centerPoint, IEnumerable rectangle var image = new Bitmap(centerPoint.X * 2, centerPoint.Y * 2); var gr = Graphics.FromImage(image); gr.Clear(Color.Black); - gr.DrawRectangles(new Pen(Color.White), rectangles.ToArray()); + using (var brush = new SolidBrush(Color.White)) + { + foreach (var rectangle in rectangles) + gr.FillRectangle(brush, rectangle); + } + return image; } diff --git a/cs/TagsCloudVisualization/Drawings/CloudTag_DecreasingSize.png b/cs/TagsCloudVisualization/Drawings/CloudTag_DecreasingSize.png index f9140ad981d004a6fdac532e3cb2d4a2f8b17cb4..f5a769dbd3bde6e330554b9e51b43dd2dec9abda 100644 GIT binary patch literal 16276 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 B?-2k1 literal 24599 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%0ATnI(L43WOcoIYAu1M$85V4IhWo!d+blmGZ zSPyx=hRk?T0WJIb&qCBEP;ChJ@fwV_MnRcFF0!1?oEFmz5X&FA30bO=lVBVFiRGD))#*%2dHjy&rW3hC z9d*AE6Ux5Zyi@pKl`v75@r_mZn$V^5Bmu#L60~w;y>f}rwFTBtUc@D46+9= zS{oMH-DwvfTp-)*tv$oq#xw9nLA>dUv&wRI2D&}p$11^V+V?};9AcEeeL^0!<4-@Nc;); zo;BC0AhpF$cwzVnIKaG}$(B{8n1E+-Gv@KKU)QQuNPJv#t80rye{#Rg>rro~;@TF# zb?U_@f*2Vnq$@iAE`{1 zXWu1o2Bsq;9qmM*+-t!abUN;Yxu$c=58qupy=h~Hb>G_+s)|ZfDZ#ZPlDta~g@j-v z0D%7tbG`Er7BYuD%sn@Zf|x%Bh3sYRPq>%=pip7~#v2_#LEtck=VU3Hq2Vqma4LAd zP~x;+lHQQ&awdACanA$GH6Aq&nUM5Rvp;WYt*O*FBu8b$cW2~wqeRXTlF3j|iW;gU zy9s=+uYLD37LRk({gq@H`aQx$#)-D^Bm;0ko|qzE-&{I*nfU53Z7W(hNL#J^o$Z?2 z?;Jw^Kc;UYT+qH#T$0WssjxbQgT zCti5SQ#{nSo`-~B*C@y_NO&&XIrv?zeF%Ny?I8fYff+ZR`}}X3!>y=dU&e){#d%h^ z@jkHP6KFupy=$mBE-<={O7#-M)SV&vF_XD!hxbmrt_%mFcLuzIREzHQpqi>uC5i$_ zx*d4rS<{0@t&LQXr!52X)vj`CN)82~!YR(nYx~-#_3$ zJLn$n4+*rBRdnR+;mnZT3AmhCXMM5#Fo8T-g(NVuJ=yL5CJ>GpPmCv_0^n2M4k-U- zszS>SyxX3+&s?C}N^Z#LQXzZK59mx^Lx@m-)eJi2>~?`Oi$D}n1Zn4uf<6fq&nOhV z>jQ-5Y~)8=?u&#XVqnX4In|>StmzETH#NQ=QEMa*+I6$KK_zIR8qQ*l5;G4M~9Q1#yKuuvt|x12dYa z&$6x8vtHF0r$Aw1DPGX~JRKC=3RN@Axo#Ik*D&*b57I9GlCAITbxG!%>>V7@?2!5D z=7|FzE^dw;Nx6~Akz8;njx|gA@MUf2TBvAzi^Xrq%U`9H!X-vFLP9N9$j@PwY0zsS zJhKf|feN71)tytHU1plnf`FS$e zTFX5lP%`>{s_crWJdc9%i`)J9HPsKyvPhDzE;@&^=kxz z{v;nk5FQ!><)Y_kl*Ks|6u647uv6N0O_M|IZr8!K>QYSR{nxHeLF1zf7w;^TJw%43 zJrV3t{)ONikAJ5P-O`x3B1pPzid2e|Jkp&famz1oj$pS$KgT>8m!2T67h{a}+4Zbp zn)oujO_e`}1W>PR(XTISc_CF$!*i;w6^BEdgmgltS85XEDT;l;swQTLb&&8C@(F$N z7(x*&=lR;8aPAYkZYIZ)nVLP4!D0z3??@aafeWlN7uu=mTdck$>QmocSiMta8~1oA zUP@34Do{?_I2a0?K;c;ysn)7*W>Z0?cE$|ZOVWo!wS`J@1=d$M<1&nqn{^l#a0$X7 z>3l3M)5cTz*e6kL`#x~jR72l}^`%pO0MZ|(Mb}Rw&H=OV&#P!`txcfhvy<%P2EFedIrF8(e<}`c%I_aC1>gZPuNgH+hb<^>ww)bPRtXaRt@xE^r`B@s@M7 z%|S(~g*nwO7dQ(h$X2fPeC232d=hTVww2Y1%9dBbeYN^;ZaW_#Jul*`%Zw6;BUi7r6;-Gx@-^h%F}ZubM3bLv?UO|jrSdlKf1Gy zuM)QfXM@`?+jz>wn)CMqw;D(>;$+{)Bh3`=^ZeSre)Vug5(39W1wjR^=3%vQt9=BP z8sF$x)^k}cX>mBfzD|u8^NKWDG99#fA)^cHeP~vMzUHS|1x% zZvE-_)9a|zon_Yt#hDxa*!pALS>(fI6HCG7v}ebZ`?L*if}SM2YH{%{T9-p{%20N- z_nk*AZ>5CxU_r-*L8>gg{Chud=Dst)!X{>A8{{1G>y$R;>x@UpL07O)Z9oC*+Hbc% zm&Wg?yh$|tixxlJU?>=wYhmcvz%Ru*Sk)K!c;M2dPlS`+cb_(O095! z8zJB-yg8y-*B+cl-jkdD4sgKo{ipmYw>~=l?yslQt7c8ZN>~JhdbOjIyn(gGBWTvr znQ_GaQOZj-YJ}&{r_Qoxgl!~t6kz8j>dG>bSwX9|B7ZVB^ZbhmhrWN}yDxtk{uQ)5 zJkTsoj*8N1fBAXGwnwe{tT@5nR%G$dqi20P$@A{Ebyzz!2Ms8-=zh>d=3+GYBUEr$ zbK#NkGpIff3vE?l53jha!jj$32==2ETbC>sp1pIGm}o#ks^^*LD5;FK;woIPWW(30 zsu|9M+Z}E~F4(^LPcH{IV%rB};PyuEYv3akPcisJj^>mYKHwqy=buMg zIT)g3(Dj{K2x0QuLbh$qm<3n8xQi%Dv`^;M5n`tm>{a%t4gcQypJzyUe1MqS6-og1 zdsyS+(m*vc7hWE3B^#a*TzQkE8}#~!AhMS*=e*Qb5KA5n+a@9i6b{ zW&M^BU=Pg9voCBxe4u*-Ad>u%WlKxw(UM>8L8=RHa!U{xQD|832fcV~!2&$KxM8YBpnrfndvfHA3^-(X+1_ z;0M1$vqGm0-R+(pTkzra>imoWsc12dNKchDKyKa>)w&;g$x2U#$mB}3SdaL=>6OXO zgQj#uar)v;lV&9*487F{2675C(3#SWe;jF};61K9*!TP!l_| zBDbtG9TGhTvC=0zztm#K26S9Bqc=CNVY*tjM2Jkmo?`BV=rjI|2;1`M;$fKZAuZf$ zwryinw8>prSg+@cQYRe3gb(R_kCg1qu8E44>MS^R15*v6L-(g^ao`s}LR8-U;34!}ptVB|`p)KTzZ!IPcI&2&QDgWEiR?{&)LWGiA zCp*OZPGhqfxT7wH88u~_dG_TkP(@tJFPlsLEgD z`$M}EV6x-RRig-4!ro#}9B9Q1e{io|S&&PTbq?sBwwVjR8?UF(3A^oU-tT<+E>wq0$jk zgHeVZk0-s>s?C9b0ODQJ!Q8%>zr5<^T)W=*hA|w5&}btGlXpBiZj6$cfYy;X#||uD zaMW(D(39T#d9)45so@qRcA;AHPgW_NKVc%phX{u%~sED55vijaJ;~D z1L(hk(U4hG9`sVtyu;@Bz`HR$j|a)${O5MpsSh;Vg_5#u(3PLsp~%RAkqqA6aIsU7 z-2x}InG2xe8@zfY?fy!c zQP4WvoF)WG%W$iDNbM~IJLxg0_W^Y%K!^0P24z+n3pz=0UhOnr@ z6!~s$j-2O7h;85RQoLx40j|KenUM1gl_;SHm2V9tX=D@T31GG$BDZ?B+Q!Uq&xP6# z+zp_3?T$HBbErAumc0{D#z-nCh01jrX3k*wJE)@c0c@iDR@!qc4LSfKamP9xPiBQF zGpI~10{jH zFpmmk{Og&}Aq7lQLR-Z*$XDbAQ*Goz?Gu56*Mzr& zgt=b+V>OVmM6(FpUQww7GYq_Co$dWumP-dXZ$wKCmf|L+|;4#sF z7-a>Xq?=fwDSAEf{uT8MSthlkpm|p(#!HjdG(0ea{|{&}MT}OHVtuqK+pQ;Mr{UP7 zpack=ON#&1Y~`r#Yzat?=6;QJk$!f2gw^}MV_BfMZi5x4vUrY6&<(pp*<)C~*R%ej z71JYxl{31k!ftGV{GIIxQ%cbd&0Sbb$_ZVqh&1Ws z^%Ul9$b(~v6nK0b(@jZTtdh6@u09QV(2QbuE|x6ss@p*!w)bYvwTqOTCDlEYW-p&g z#v6&g4T9*zIUKc|8srhgoOkZ{>KfJdo#Zm4@BUCwqavJxU)LPwp(C^@@CkHgLM3tD zJhudWPX;NH-h~+*n~@9)bc3uINkcR{B&~Mu=QkX>dZszZ9u{W*MoQHWY z%yyXTdpOi=s15^1eKP^s_7bORz5tCOQ)IXmbvh`jV=0}G49oWkMCZj0G2FDe92b=>gtiWv!a9}mt3%CNl<%tTyJ#rt!ay>Y& z18A90ruCRwRZuzXfHJU`xpK^9;S~%^2V}SgE8Jju9?Sq8EL4S4b!mXsff)!~M*r6z z1JeT6hoq;5^~aX!a)A*eMU~C{rxuk!K18npzK0>_;gw1)1%uUtAJBa^4Vm%P1A0;q zWL?EpLc^7T{D8~udm1)Tsy}WaNR0XIZG3rDrPv_;f&y@Q`&4llaX?6L8pWSak40iF zP#$b!5Uj1O2qsd{P!ovSgd;?^(X)}*dNEffp!BkkNh#>6LW7N=L6GpMmwyzd+S@yB zJ6IDN3(YDQ@M=K(6L*Pq{r|zHE|hquQ!DFQp{EEfDtLMrmvewYp+wFP*z62$!+@#4 zfDjmMLkmxXWdcme6xlr-@E{5GFkLr2Mb~CC@X{jL%@S&zPRl}N?f2UbiK2Zes?@d? z*?@;R>c~;8le=k~MTp>jIXNP5oCQbPeot+OHZve+3D`tz zAM1^79G=N+w>~ZR$D2ig(e8ul?_o-%^1q+xfGLp`cnuiL0g0W1pd`>4-5)*D2NndI ze_abz*66SGUi@P=At_N?!kw6{`}$fQoP0 z=0RKvo)l{Y(WJRLCv$m8tH5i0R=xFgN~JKpiSkuY4U0Ij-C2bfWdq_DSaZf{53YyP zLpL3C`A1-6h(dtMq8L0CrT|F(1mOOXv~{1_$ODA{^M~=Gl@Miu(eROH+Sfr213`I^_#@n!)N-G!c$=@Su~hU4FN^o`S?6R*OlitN5X)6)4^G3ZP`mg9W4ULQuE z67!sNzu}F>UJ^K3Q~NCusXuX)u_{CFGw5*dClV7+9#CNDh3|SC!I`|u$1vFXc4tas zK-&$*>g5ie0#fzEB_y#^)-SE-!RVG82gu2&1l7d-+sX}1=>Y8xZeip=PtQy=a2CkD zKiAM`-j!c~R2a&E+*dj3*jx;1ek#Bzbpx>9=h}s}{e+b$+Br7-@n-t7rC^ze@ui~Lab~)2jsjcNR z5MDckDb2bcqvSR!R_G75I638tDJ&enOOOZ80t(bdjd|>8x`5*dnP_E=R@y%`Iy@A4x3kCi0sQXF*Q$c<#kv37k{wtBLc3 zh2{x9`|Yuy|2g)B7m`K>dI(d`#TAmwv08ROF50+>tepOKeM+rM%xhJ%eLs9_XzE&NI*+(|FrK8*w@)b{48q9qce#$N7<-r^V`E z`8xnc(DPWhV^7jZd)>NXdA51WlBT>PUJiT zWF_#(P&}|sft~EP$WTuSd%cn~7M{U?sfDd-i;yQc({(BJ1(%^ugY35ArKH}I?#JCz zQkv~T;c<^s&cU-ZqwPR{GA785iKJ%mZ#bp0Uge&x+b$zoJX1lzb1V9<;|+0IW0zfJ zB`v(?B%3-Fdy%T^z%5&U~}6k|U{gt>SU`Z!q7-+S}B2X+KVvMe8d+_*Bpo zuVRlAZMVY!hp8~Ig=LJd!J@0nUeNo}B{Li(=tS{ID2_&Jw}Tbbnh&%R^#SJ^oEJ-4 zdfW0^=b7#WlBL)<8`2AveseWOYlv;KDDv1$2BOZJ@h*W)CA-_(FhcstFyf7hd+4jpw z!c~x2B;?!i9hQG@J|J66rut;^V2b%&?cKR%vJ;}+?StRgx`2=9kjj`dDQ7VGi>!Cf z(ir6q#BO@d@Wv$R_qP?E*T(=fadw4RP%N9k11Z5TtUYnl({wXApnm4{?VuxGYPMyO zgxG#0K+(XS>0T4FBkT#?s!Ym<4?yA@i9!p+FO1i>Z(9+oY>*3#C&|jEd2HKX0cEh# z#YpctY`3){rz2Jnp93qZpl~2ZPst2euvp^b4wK4>oLsaJmW{n^4TX-Uo|fWm!U#f>YUKwvu+TP$s3%iO~pa zsAf!|YKj`(w!s-5D6G6giY%juYcsG8;Sctrq%LqDT5p}HoSj>2wUg@ zVvMi*SyUubAqaY&H`*#*_bweC1zfYQx;od^8E-}Cgh&mGcAOwnadaW)FZ6$zLb$M! zyt_2Op6GorG{oZNna=hhgTy~jxOV27t4$B;{aDAdW8`_deuxF~I=ztAMQb|5e)VMLTco`QqFR6XJ4yN|XPB~j1ZM*e37VbKR)3Gd$MhGuK+r{{L1SF=d z;NuCpzmc0QUbs5m*+UnBSL{tHcm-l)5Hom~ban*1%tvltJr0zBshLuCYM9$MaS{)E z1F1N7--+$;YuM%LOy0U!B=Jcf&-H#=dpNloGHln2JK+S5jv1Wax)I+QDc7Q^3?9 zl3?o29lYoxqw$@^o$qN^U^1*bv*{LQ&~HJusg{x6$2o^Fc#Lf%;YV6*QmIX*nQt(7 z*@yh1m%`hJboQfejJlZtx`6f6o?IpQ3HLgZR6$$No8;+)!)Uw~5*eb-VgjW1@4d{B zW5o%x)O~$2nwZUrWORp&$gk;bE3`Q90u!BTaZ+Ttbw(LID%5ic-25`7Vt5U1q{8l7 zG{15IX=4m$r^%Pc3Z!uFl1?k++#|&XdUNu2(NlfnO8&U_;Tg>Zx>Xns!Yn2Vi+-X| z-vMJ8{H0%X_RCr)U@J1LS>>I8=L>0jeCM zBrTQXg~DRu@QPGXj0NO9&|Blcb?8~#3l|pZwuC{+r=5c^Mo2d%C=p*f0*n9j0^Tb16WG>Ii){{=j{3kusI6y0_ij=?V;_h z-nPK_+Fr7cOdisKsGiY!BH$`CTJ3+63_TL33%3>ND*zNLg5H=L5_@{=g%MLMT@R2q3VSwHyY zgHH?Ro5$yL`kuqEPqNUZF2K`g{6uw{0e?8%X-acYu2y7lW?(^WXPt9(P_n+UI3!{H3yRZwXc zM1xrvgwY>K9qY+Md-jODdbNnQF@%Wxw!>{;GkTxFi^?|q zXvnYsZ~q8XY^OKcCQJC^2616N{8kkiW5qinYP TB^4g?AF_1uN{6&XA0PM+fB6@; diff --git a/cs/TagsCloudVisualization/Drawings/CloudTag_RandomSize.png b/cs/TagsCloudVisualization/Drawings/CloudTag_RandomSize.png index db32137ad91b3f1de7c89135175cd653f3e14960..26a5b0c10ed1f2d31f3cba3bacdc3ff6acfa7bca 100644 GIT binary patch literal 21008 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 literal 28138 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 Prx%}_G+sA$*7E-YJWmuD From eff096f8c74753aca232aa3d0cb75c354393040f Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Thu, 7 Dec 2023 02:09:19 +0500 Subject: [PATCH 08/21] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=20=D0=BD=D0=B0=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D1=83=20=D0=BF=D0=BB=D0=BE=D1=82?= =?UTF-8?q?=D0=BD=D0=BE=D1=81=D1=82=D0=B8=20=D0=B7=D0=B0=D0=BA=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D0=BA=D0=B8=20=D0=B8=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0?= =?UTF-8?q?=D0=B2=D0=B8=D0=BB=20=D0=BD=D0=B5=D0=B9=D0=BC=D1=81=D0=BF=D0=B5?= =?UTF-8?q?=D0=B9=D1=81=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 5 ++-- .../UnitTests/ArchimedeanSpiral_Should.cs | 3 ++- .../UnitTests/CircularCloudLayouter_Should.cs | 27 +++++++++++++++++-- .../UnitTests/TestDataArchimedeanSpiral.cs | 2 +- .../TestDataCircularCloudLayouter.cs | 2 +- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 1f6d2dc33..5504b2af8 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -6,6 +6,7 @@ public class CircularCloudLayouter(Point centerPoint) { private readonly List rectangles = new(); private readonly ArchimedeanSpiral spiral = new(centerPoint); + public Point CenterPoint { get; } = centerPoint; public Rectangle PutNextRectangle(Size rectangleSize) { @@ -14,7 +15,7 @@ public Rectangle PutNextRectangle(Size rectangleSize) while (true) { var nextPoint = spiral.GetNextPoint(); - var rectangle = new Rectangle(new Point(nextPoint.X - rectangleSize.Width / 2, nextPoint.Y - + var rectangle = new Rectangle(new Point(nextPoint.X - rectangleSize.Width / 2, nextPoint.Y - rectangleSize.Height / 2), rectangleSize); if (rectangles.Any(x => x.IntersectsWith(rectangle))) continue; rectangles.Add(rectangle); @@ -26,4 +27,4 @@ public Rectangle PutNextRectangle(Size rectangleSize) public IReadOnlyList GetRectangles() => rectangles.AsReadOnly(); } -} \ No newline at end of file +} diff --git a/cs/TagsCloudVisualizationTests/UnitTests/ArchimedeanSpiral_Should.cs b/cs/TagsCloudVisualizationTests/UnitTests/ArchimedeanSpiral_Should.cs index 50e7b51b4..709ffd368 100644 --- a/cs/TagsCloudVisualizationTests/UnitTests/ArchimedeanSpiral_Should.cs +++ b/cs/TagsCloudVisualizationTests/UnitTests/ArchimedeanSpiral_Should.cs @@ -1,8 +1,9 @@ using System.Drawing; using FluentAssertions; using NUnit.Framework; +using TagsCloudVisualization; -namespace TagsCloudVisualization.UnitTests +namespace TagsCloudVisualizationTests.UnitTests { [TestFixture] public class ArchimedeanSpiral_Should diff --git a/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs index b8a825deb..75c171d96 100644 --- a/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs @@ -1,8 +1,9 @@ using System.Drawing; using FluentAssertions; using NUnit.Framework; +using TagsCloudVisualization; -namespace TagsCloudVisualization.UnitTests +namespace TagsCloudVisualizationTests.UnitTests { class CircularCloudLayouter_Should { @@ -43,7 +44,7 @@ public void AddSeveralRectangles_Correctly() layouter.GetRectangles().Should().HaveCount(25).And.AllBeOfType(typeof(Rectangle)); } - + [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] public void AddSeveralRectangles_DoNotIntersect(Point point) { @@ -57,5 +58,27 @@ public void AddSeveralRectangles_DoNotIntersect(Point point) for (var i = 1; i < rectangles.Count; i++) rectangles.Skip(i).All(x => !rectangles[i - 1].IntersectsWith(x)).Should().Be(true); } + + [Test] + public void DensityTest() + { + var layouter = new CircularCloudLayouter(new Point()); + for (var i = 0; i < 200; i++) + layouter.PutNextRectangle(new Size(50, 50)); + var rectanglesSquare = 0; + var maxdX = 0; + var maxdY = 0; + foreach (var rectangle in layouter.GetRectangles()) + { + rectanglesSquare += rectangle.Width * rectangle.Height; + maxdX = Math.Max(maxdX, Math.Abs(rectangle.X) + rectangle.Width / 2 - layouter.CenterPoint.X); + maxdY = Math.Max(maxdY, Math.Abs(rectangle.Y) + rectangle.Height / 2 - layouter.CenterPoint.Y); + } + + var radius = Math.Max(maxdX, maxdY); + var circleSquare = Math.PI * radius * radius; + + (rectanglesSquare / circleSquare).Should().BeGreaterOrEqualTo(0.7); + } } } diff --git a/cs/TagsCloudVisualizationTests/UnitTests/TestDataArchimedeanSpiral.cs b/cs/TagsCloudVisualizationTests/UnitTests/TestDataArchimedeanSpiral.cs index f71c466bf..9097f4b70 100644 --- a/cs/TagsCloudVisualizationTests/UnitTests/TestDataArchimedeanSpiral.cs +++ b/cs/TagsCloudVisualizationTests/UnitTests/TestDataArchimedeanSpiral.cs @@ -1,7 +1,7 @@ using System.Drawing; using NUnit.Framework; -namespace TagsCloudVisualization.UnitTests +namespace TagsCloudVisualizationTests.UnitTests { public class TestDataArchimedeanSpiral { diff --git a/cs/TagsCloudVisualizationTests/UnitTests/TestDataCircularCloudLayouter.cs b/cs/TagsCloudVisualizationTests/UnitTests/TestDataCircularCloudLayouter.cs index e6be7369a..0ae999457 100644 --- a/cs/TagsCloudVisualizationTests/UnitTests/TestDataCircularCloudLayouter.cs +++ b/cs/TagsCloudVisualizationTests/UnitTests/TestDataCircularCloudLayouter.cs @@ -1,7 +1,7 @@ using System.Drawing; using NUnit.Framework; -namespace TagsCloudVisualization.UnitTests +namespace TagsCloudVisualizationTests.UnitTests { public class TestDataCircularCloudLayouter { From 44ae3828f2a7675bd58b0bee7a52859b57679b0a Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Fri, 8 Dec 2023 11:57:05 +0500 Subject: [PATCH 09/21] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=87=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=BA=D0=BE=D0=B4=D0=B0=20=D0=B8=20IDisposab?= =?UTF-8?q?le?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 18 +++++++++++------- cs/TagsCloudVisualization/Drawer.cs | 15 ++++++++------- cs/TagsCloudVisualization/Program.cs | 6 +++--- .../UnitTests/CircularCloudLayouter_Should.cs | 10 +++++----- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 5504b2af8..3b92be72b 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -4,19 +4,25 @@ namespace TagsCloudVisualization { public class CircularCloudLayouter(Point centerPoint) { - private readonly List rectangles = new(); - private readonly ArchimedeanSpiral spiral = new(centerPoint); public Point CenterPoint { get; } = centerPoint; + public IReadOnlyList Rectangles => rectangles.AsReadOnly(); + private readonly List rectangles = []; + private readonly ArchimedeanSpiral spiral = new(centerPoint); public Rectangle PutNextRectangle(Size rectangleSize) { if (rectangleSize.Height <= 0 || rectangleSize.Width <= 0) - throw new ArgumentException("rectangleSize with zero or negative height or width is prohibited!"); + throw new ArgumentException( + $"rectangleSize with zero or negative height or width is prohibited!", + "rectangleSize" + ); while (true) { var nextPoint = spiral.GetNextPoint(); - var rectangle = new Rectangle(new Point(nextPoint.X - rectangleSize.Width / 2, nextPoint.Y - - rectangleSize.Height / 2), rectangleSize); + var rectangle = new Rectangle( + new Point(nextPoint.X - rectangleSize.Width / 2, nextPoint.Y - rectangleSize.Height / 2), + rectangleSize + ); if (rectangles.Any(x => x.IntersectsWith(rectangle))) continue; rectangles.Add(rectangle); break; @@ -24,7 +30,5 @@ public Rectangle PutNextRectangle(Size rectangleSize) return rectangles[^1]; } - - public IReadOnlyList GetRectangles() => rectangles.AsReadOnly(); } } diff --git a/cs/TagsCloudVisualization/Drawer.cs b/cs/TagsCloudVisualization/Drawer.cs index 4fa9d5c7f..edb8abe85 100644 --- a/cs/TagsCloudVisualization/Drawer.cs +++ b/cs/TagsCloudVisualization/Drawer.cs @@ -7,15 +7,16 @@ public class Drawer public static Image GetImage(Point centerPoint, IEnumerable rectangles) { var image = new Bitmap(centerPoint.X * 2, centerPoint.Y * 2); - var gr = Graphics.FromImage(image); - gr.Clear(Color.Black); - using (var brush = new SolidBrush(Color.White)) + using (var gr = Graphics.FromImage(image)) { - foreach (var rectangle in rectangles) - gr.FillRectangle(brush, rectangle); + gr.Clear(Color.Black); + using (var brush = new SolidBrush(Color.White)) + { + foreach (var rectangle in rectangles) + gr.FillRectangle(brush, rectangle); + } } - - + return image; } } diff --git a/cs/TagsCloudVisualization/Program.cs b/cs/TagsCloudVisualization/Program.cs index 10cb9fa66..2ecde8780 100644 --- a/cs/TagsCloudVisualization/Program.cs +++ b/cs/TagsCloudVisualization/Program.cs @@ -26,7 +26,7 @@ private static Image DrawDecreasingSize() for (var i = 0; i < 200; i++) layouter.PutNextRectangle(new Size(40, 20)); - return Drawer.GetImage(new Point(340, 340), layouter.GetRectangles()); + return Drawer.GetImage(new Point(340, 340), layouter.Rectangles); } private static Image DrawSameSize() @@ -35,7 +35,7 @@ private static Image DrawSameSize() for (var i = 0; i < 200; i++) layouter.PutNextRectangle(new Size(30, 30)); - return Drawer.GetImage(new Point(340, 340), layouter.GetRectangles()); + return Drawer.GetImage(new Point(340, 340), layouter.Rectangles); } private static Image DrawRandomSize() @@ -45,7 +45,7 @@ private static Image DrawRandomSize() for (var i = 0; i < 200; i++) layouter.PutNextRectangle(new Size(rnd.Next(5, 50), rnd.Next(5, 50))); - return Drawer.GetImage(new Point(340, 340), layouter.GetRectangles()); + return Drawer.GetImage(new Point(340, 340), layouter.Rectangles); } } } diff --git a/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs index 75c171d96..7858499df 100644 --- a/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs @@ -20,7 +20,7 @@ public void Throw_WhenPutNewRectangle_WidthOrHeightLessEqualsZero(Size size) public void RectanglesEmpty_AfterCreation() { var layouter = new CircularCloudLayouter(new Point()); - layouter.GetRectangles().Should().BeEmpty(); + layouter.Rectangles.Should().BeEmpty(); } [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] @@ -28,7 +28,7 @@ public void Add_FirstRectangle_ToCenter(Point center) { var layouter = new CircularCloudLayouter(center); layouter.PutNextRectangle(new Size(10, 2)); - layouter.GetRectangles().Should().HaveCount(1) + layouter.Rectangles.Should().HaveCount(1) .And.BeEquivalentTo(new Rectangle( new Point(center.X - 10 / 2, center.Y - 2 / 2), new Size(10, 2))); } @@ -42,7 +42,7 @@ public void AddSeveralRectangles_Correctly() layouter.PutNextRectangle(new Size(i * 20, i * 10)); } - layouter.GetRectangles().Should().HaveCount(25).And.AllBeOfType(typeof(Rectangle)); + layouter.Rectangles.Should().HaveCount(25).And.AllBeOfType(typeof(Rectangle)); } [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] @@ -54,7 +54,7 @@ public void AddSeveralRectangles_DoNotIntersect(Point point) layouter.PutNextRectangle(new Size(i * 20, i * 10)); } - var rectangles = layouter.GetRectangles(); + var rectangles = layouter.Rectangles; for (var i = 1; i < rectangles.Count; i++) rectangles.Skip(i).All(x => !rectangles[i - 1].IntersectsWith(x)).Should().Be(true); } @@ -68,7 +68,7 @@ public void DensityTest() var rectanglesSquare = 0; var maxdX = 0; var maxdY = 0; - foreach (var rectangle in layouter.GetRectangles()) + foreach (var rectangle in layouter.Rectangles) { rectanglesSquare += rectangle.Width * rectangle.Height; maxdX = Math.Max(maxdX, Math.Abs(rectangle.X) + rectangle.Width / 2 - layouter.CenterPoint.X); From 796eb5a260eb4aaf49e0c9f97e8c62083329a253 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Fri, 8 Dec 2023 12:20:16 +0500 Subject: [PATCH 10/21] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20=D1=81?= =?UTF-8?q?=D0=BB=D0=BE=D0=B2=D0=B0=20=D0=B8=D0=B7=20=D0=BE=D0=B1=D1=89?= =?UTF-8?q?=D0=B5=D0=B3=D0=BE=20=D1=81=D0=BB=D0=BE=D0=B2=D0=B0=D1=80=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/tdd.sln.DotSettings | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cs/tdd.sln.DotSettings b/cs/tdd.sln.DotSettings index b179e7882..6179ffdca 100644 --- a/cs/tdd.sln.DotSettings +++ b/cs/tdd.sln.DotSettings @@ -81,5 +81,4 @@ public void SetUp() $END$ } - True - True \ No newline at end of file + \ No newline at end of file From aa61ae19a4b3636fbdfd1ef0370f77275784eca1 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Fri, 8 Dec 2023 12:41:10 +0500 Subject: [PATCH 11/21] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=87=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=BA=D0=BE=D0=B4=D0=B0=20=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=BE=D0=B2,=20=D0=B8=20=D1=81=D0=BE=D0=BE=D1=82=D0=BD?= =?UTF-8?q?=D0=BE=D1=88=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=BE=D0=BD=20=D0=BF=D1=80=D1=8F=D0=BC=D0=BE=D1=83=D0=B3=D0=BE?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2=20=D1=82=D0=B5=D0=B3?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Drawings/CloudTag_RandomSize.png | Bin 21008 -> 15233 bytes .../Drawings/CloudTag_SameSize.png | Bin 17024 -> 14756 bytes cs/TagsCloudVisualization/Program.cs | 9 +++-- .../UnitTests/CircularCloudLayouter_Should.cs | 31 ++++++++++-------- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/cs/TagsCloudVisualization/Drawings/CloudTag_RandomSize.png b/cs/TagsCloudVisualization/Drawings/CloudTag_RandomSize.png index 26a5b0c10ed1f2d31f3cba3bacdc3ff6acfa7bca..204862a53f26af325c2271c17f3258cda7c688c2 100644 GIT binary patch literal 15233 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 literal 21008 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 diff --git a/cs/TagsCloudVisualization/Drawings/CloudTag_SameSize.png b/cs/TagsCloudVisualization/Drawings/CloudTag_SameSize.png index 652e1a01f6862927e73341303872f380abf3eb34..0def998d3d3e10935678ebc19c468126cbb1f8f1 100644 GIT binary patch literal 14756 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 Date: Fri, 8 Dec 2023 12:54:05 +0500 Subject: [PATCH 12/21] =?UTF-8?q?=D0=97=D0=B0=D0=BF=D1=80=D0=B5=D1=82?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=82=D1=80=D0=B8=D1=86?= =?UTF-8?q?=D0=B0=D1=82=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D1=85=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B7=D0=BC=D0=B5=D1=80=D0=BE=D0=B2=20=D0=BA=D0=B0=D1=80=D1=82?= =?UTF-8?q?=D0=B8=D0=BD=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/Drawer.cs | 6 ++++-- cs/TagsCloudVisualization/Program.cs | 14 +++++++------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/cs/TagsCloudVisualization/Drawer.cs b/cs/TagsCloudVisualization/Drawer.cs index edb8abe85..60c7ab3d9 100644 --- a/cs/TagsCloudVisualization/Drawer.cs +++ b/cs/TagsCloudVisualization/Drawer.cs @@ -4,9 +4,11 @@ namespace TagsCloudVisualization { public class Drawer { - public static Image GetImage(Point centerPoint, IEnumerable rectangles) + public static Image GetImage(Size size, IEnumerable rectangles) { - var image = new Bitmap(centerPoint.X * 2, centerPoint.Y * 2); + if (size.Width <= 0 || size.Height <= 0) + throw new ArgumentException("size width and height should be positive", "size"); + var image = new Bitmap(size.Width, size.Height); using (var gr = Graphics.FromImage(image)) { gr.Clear(Color.Black); diff --git a/cs/TagsCloudVisualization/Program.cs b/cs/TagsCloudVisualization/Program.cs index 7e8f57b88..9016fad78 100644 --- a/cs/TagsCloudVisualization/Program.cs +++ b/cs/TagsCloudVisualization/Program.cs @@ -19,23 +19,23 @@ private static Image DrawDecreasingSize() { var layouter = new CircularCloudLayouter(new Point(340, 340)); layouter.PutNextRectangle(new Size(200, 80)); - + for (var i = 0; i < 20; i++) layouter.PutNextRectangle(new Size(80, 40)); - + for (var i = 0; i < 200; i++) layouter.PutNextRectangle(new Size(40, 20)); - - return Drawer.GetImage(new Point(340, 340), layouter.Rectangles); + + return Drawer.GetImage(new Size(340 * 2, 340 * 2), layouter.Rectangles); } private static Image DrawSameSize() { var layouter = new CircularCloudLayouter(new Point(340, 340)); - for (var i = 0; i < 200; i++) + for (var i = 0; i < 200; i++) layouter.PutNextRectangle(new Size(50, 25)); - return Drawer.GetImage(new Point(340, 340), layouter.Rectangles); + return Drawer.GetImage(new Size(340 * 2, 340 * 2), layouter.Rectangles); } private static Image DrawRandomSize() @@ -48,7 +48,7 @@ private static Image DrawRandomSize() layouter.PutNextRectangle(new Size(width, rnd.Next(width / 2 - 10, width / 2))); } - return Drawer.GetImage(new Point(340, 340), layouter.Rectangles); + return Drawer.GetImage(new Size(340 * 2, 340 * 2), layouter.Rectangles); } } } From 1e1caf0ce392f161b6a88bc7caef6c1a294854a6 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Fri, 8 Dec 2023 14:40:49 +0500 Subject: [PATCH 13/21] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B4=D0=BE=D0=BF=D0=BE=D0=BB=D0=BD=D0=B8=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D0=BE=D0=B5=20=D1=81=D0=BC=D0=B5=D1=89=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BA=20=D1=86=D0=B5=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D1=83=20=D0=B4=D0=BB=D1=8F=20=D1=83=D0=B2=D0=B5=D0=BB=D0=B8?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=BB=D0=BE=D1=82=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 48 +++++++++++++++++- .../Drawings/CloudTag_DecreasingSize.png | Bin 16276 -> 7454 bytes .../Drawings/CloudTag_RandomSize.png | Bin 15233 -> 9945 bytes .../Drawings/CloudTag_SameSize.png | Bin 14756 -> 6869 bytes .../UnitTests/CircularCloudLayouter_Should.cs | 4 +- 5 files changed, 48 insertions(+), 4 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 3b92be72b..8eeb34004 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -14,7 +14,7 @@ public Rectangle PutNextRectangle(Size rectangleSize) if (rectangleSize.Height <= 0 || rectangleSize.Width <= 0) throw new ArgumentException( $"rectangleSize with zero or negative height or width is prohibited!", - "rectangleSize" + nameof(rectangleSize) ); while (true) { @@ -23,12 +23,56 @@ public Rectangle PutNextRectangle(Size rectangleSize) new Point(nextPoint.X - rectangleSize.Width / 2, nextPoint.Y - rectangleSize.Height / 2), rectangleSize ); - if (rectangles.Any(x => x.IntersectsWith(rectangle))) continue; + if (CheckIfIntersectsWithOthers(rectangle)) continue; + rectangle = GetCloserToCenterRectangle(rectangle); rectangles.Add(rectangle); break; } return rectangles[^1]; } + + private bool CheckIfIntersectsWithOthers(Rectangle rectangle) => + rectangles.Any(x => x.IntersectsWith(rectangle)); + + private Rectangle GetCloserToCenterRectangle(Rectangle rectangle) + { + var direction = GetDirection(rectangle); + for (var i = 0; i < direction.Count; i++) + { + var newRectangle = GetMovedRectangle(rectangle, direction[i].X, direction[i].Y); + while (!CheckIfIntersectsWithOthers(newRectangle)) + { + if (CenterPoint.X - newRectangle.Size.Width / 2 == newRectangle.X + || CenterPoint.Y - newRectangle.Size.Height / 2 == newRectangle.Y) + break; + rectangle = newRectangle; + newRectangle = GetMovedRectangle(rectangle, direction[i].X, direction[i].Y); + } + } + + return rectangle; + } + + private List<(int X, int Y)> GetDirection(Rectangle rectangle) + { + var horizontalDiffer = CenterPoint.X - rectangle.Size.Width / 2 - rectangle.X; + var verticalDiffer = CenterPoint.Y - rectangle.Size.Height / 2 - rectangle.Y; + var directions = new List<(int X, int Y)>(); + if (horizontalDiffer != 0) + directions.Add((horizontalDiffer > 0 ? 1 : -1, 0)); + if (CenterPoint.Y - rectangle.Size.Height / 2 != rectangle.Y) + directions.Add((0, verticalDiffer > 0 ? 1 : -1)); + return directions; + } + + private static Rectangle GetMovedRectangle(Rectangle rectangle, int xDelta, int yDelta) => + new( + new Point( + rectangle.X + xDelta, + rectangle.Y + yDelta + ), + rectangle.Size + ); } } diff --git a/cs/TagsCloudVisualization/Drawings/CloudTag_DecreasingSize.png b/cs/TagsCloudVisualization/Drawings/CloudTag_DecreasingSize.png index f5a769dbd3bde6e330554b9e51b43dd2dec9abda..3abcb75b9c3c6de0d8beeb133542e0f31cc565d8 100644 GIT binary patch literal 7454 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 B?-2k1 diff --git a/cs/TagsCloudVisualization/Drawings/CloudTag_RandomSize.png b/cs/TagsCloudVisualization/Drawings/CloudTag_RandomSize.png index 204862a53f26af325c2271c17f3258cda7c688c2..eb89584d64619acd46cf9a944b0c300d005c9f2c 100644 GIT binary patch literal 9945 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 literal 15233 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 diff --git a/cs/TagsCloudVisualization/Drawings/CloudTag_SameSize.png b/cs/TagsCloudVisualization/Drawings/CloudTag_SameSize.png index 0def998d3d3e10935678ebc19c468126cbb1f8f1..448c38036feb2e42357ec0f1a2c2d8868f31326f 100644 GIT binary patch literal 6869 zcmeHMZA?>F7(RuTiCx*8ga$0xriC$ub|302qDv7h7Z9lo1f+Z@4%voSsHkCFZ4QrA$2jre#t$?bc0(*- zA7KM&e zBbuVyg1gZO8(oi=BhBGuEdF6dNFAJ4uHdSlf zPg1<$+ARy`oex?ob6Cml?UrYD71P!)kS-;TF5c%C7*AWHY>nbMrCFmGH*k$q!o+cH zEz;T|S1|qBdh3=Yj9nb0fEZV>@_WSkNnDD6hsv2d#sF(nOrW^t{&4m$U(-4w2<5#Z zYRWdLe1Hz-GaV;OF9@VE;;7ori!Mt?jS?_;T;13~F>rHV0z z2>Kd_GC!5gUIE}^uF5bez?0#a;Y;J+FQ;qY?I*8lC-@^M1FO`DIaScxaW>Ve%U9M7 z1q&Y$9y$=mj270Yr=f&wsXHoit*U+1YoW%S0InM2u*(5Ip4RfS-=Mj9MqSVMRs0{M ziICBiwx#)%8Xp&oF{^Kbd6%NfVTLSGH+G9uu6<2ivo_=7j|FmDjClEg?a}fEeuTWo z9jlz{Bn-@k(1Y67{l_a{*rQvKA zN`^GNOJ4zLxX8MX0cp6KrYAufZo!k`n4N9GmxjuKm(xGQ8r(|(;99Tdsm|cN@<|?< zJct4%Pc$by3`(9HG z-e0RUe@<6pM)b@W({wA+8&y;-ke%I#QHdF^;hy*dA4--mUtjc`Hhtpi|8J;1-(F8g vUckIykt^7#LL|4N@lA}szlSqfzxs@M9r@(KMV-roZAAejF)iUnd||_%1%oQP literal 14756 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 Date: Fri, 8 Dec 2023 14:53:21 +0500 Subject: [PATCH 14/21] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=20=D0=BD=D0=B0=20=D0=BF?= =?UTF-8?q?=D0=BB=D0=BE=D1=82=D0=BD=D0=BE=D1=81=D1=82=D1=8C,=20=D1=87?= =?UTF-8?q?=D1=82=D0=BE=D0=B1=D1=8B=20=D0=BE=D0=BA=D1=80=D1=83=D0=B6=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=8C=20=D0=BF=D0=BE=D0=BB=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=8C=D1=8E=20=D0=B2=D0=BA=D0=BB=D1=8E=D1=87=D0=B0=D0=BB?= =?UTF-8?q?=D0=B0=20=D0=B2=D1=81=D0=B5=20=D0=BF=D1=80=D1=8F=D0=BC=D0=BE?= =?UTF-8?q?=D1=83=D0=B3=D0=BE=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../UnitTests/CircularCloudLayouter_Should.cs | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs index 00197662d..f5915f100 100644 --- a/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs @@ -54,23 +54,20 @@ public void AddSeveralRectangles_DoNotIntersect(Point point) [Test] public void DensityTest() { - var layouter = new CircularCloudLayouter(new Point()); + var layouter = new CircularCloudLayouter(new Point(500, 500)); for (var i = 0; i < 2000; i++) layouter.PutNextRectangle(new Size(35, 15)); var rectanglesSquare = 0; - var maxdX = 0; - var maxdY = 0; + var radius = 0; foreach (var rectangle in layouter.Rectangles) { rectanglesSquare += rectangle.Width * rectangle.Height; - maxdX = Math.Max(maxdX, Math.Abs(rectangle.X) + rectangle.Width / 2 - layouter.CenterPoint.X); - maxdY = Math.Max(maxdY, Math.Abs(rectangle.Y) + rectangle.Height / 2 - layouter.CenterPoint.Y); + var x = Math.Abs(rectangle.X) + rectangle.Width / 2 - layouter.CenterPoint.X; + var y = Math.Abs(rectangle.Y) + rectangle.Height / 2 - layouter.CenterPoint.Y; + radius = Math.Max(radius, (int)Math.Sqrt(x * x + y * y)); } - - var radius = Math.Max(maxdX, maxdY); var circleSquare = Math.PI * radius * radius; - - (rectanglesSquare / circleSquare).Should().BeGreaterOrEqualTo(0.9); + (rectanglesSquare / circleSquare).Should().BeGreaterOrEqualTo(0.95); } private static CircularCloudLayouter CreateValidator_WithSeveralRectangles(int amount) From 29fd4d6b5639fb16962ec2e6feb492accd63f0a4 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Sun, 10 Dec 2023 20:00:43 +0500 Subject: [PATCH 15/21] =?UTF-8?q?=D0=9F=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=BB=20=D0=BD=D0=B5=D0=B9=D0=BC=D1=81=D0=BF=D0=B5=D0=B9=D1=81?= =?UTF-8?q?=D1=8B=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2,=20=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D1=81=D1=87=D1=91=D1=82=20=D1=80=D0=B0=D0=B4=D0=B8=D1=83?= =?UTF-8?q?=D1=81=D0=B0=20=D0=BE=D0=BA=D1=80=D1=83=D0=B6=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D0=B8=20=D0=B8=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BE=D1=82=D1=80=D0=B8=D1=81=D0=BE=D0=B2=D0=BA=D1=83?= =?UTF-8?q?=20=D1=83=D0=BF=D0=B0=D0=B2=D1=88=D0=B8=D1=85=20=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=B2=20=D0=B4=D0=BB=D1=8F=203=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=B4=D0=B0=D1=87=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ArchimedeanSpiral_Should.cs | 3 +- .../CircularCloudLayouter_Should.cs | 57 ++++++++++++------- .../TestDataArchimedeanSpiral.cs | 6 +- .../TestDataCircularCloudLayouter.cs | 2 +- 4 files changed, 44 insertions(+), 24 deletions(-) rename cs/TagsCloudVisualizationTests/{UnitTests => }/ArchimedeanSpiral_Should.cs (95%) rename cs/TagsCloudVisualizationTests/{UnitTests => }/CircularCloudLayouter_Should.cs (55%) rename cs/TagsCloudVisualizationTests/{UnitTests => }/TestDataArchimedeanSpiral.cs (84%) rename cs/TagsCloudVisualizationTests/{UnitTests => }/TestDataCircularCloudLayouter.cs (94%) diff --git a/cs/TagsCloudVisualizationTests/UnitTests/ArchimedeanSpiral_Should.cs b/cs/TagsCloudVisualizationTests/ArchimedeanSpiral_Should.cs similarity index 95% rename from cs/TagsCloudVisualizationTests/UnitTests/ArchimedeanSpiral_Should.cs rename to cs/TagsCloudVisualizationTests/ArchimedeanSpiral_Should.cs index 709ffd368..cfca29644 100644 --- a/cs/TagsCloudVisualizationTests/UnitTests/ArchimedeanSpiral_Should.cs +++ b/cs/TagsCloudVisualizationTests/ArchimedeanSpiral_Should.cs @@ -3,7 +3,8 @@ using NUnit.Framework; using TagsCloudVisualization; -namespace TagsCloudVisualizationTests.UnitTests + +namespace TagsCloudVisualizationTests { [TestFixture] public class ArchimedeanSpiral_Should diff --git a/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs similarity index 55% rename from cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs rename to cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs index f5915f100..d66598295 100644 --- a/cs/TagsCloudVisualizationTests/UnitTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs @@ -1,12 +1,32 @@ using System.Drawing; +using System.Reflection; using FluentAssertions; using NUnit.Framework; +using NUnit.Framework.Interfaces; using TagsCloudVisualization; -namespace TagsCloudVisualizationTests.UnitTests +namespace TagsCloudVisualizationTests { class CircularCloudLayouter_Should { + private static CircularCloudLayouter? layouter; + private string imagePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\FailedLayout.png"; + + [TearDown] + public void TagCloudVisualizerCircularCloudLayouterTearDown() + { + if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed && layouter is not null) + { + var failImage = Drawer.GetImage( + new Size(layouter.CenterPoint.X * 2, layouter.CenterPoint.Y * 2), layouter.Rectangles + ); + failImage.Save(imagePath); + Console.WriteLine($"Tag cloud visualization saved to file <{imagePath}>"); + } + + layouter = null; + } + [TestCaseSource(typeof(TestDataCircularCloudLayouter), nameof(TestDataCircularCloudLayouter.ZeroOrLessHeightOrWidth_Size))] public void Throw_WhenPutNewRectangle_WidthOrHeightLessEqualsZero(Size size) @@ -19,33 +39,32 @@ public void Throw_WhenPutNewRectangle_WidthOrHeightLessEqualsZero(Size size) [Test] public void RectanglesEmpty_AfterCreation() { - var layouter = new CircularCloudLayouter(new Point()); + layouter = new CircularCloudLayouter(new Point()); layouter.Rectangles.Should().BeEmpty(); } [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] public void Add_FirstRectangle_ToCenter(Point center) { - var layouter = new CircularCloudLayouter(center); + layouter = new CircularCloudLayouter(center); layouter.PutNextRectangle(new Size(10, 2)); layouter.Rectangles.Should().HaveCount(1) .And.BeEquivalentTo(new Rectangle( new Point(center.X - 10 / 2, center.Y - 2 / 2), new Size(10, 2))); } - [Test] - public void AddSeveralRectangles_Correctly() + [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] + public void AddSeveralRectangles_Correctly(Point centerPoint) { var amount = 25; - var layouter = CreateValidator_WithSeveralRectangles(amount); + layouter = CreateLayouter_With_SeveralRectangles(amount, centerPoint); layouter.Rectangles.Should().HaveCount(amount); } [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] - public void AddSeveralRectangles_DoNotIntersect(Point point) + public void AddSeveralRectangles_DoNotIntersect(Point centerPoint) { - var layouter = CreateValidator_WithSeveralRectangles(25); - + layouter = CreateLayouter_With_SeveralRectangles(25, centerPoint); var rectangles = layouter.Rectangles; for (var i = 1; i < rectangles.Count; i++) rectangles.Skip(i).All(x => !rectangles[i - 1].IntersectsWith(x)).Should().Be(true); @@ -54,31 +73,31 @@ public void AddSeveralRectangles_DoNotIntersect(Point point) [Test] public void DensityTest() { - var layouter = new CircularCloudLayouter(new Point(500, 500)); - for (var i = 0; i < 2000; i++) - layouter.PutNextRectangle(new Size(35, 15)); + layouter = CreateLayouter_With_SeveralRectangles(2000, new Point(960, 540)); var rectanglesSquare = 0; var radius = 0; foreach (var rectangle in layouter.Rectangles) { rectanglesSquare += rectangle.Width * rectangle.Height; - var x = Math.Abs(rectangle.X) + rectangle.Width / 2 - layouter.CenterPoint.X; - var y = Math.Abs(rectangle.Y) + rectangle.Height / 2 - layouter.CenterPoint.Y; + var x = Math.Abs(rectangle.X) + rectangle.Width - layouter.CenterPoint.X; + var y = Math.Abs(rectangle.Y) + rectangle.Height - layouter.CenterPoint.Y; radius = Math.Max(radius, (int)Math.Sqrt(x * x + y * y)); } + var circleSquare = Math.PI * radius * radius; - (rectanglesSquare / circleSquare).Should().BeGreaterOrEqualTo(0.95); + (rectanglesSquare / circleSquare).Should().BeGreaterOrEqualTo(0.8); } - private static CircularCloudLayouter CreateValidator_WithSeveralRectangles(int amount) + private static CircularCloudLayouter CreateLayouter_With_SeveralRectangles(int amount, Point center) { - var layouter = new CircularCloudLayouter(new Point()); + var newLayouter = new CircularCloudLayouter(center); + var width = new Random().Next(10, 50); for (var i = 1; i < amount + 1; i++) { - layouter.PutNextRectangle(new Size(i * 20, i * 10)); + newLayouter.PutNextRectangle(new Size(width, width / 5)); } - return layouter; + return newLayouter; } } } diff --git a/cs/TagsCloudVisualizationTests/UnitTests/TestDataArchimedeanSpiral.cs b/cs/TagsCloudVisualizationTests/TestDataArchimedeanSpiral.cs similarity index 84% rename from cs/TagsCloudVisualizationTests/UnitTests/TestDataArchimedeanSpiral.cs rename to cs/TagsCloudVisualizationTests/TestDataArchimedeanSpiral.cs index 9097f4b70..2d9ac2934 100644 --- a/cs/TagsCloudVisualizationTests/UnitTests/TestDataArchimedeanSpiral.cs +++ b/cs/TagsCloudVisualizationTests/TestDataArchimedeanSpiral.cs @@ -1,15 +1,15 @@ using System.Drawing; using NUnit.Framework; -namespace TagsCloudVisualizationTests.UnitTests +namespace TagsCloudVisualizationTests { public class TestDataArchimedeanSpiral { public static IEnumerable Different_CenterPoints() { - yield return new TestCaseData(new Point(0, 0)).SetName("(0, 0) center"); + yield return new TestCaseData(new Point(1, 1)).SetName("(1, 1) center"); yield return new TestCaseData(new Point(343, 868)).SetName("(343, 868) center"); - yield return new TestCaseData(new Point(-343, -868)).SetName("(-343, -868) center"); + yield return new TestCaseData(new Point(960, 540)).SetName("(960, 540) center"); } public static IEnumerable DifferentIterationsAdded_ExpectedPoints() diff --git a/cs/TagsCloudVisualizationTests/UnitTests/TestDataCircularCloudLayouter.cs b/cs/TagsCloudVisualizationTests/TestDataCircularCloudLayouter.cs similarity index 94% rename from cs/TagsCloudVisualizationTests/UnitTests/TestDataCircularCloudLayouter.cs rename to cs/TagsCloudVisualizationTests/TestDataCircularCloudLayouter.cs index 0ae999457..586060e43 100644 --- a/cs/TagsCloudVisualizationTests/UnitTests/TestDataCircularCloudLayouter.cs +++ b/cs/TagsCloudVisualizationTests/TestDataCircularCloudLayouter.cs @@ -1,7 +1,7 @@ using System.Drawing; using NUnit.Framework; -namespace TagsCloudVisualizationTests.UnitTests +namespace TagsCloudVisualizationTests { public class TestDataCircularCloudLayouter { From af7a46dac46ab0c38356cebfcf8fcfda41206ec6 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Sun, 10 Dec 2023 20:15:02 +0500 Subject: [PATCH 16/21] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D1=87=D0=B8?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=BA=D0=BE=D0=B4=D0=B0=20=D0=B8=20=D0=BE?= =?UTF-8?q?=D0=B1=D0=BB=D0=B0=D1=81=D1=82=D0=B8=20=D0=B2=D0=B8=D0=B4=D0=B8?= =?UTF-8?q?=D0=BC=D0=BE=D1=81=D1=82=D0=B8=20centralPoint?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 8eeb34004..d5511133b 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -2,12 +2,19 @@ namespace TagsCloudVisualization { - public class CircularCloudLayouter(Point centerPoint) + public class CircularCloudLayouter { - public Point CenterPoint { get; } = centerPoint; - public IReadOnlyList Rectangles => rectangles.AsReadOnly(); + private readonly ArchimedeanSpiral spiral; private readonly List rectangles = []; - private readonly ArchimedeanSpiral spiral = new(centerPoint); + + public IReadOnlyList Rectangles => rectangles.AsReadOnly(); + public Point CenterPoint { get; } + + public CircularCloudLayouter(Point centerPoint) + { + CenterPoint = centerPoint; + spiral = new ArchimedeanSpiral(centerPoint); + } public Rectangle PutNextRectangle(Size rectangleSize) { @@ -19,11 +26,9 @@ public Rectangle PutNextRectangle(Size rectangleSize) while (true) { var nextPoint = spiral.GetNextPoint(); - var rectangle = new Rectangle( - new Point(nextPoint.X - rectangleSize.Width / 2, nextPoint.Y - rectangleSize.Height / 2), - rectangleSize - ); - if (CheckIfIntersectsWithOthers(rectangle)) continue; + var newPoint = new Point(nextPoint.X - rectangleSize.Width / 2, nextPoint.Y - rectangleSize.Height / 2); + var rectangle = new Rectangle(newPoint, rectangleSize); + if (IsIntersectsWithOthers(rectangle)) continue; rectangle = GetCloserToCenterRectangle(rectangle); rectangles.Add(rectangle); break; @@ -32,7 +37,7 @@ public Rectangle PutNextRectangle(Size rectangleSize) return rectangles[^1]; } - private bool CheckIfIntersectsWithOthers(Rectangle rectangle) => + private bool IsIntersectsWithOthers(Rectangle rectangle) => rectangles.Any(x => x.IntersectsWith(rectangle)); private Rectangle GetCloserToCenterRectangle(Rectangle rectangle) @@ -41,7 +46,7 @@ private Rectangle GetCloserToCenterRectangle(Rectangle rectangle) for (var i = 0; i < direction.Count; i++) { var newRectangle = GetMovedRectangle(rectangle, direction[i].X, direction[i].Y); - while (!CheckIfIntersectsWithOthers(newRectangle)) + while (!IsIntersectsWithOthers(newRectangle)) { if (CenterPoint.X - newRectangle.Size.Width / 2 == newRectangle.X || CenterPoint.Y - newRectangle.Size.Height / 2 == newRectangle.Y) From 67fa44a0c3cb7bd94a7cde07ef3818b54d62d371 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Sun, 10 Dec 2023 20:24:23 +0500 Subject: [PATCH 17/21] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=20=D0=BD=D0=B0=20=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D1=83,=20=D1=87=D1=82=D0=BE=20?= =?UTF-8?q?=D1=86=D0=B5=D0=BD=D1=82=D1=80=20=D1=81=D0=BE=D1=85=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D1=8F=D0=B5=D1=82=D1=81=D1=8F=20=D0=BD=D0=B5=D0=B8=D0=B7?= =?UTF-8?q?=D0=BC=D0=B5=D0=BD=D0=BD=D1=8B=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter_Should.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs index d66598295..4ebbde6fc 100644 --- a/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs @@ -43,6 +43,13 @@ public void RectanglesEmpty_AfterCreation() layouter.Rectangles.Should().BeEmpty(); } + [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] + public void PutNextRectangle_DoesNotAffectCeterPoint(Point centerPoint) + { + layouter = CreateLayouter_With_SeveralRectangles(30, centerPoint); + layouter.CenterPoint.Should().BeEquivalentTo(centerPoint); + } + [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] public void Add_FirstRectangle_ToCenter(Point center) { From d0b74290570ec0cd73a1eaa1a1f7fccf97fe4f32 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Sun, 10 Dec 2023 20:27:59 +0500 Subject: [PATCH 18/21] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=81=D0=B4=D0=B2=D0=B8=D0=B3=20=D0=BF=D0=BE=20=D0=B4?= =?UTF-8?q?=D0=B8=D0=B0=D0=B3=D0=BE=D0=BD=D0=B0=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/CircularCloudLayouter.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index d5511133b..fb40b3578 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -64,9 +64,11 @@ private Rectangle GetCloserToCenterRectangle(Rectangle rectangle) var horizontalDiffer = CenterPoint.X - rectangle.Size.Width / 2 - rectangle.X; var verticalDiffer = CenterPoint.Y - rectangle.Size.Height / 2 - rectangle.Y; var directions = new List<(int X, int Y)>(); + if (horizontalDiffer != 0 && verticalDiffer != 0) + directions.Add((horizontalDiffer > 0 ? 1 : -1, verticalDiffer > 0 ? 1 : -1)); if (horizontalDiffer != 0) directions.Add((horizontalDiffer > 0 ? 1 : -1, 0)); - if (CenterPoint.Y - rectangle.Size.Height / 2 != rectangle.Y) + if (verticalDiffer != 0) directions.Add((0, verticalDiffer > 0 ? 1 : -1)); return directions; } From a3e8b1e522c32db6e93d8544f80294d59b69fafa Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Sun, 10 Dec 2023 20:42:41 +0500 Subject: [PATCH 19/21] =?UTF-8?q?=D0=A4=D0=B8=D0=BA=D1=81=20=D0=BB=D0=BE?= =?UTF-8?q?=D0=B3=D0=B8=D0=BA=D0=B8=20=D1=80=D0=B0=D1=81=D1=81=D1=87=D1=91?= =?UTF-8?q?=D1=82=D0=B0=20=D1=80=D0=B0=D0=B4=D0=B8=D1=83=D1=81=D0=B0=20?= =?UTF-8?q?=D0=BE=D0=BA=D1=80=D1=83=D0=B6=D0=BD=D0=BE=D1=81=D1=82=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter_Should.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs index 4ebbde6fc..c83c45249 100644 --- a/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs @@ -10,7 +10,9 @@ namespace TagsCloudVisualizationTests class CircularCloudLayouter_Should { private static CircularCloudLayouter? layouter; - private string imagePath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\FailedLayout.png"; + + private string imagePath = + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\FailedLayout.png"; [TearDown] public void TagCloudVisualizerCircularCloudLayouterTearDown() @@ -49,7 +51,7 @@ public void PutNextRectangle_DoesNotAffectCeterPoint(Point centerPoint) layouter = CreateLayouter_With_SeveralRectangles(30, centerPoint); layouter.CenterPoint.Should().BeEquivalentTo(centerPoint); } - + [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] public void Add_FirstRectangle_ToCenter(Point center) { @@ -86,8 +88,12 @@ public void DensityTest() foreach (var rectangle in layouter.Rectangles) { rectanglesSquare += rectangle.Width * rectangle.Height; - var x = Math.Abs(rectangle.X) + rectangle.Width - layouter.CenterPoint.X; - var y = Math.Abs(rectangle.Y) + rectangle.Height - layouter.CenterPoint.Y; + var x = Math.Abs(layouter.CenterPoint.X - rectangle.X); + if (rectangle.X > layouter.CenterPoint.X) + x += rectangle.Width; + var y = Math.Abs(layouter.CenterPoint.Y - rectangle.Y); + if (rectangle.Y > layouter.CenterPoint.Y) + y += rectangle.Height; radius = Math.Max(radius, (int)Math.Sqrt(x * x + y * y)); } From c373da451fbfb463158786e2582e5e992150fbf5 Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Mon, 11 Dec 2023 20:45:56 +0500 Subject: [PATCH 20/21] =?UTF-8?q?=D0=98=D1=81=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D1=83=20=D1=80?= =?UTF-8?q?=D0=B0=D1=81=D1=81=D1=87=D1=91=D1=82=D0=B0=20=D1=80=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D1=83=D1=81=D0=B0=20=D0=BE=D0=BA=D1=80=D1=83=D0=B6=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8,=20=D1=83=D0=B1=D1=80=D0=B0=D0=BB=20?= =?UTF-8?q?=D1=80=D0=B0=D0=BD=D0=B4=D0=BE=D0=BC=20=D0=B8=D0=B7=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=BE=D0=B2,=20=D0=B8=D1=81=D0=BF=D1=80?= =?UTF-8?q?=D0=B0=D0=B2=D0=B8=D0=BB=20=D1=87=D0=B8=D1=81=D1=82=D0=BE=D0=BA?= =?UTF-8?q?=D0=BE=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 8 +++--- .../CircularCloudLayouter_Should.cs | 28 ++++++++++--------- .../TestDataArchimedeanSpiral.cs | 2 +- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index fb40b3578..49670d559 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -42,17 +42,17 @@ private bool IsIntersectsWithOthers(Rectangle rectangle) => private Rectangle GetCloserToCenterRectangle(Rectangle rectangle) { - var direction = GetDirection(rectangle); - for (var i = 0; i < direction.Count; i++) + var directions = GetDirection(rectangle); + foreach (var direction in directions) { - var newRectangle = GetMovedRectangle(rectangle, direction[i].X, direction[i].Y); + var newRectangle = GetMovedRectangle(rectangle, direction.X, direction.Y); while (!IsIntersectsWithOthers(newRectangle)) { if (CenterPoint.X - newRectangle.Size.Width / 2 == newRectangle.X || CenterPoint.Y - newRectangle.Size.Height / 2 == newRectangle.Y) break; rectangle = newRectangle; - newRectangle = GetMovedRectangle(rectangle, direction[i].X, direction[i].Y); + newRectangle = GetMovedRectangle(rectangle, direction.X, direction.Y); } } diff --git a/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs index c83c45249..d65f7ec5d 100644 --- a/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs @@ -19,9 +19,7 @@ public void TagCloudVisualizerCircularCloudLayouterTearDown() { if (TestContext.CurrentContext.Result.Outcome.Status == TestStatus.Failed && layouter is not null) { - var failImage = Drawer.GetImage( - new Size(layouter.CenterPoint.X * 2, layouter.CenterPoint.Y * 2), layouter.Rectangles - ); + var failImage = Drawer.GetImage(new Size(1920, 1080), layouter.Rectangles); failImage.Save(imagePath); Console.WriteLine($"Tag cloud visualization saved to file <{imagePath}>"); } @@ -82,31 +80,35 @@ public void AddSeveralRectangles_DoNotIntersect(Point centerPoint) [Test] public void DensityTest() { - layouter = CreateLayouter_With_SeveralRectangles(2000, new Point(960, 540)); + layouter = CreateLayouter_With_SeveralRectangles(4000, new Point(960, 540)); var rectanglesSquare = 0; var radius = 0; foreach (var rectangle in layouter.Rectangles) { rectanglesSquare += rectangle.Width * rectangle.Height; - var x = Math.Abs(layouter.CenterPoint.X - rectangle.X); - if (rectangle.X > layouter.CenterPoint.X) - x += rectangle.Width; - var y = Math.Abs(layouter.CenterPoint.Y - rectangle.Y); - if (rectangle.Y > layouter.CenterPoint.Y) - y += rectangle.Height; + + var x = Math.Max( + Math.Abs(layouter.CenterPoint.X - rectangle.X), + rectangle.X + rectangle.Width - layouter.CenterPoint.X + ); + var y = Math.Max( + Math.Abs(layouter.CenterPoint.Y - rectangle.Y), + rectangle.Y + rectangle.Height - layouter.CenterPoint.Y + ); radius = Math.Max(radius, (int)Math.Sqrt(x * x + y * y)); } var circleSquare = Math.PI * radius * radius; - (rectanglesSquare / circleSquare).Should().BeGreaterOrEqualTo(0.8); + (rectanglesSquare / circleSquare).Should().BeGreaterOrEqualTo(0.75); } private static CircularCloudLayouter CreateLayouter_With_SeveralRectangles(int amount, Point center) { var newLayouter = new CircularCloudLayouter(center); - var width = new Random().Next(10, 50); - for (var i = 1; i < amount + 1; i++) + + for (var i = amount; i > 0; i--) { + var width = i % 40 + 10; newLayouter.PutNextRectangle(new Size(width, width / 5)); } diff --git a/cs/TagsCloudVisualizationTests/TestDataArchimedeanSpiral.cs b/cs/TagsCloudVisualizationTests/TestDataArchimedeanSpiral.cs index 2d9ac2934..9f1ca45a0 100644 --- a/cs/TagsCloudVisualizationTests/TestDataArchimedeanSpiral.cs +++ b/cs/TagsCloudVisualizationTests/TestDataArchimedeanSpiral.cs @@ -7,7 +7,7 @@ public class TestDataArchimedeanSpiral { public static IEnumerable Different_CenterPoints() { - yield return new TestCaseData(new Point(1, 1)).SetName("(1, 1) center"); + yield return new TestCaseData(new Point(0, 0)).SetName("(0, 0) center"); yield return new TestCaseData(new Point(343, 868)).SetName("(343, 868) center"); yield return new TestCaseData(new Point(960, 540)).SetName("(960, 540) center"); } From ae7ed6537b51a8ff9b1b0bdcbf48457b8bd6441f Mon Sep 17 00:00:00 2001 From: Crazy1beatch Date: Mon, 11 Dec 2023 21:01:53 +0500 Subject: [PATCH 21/21] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20=D1=81?= =?UTF-8?q?=D0=B2=D0=BE=D0=B9=D1=81=D1=82=D0=B2=D0=BE=20CentralPoint=20?= =?UTF-8?q?=D0=B8=D0=B7=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9?= =?UTF-8?q?=D1=81=D0=B0=20CircularCloudLayouter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 12 ++++++------ .../CircularCloudLayouter_Should.cs | 18 ++++++------------ 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 49670d559..bc65f56ff 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -6,13 +6,13 @@ public class CircularCloudLayouter { private readonly ArchimedeanSpiral spiral; private readonly List rectangles = []; + private readonly Point centerPoint; public IReadOnlyList Rectangles => rectangles.AsReadOnly(); - public Point CenterPoint { get; } public CircularCloudLayouter(Point centerPoint) { - CenterPoint = centerPoint; + this.centerPoint = centerPoint; spiral = new ArchimedeanSpiral(centerPoint); } @@ -48,8 +48,8 @@ private Rectangle GetCloserToCenterRectangle(Rectangle rectangle) var newRectangle = GetMovedRectangle(rectangle, direction.X, direction.Y); while (!IsIntersectsWithOthers(newRectangle)) { - if (CenterPoint.X - newRectangle.Size.Width / 2 == newRectangle.X - || CenterPoint.Y - newRectangle.Size.Height / 2 == newRectangle.Y) + if (centerPoint.X - newRectangle.Size.Width / 2 == newRectangle.X + || centerPoint.Y - newRectangle.Size.Height / 2 == newRectangle.Y) break; rectangle = newRectangle; newRectangle = GetMovedRectangle(rectangle, direction.X, direction.Y); @@ -61,8 +61,8 @@ private Rectangle GetCloserToCenterRectangle(Rectangle rectangle) private List<(int X, int Y)> GetDirection(Rectangle rectangle) { - var horizontalDiffer = CenterPoint.X - rectangle.Size.Width / 2 - rectangle.X; - var verticalDiffer = CenterPoint.Y - rectangle.Size.Height / 2 - rectangle.Y; + var horizontalDiffer = centerPoint.X - rectangle.Size.Width / 2 - rectangle.X; + var verticalDiffer = centerPoint.Y - rectangle.Size.Height / 2 - rectangle.Y; var directions = new List<(int X, int Y)>(); if (horizontalDiffer != 0 && verticalDiffer != 0) directions.Add((horizontalDiffer > 0 ? 1 : -1, verticalDiffer > 0 ? 1 : -1)); diff --git a/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs b/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs index d65f7ec5d..7e97b7769 100644 --- a/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs +++ b/cs/TagsCloudVisualizationTests/CircularCloudLayouter_Should.cs @@ -43,13 +43,6 @@ public void RectanglesEmpty_AfterCreation() layouter.Rectangles.Should().BeEmpty(); } - [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] - public void PutNextRectangle_DoesNotAffectCeterPoint(Point centerPoint) - { - layouter = CreateLayouter_With_SeveralRectangles(30, centerPoint); - layouter.CenterPoint.Should().BeEquivalentTo(centerPoint); - } - [TestCaseSource(typeof(TestDataArchimedeanSpiral), nameof(TestDataArchimedeanSpiral.Different_CenterPoints))] public void Add_FirstRectangle_ToCenter(Point center) { @@ -80,7 +73,8 @@ public void AddSeveralRectangles_DoNotIntersect(Point centerPoint) [Test] public void DensityTest() { - layouter = CreateLayouter_With_SeveralRectangles(4000, new Point(960, 540)); + var centerPoint = new Point(960, 540); + layouter = CreateLayouter_With_SeveralRectangles(4000, centerPoint); var rectanglesSquare = 0; var radius = 0; foreach (var rectangle in layouter.Rectangles) @@ -88,12 +82,12 @@ public void DensityTest() rectanglesSquare += rectangle.Width * rectangle.Height; var x = Math.Max( - Math.Abs(layouter.CenterPoint.X - rectangle.X), - rectangle.X + rectangle.Width - layouter.CenterPoint.X + Math.Abs(centerPoint.X - rectangle.X), + rectangle.X + rectangle.Width - centerPoint.X ); var y = Math.Max( - Math.Abs(layouter.CenterPoint.Y - rectangle.Y), - rectangle.Y + rectangle.Height - layouter.CenterPoint.Y + Math.Abs(centerPoint.Y - rectangle.Y), + rectangle.Y + rectangle.Height - centerPoint.Y ); radius = Math.Max(radius, (int)Math.Sqrt(x * x + y * y)); }