From 9590cf25fdd54639657a579b50d085cb2c021e7f Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 17:54:47 +0500 Subject: [PATCH 01/33] Create projects TagsCloudVisualization, Tests --- cs/TagsCloudVisualization/TagsCloudVisualization.csproj | 9 +++++++++ cs/Tests/Tests.csproj | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 cs/TagsCloudVisualization/TagsCloudVisualization.csproj create mode 100644 cs/Tests/Tests.csproj diff --git a/cs/TagsCloudVisualization/TagsCloudVisualization.csproj b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj new file mode 100644 index 000000000..3a6353295 --- /dev/null +++ b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + diff --git a/cs/Tests/Tests.csproj b/cs/Tests/Tests.csproj new file mode 100644 index 000000000..3a6353295 --- /dev/null +++ b/cs/Tests/Tests.csproj @@ -0,0 +1,9 @@ + + + + net8.0 + enable + enable + + + From ef5b9d0a0f422e70ff740ebdf7c602f445bb6ff5 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 18:00:12 +0500 Subject: [PATCH 02/33] Add tdd.sln, tdd.sln.DotSettings --- cs/tdd.sln | 12 ++++++++++++ cs/tdd.sln.DotSettings | 3 +++ 2 files changed, 15 insertions(+) diff --git a/cs/tdd.sln b/cs/tdd.sln index c8f523d63..918ebe748 100644 --- a/cs/tdd.sln +++ b/cs/tdd.sln @@ -7,6 +7,10 @@ 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", "{E344A7C8-C0E8-4231-BAAD-E2774B855CDF}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{86B722F4-6F6A-4773-B2E6-233B10DB7492}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +25,14 @@ 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 + {E344A7C8-C0E8-4231-BAAD-E2774B855CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E344A7C8-C0E8-4231-BAAD-E2774B855CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E344A7C8-C0E8-4231-BAAD-E2774B855CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E344A7C8-C0E8-4231-BAAD-E2774B855CDF}.Release|Any CPU.Build.0 = Release|Any CPU + {86B722F4-6F6A-4773-B2E6-233B10DB7492}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86B722F4-6F6A-4773-B2E6-233B10DB7492}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86B722F4-6F6A-4773-B2E6-233B10DB7492}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86B722F4-6F6A-4773-B2E6-233B10DB7492}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/cs/tdd.sln.DotSettings b/cs/tdd.sln.DotSettings index 135b83ecb..229f449d2 100644 --- a/cs/tdd.sln.DotSettings +++ b/cs/tdd.sln.DotSettings @@ -1,6 +1,9 @@  <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /> <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /> + <Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy> + <Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb_AaBb" /></Policy> + True True True Imported 10.10.2016 From c3361d06bb2f352879e5bbc11e0e1d2c39a1691d Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 18:06:50 +0500 Subject: [PATCH 03/33] Add ICircularCloudLayouter.cs, CircularCloudLayouter.cs --- cs/TagsCloudVisualization/CircularCloudLayouter.cs | 13 +++++++++++++ cs/TagsCloudVisualization/ICircularCloudLayouter.cs | 8 ++++++++ 2 files changed, 21 insertions(+) create mode 100644 cs/TagsCloudVisualization/CircularCloudLayouter.cs create mode 100644 cs/TagsCloudVisualization/ICircularCloudLayouter.cs diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs new file mode 100644 index 000000000..7c7d7a797 --- /dev/null +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -0,0 +1,13 @@ +using System.Drawing; + +namespace TagsCloudVisualization; + +public class CircularCloudLayouter +{ + private readonly Point center; + + public CircularCloudLayouter(Point center) + { + this.center = center; + } +} \ No newline at end of file diff --git a/cs/TagsCloudVisualization/ICircularCloudLayouter.cs b/cs/TagsCloudVisualization/ICircularCloudLayouter.cs new file mode 100644 index 000000000..106b0068c --- /dev/null +++ b/cs/TagsCloudVisualization/ICircularCloudLayouter.cs @@ -0,0 +1,8 @@ +using System.Drawing; + +namespace TagsCloudVisualization; + +public interface ICircularCloudLayouter +{ + Rectangle PutNextRectangle(Size rectangleSize); +} \ No newline at end of file From 9e42a7145e0c2b1f44ea20342f2abaff7e59637f Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 18:07:27 +0500 Subject: [PATCH 04/33] Add CircularCloudLayouterTests.cs --- cs/Tests/CircularCloudLayouterTests.cs | 8 ++++++++ cs/Tests/Tests.csproj | 4 ++++ 2 files changed, 12 insertions(+) create mode 100644 cs/Tests/CircularCloudLayouterTests.cs diff --git a/cs/Tests/CircularCloudLayouterTests.cs b/cs/Tests/CircularCloudLayouterTests.cs new file mode 100644 index 000000000..2808fa526 --- /dev/null +++ b/cs/Tests/CircularCloudLayouterTests.cs @@ -0,0 +1,8 @@ +using NUnit.Framework; + +namespace Tests; + +[TestFixture] +public class CircularCloudLayouterTests +{ +} \ No newline at end of file diff --git a/cs/Tests/Tests.csproj b/cs/Tests/Tests.csproj index 3a6353295..9cca92ad6 100644 --- a/cs/Tests/Tests.csproj +++ b/cs/Tests/Tests.csproj @@ -6,4 +6,8 @@ enable + + + + From bd1809c37157bd0fa52ac0f14f6196fd0b323710 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 19:21:36 +0500 Subject: [PATCH 05/33] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=B5=D1=80=D0=B2=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BF=D1=80=D1=8F=D0=BC=D0=BE=D1=83=D0=B3=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 12 +++++++++++- cs/Tests/CircularCloudLayouterTests.cs | 18 +++++++++++++++++- cs/Tests/Tests.csproj | 6 ++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 7c7d7a797..ed0ea987a 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -2,12 +2,22 @@ namespace TagsCloudVisualization; -public class CircularCloudLayouter +public class CircularCloudLayouter : ICircularCloudLayouter { private readonly Point center; + private readonly List addedRectangles; public CircularCloudLayouter(Point center) { this.center = center; + addedRectangles = new List(); + } + + public Rectangle PutNextRectangle(Size rectangleSize) + { + if (addedRectangles.Count == 0) + return new Rectangle(center, rectangleSize); + + return new Rectangle(new Point(center.X + 1, center.Y + 2), rectangleSize); } } \ No newline at end of file diff --git a/cs/Tests/CircularCloudLayouterTests.cs b/cs/Tests/CircularCloudLayouterTests.cs index 2808fa526..be16c977c 100644 --- a/cs/Tests/CircularCloudLayouterTests.cs +++ b/cs/Tests/CircularCloudLayouterTests.cs @@ -1,8 +1,24 @@ -using NUnit.Framework; +using System.Drawing; +using FluentAssertions; +using NUnit.Framework; +using TagsCloudVisualization; namespace Tests; [TestFixture] public class CircularCloudLayouterTests { + [TestCase(0, 0, 10, 15)] + [TestCase(2, 7, 5, 9)] + public void PutNextRectangle_ShouldRectangleInCenter_WhenAddFirstRectangle(int centerX, int centerY, + int rectangleWidth, int rectangleHeight) + { + var center = new Point(centerX, centerY); + var c = new CircularCloudLayouter(center); + var rectangleSize = new Size(rectangleWidth, rectangleHeight); + + var addedRectangle = c.PutNextRectangle(rectangleSize); + + addedRectangle.Location.Should().BeEquivalentTo(center); + } } \ No newline at end of file diff --git a/cs/Tests/Tests.csproj b/cs/Tests/Tests.csproj index 9cca92ad6..dd1db7c96 100644 --- a/cs/Tests/Tests.csproj +++ b/cs/Tests/Tests.csproj @@ -7,7 +7,13 @@ + + + + + + From 0747ad9370fb155f5d587efccb8728fee21a0ba1 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 19:58:16 +0500 Subject: [PATCH 06/33] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B2=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B2=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=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=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/CircularCloudLayouter.cs | 9 ++++++++- cs/Tests/CircularCloudLayouterTests.cs | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index ed0ea987a..e325d31b9 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -16,7 +16,14 @@ public CircularCloudLayouter(Point center) public Rectangle PutNextRectangle(Size rectangleSize) { if (addedRectangles.Count == 0) - return new Rectangle(center, rectangleSize); + { + var rectangleStartPoint = + new Point(center.X - rectangleSize.Width / 2, center.Y - rectangleSize.Height / 2); + var firstRectangle = new Rectangle(rectangleStartPoint, rectangleSize); + addedRectangles.Add(firstRectangle); + return firstRectangle; + } + return new Rectangle(new Point(center.X + 1, center.Y + 2), rectangleSize); } diff --git a/cs/Tests/CircularCloudLayouterTests.cs b/cs/Tests/CircularCloudLayouterTests.cs index be16c977c..8dca66f84 100644 --- a/cs/Tests/CircularCloudLayouterTests.cs +++ b/cs/Tests/CircularCloudLayouterTests.cs @@ -18,7 +18,8 @@ public void PutNextRectangle_ShouldRectangleInCenter_WhenAddFirstRectangle(int c var rectangleSize = new Size(rectangleWidth, rectangleHeight); var addedRectangle = c.PutNextRectangle(rectangleSize); + var expectedRectangleStartPoint = new Point(centerX - rectangleWidth / 2, centerY - rectangleHeight / 2); - addedRectangle.Location.Should().BeEquivalentTo(center); + addedRectangle.Location.Should().BeEquivalentTo(expectedRectangleStartPoint); } } \ No newline at end of file From f792052be25190c0325e05ac4062d4e5277159f2 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 21:04:46 +0500 Subject: [PATCH 07/33] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0?= =?UTF-8?q?=D1=86=D0=B8=D1=8F=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BD=D0=B5=D1=81=D0=BA=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=D0=BA=D0=B8=D1=85=20=D0=BF=D1=80=D1=8F=D0=BC=D0=BE=D1=83=D0=B3?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=BF=D0=BE?= =?UTF-8?q?=20=D1=81=D0=BF=D0=B8=D1=80=D0=B0=D0=BB=D0=B8=20=D1=81=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 29 ++++++++++++- cs/Tests/CircularCloudLayouterTests.cs | 42 ++++++++++++++++++- 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index e325d31b9..792fbdea7 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -6,6 +6,8 @@ public class CircularCloudLayouter : ICircularCloudLayouter { private readonly Point center; private readonly List addedRectangles; + private double currentAngleOfSpiral; + private double currentRadiusOfSpiral; public CircularCloudLayouter(Point center) { @@ -23,8 +25,33 @@ public Rectangle PutNextRectangle(Size rectangleSize) addedRectangles.Add(firstRectangle); return firstRectangle; } + + Rectangle rectangle; + + do + { + var x = center.X + (int)(currentRadiusOfSpiral * Math.Cos(currentAngleOfSpiral)) - rectangleSize.Width / 2; + var y = center.Y + (int)(currentRadiusOfSpiral * Math.Sin(currentAngleOfSpiral)) - rectangleSize.Height / 2; + rectangle = new Rectangle(new Point(x, y), rectangleSize); + + // увеличиваем угол на 1 градус + currentAngleOfSpiral += Math.PI / 180; + + // проверяем не прошли ли целый круг + if (currentAngleOfSpiral > 2 * Math.PI) + { + currentAngleOfSpiral = 0; + currentRadiusOfSpiral++; + } + } while (IntersectWithAddedRectangles(rectangle)); + addedRectangles.Add(rectangle); + + return rectangle; + } - return new Rectangle(new Point(center.X + 1, center.Y + 2), rectangleSize); + private bool IntersectWithAddedRectangles(Rectangle rectangle) + { + return addedRectangles.Any(addedRectangle => addedRectangle.IntersectsWith(rectangle)); } } \ No newline at end of file diff --git a/cs/Tests/CircularCloudLayouterTests.cs b/cs/Tests/CircularCloudLayouterTests.cs index 8dca66f84..818f41f09 100644 --- a/cs/Tests/CircularCloudLayouterTests.cs +++ b/cs/Tests/CircularCloudLayouterTests.cs @@ -14,12 +14,50 @@ public void PutNextRectangle_ShouldRectangleInCenter_WhenAddFirstRectangle(int c int rectangleWidth, int rectangleHeight) { var center = new Point(centerX, centerY); - var c = new CircularCloudLayouter(center); + var cloudLayouter = new CircularCloudLayouter(center); var rectangleSize = new Size(rectangleWidth, rectangleHeight); - var addedRectangle = c.PutNextRectangle(rectangleSize); + var addedRectangle = cloudLayouter.PutNextRectangle(rectangleSize); var expectedRectangleStartPoint = new Point(centerX - rectangleWidth / 2, centerY - rectangleHeight / 2); addedRectangle.Location.Should().BeEquivalentTo(expectedRectangleStartPoint); } + + [TestCase(10, 5, 15)] + [TestCase(50, 30, 100)] + [TestCase(100, 5, 50)] + public void PutNextRectangle_ShouldAddedRectanglesDoNotIntersect(int countRectangles, int minSideLength, + int maxSideLength) + { + var cloudLayouter = new CircularCloudLayouter(new Point(0, 0)); + var rectangleSizes = GetGeneratedRectangleSizes(countRectangles, minSideLength, maxSideLength); + var addedRectangles = new List(); + + addedRectangles.AddRange(rectangleSizes.Select(t => cloudLayouter.PutNextRectangle(t))); + + for (var i = 0; i < addedRectangles.Count-1; i++) + { + addedRectangles + .Skip(i + 1) + .Any(addedRectangle => addedRectangle.IntersectsWith(addedRectangles[i])) + .Should() + .BeFalse(); + } + } + + private static List GetGeneratedRectangleSizes(int countRectangles, int minSideLength, int maxSideLength) + { + var generatedSizes = new List(); + var random = new Random(); + + for (var i = 0; i < countRectangles; i++) + { + var rectangleSize = new Size(random.Next(minSideLength, maxSideLength), + random.Next(minSideLength, maxSideLength)); + + generatedSizes.Add(rectangleSize); + } + + return generatedSizes; + } } \ No newline at end of file From c17e0f927f54ade20591d7439f501f8d0b28ed16 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 21:12:02 +0500 Subject: [PATCH 08/33] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20=D0=BE?= =?UTF-8?q?=D1=82=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=83=D1=8E=20=D0=BB=D0=BE?= =?UTF-8?q?=D0=B3=D0=B8=D0=BA=D1=83=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=B5=D1=80=D0=B2=D0=BE=D0=B3?= =?UTF-8?q?=D0=BE=20=D0=BF=D1=80=D1=8F=D0=BC=D0=BE=D1=83=D0=B3=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D0=B8=D0=BA=D0=B0=20(=D0=B8=D0=B7=D0=BB=D0=B8?= =?UTF-8?q?=D1=88=D0=BD=D1=8F=D1=8F)=20=D0=A2=D0=B0=D0=BA=20=D0=BA=D0=B0?= =?UTF-8?q?=D0=BA=20=D0=B8=D0=B7=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D0=BE=20=D1=83=D0=B3=D0=BE=D0=BB=20=D0=B8=20=D1=80=D0=B0=D0=B4?= =?UTF-8?q?=D0=B8=D1=83=D1=81=20=D1=81=D0=BF=D0=B8=D1=80=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=20=D1=80=D0=B0=D0=B2=D0=BD=D1=8B=20=D0=BD=D1=83=D0=BB=D1=8E,?= =?UTF-8?q?=20=D1=82=D0=BE=20=D1=86=D0=B5=D0=BD=D1=82=D1=80=20=D0=B1=D1=83?= =?UTF-8?q?=D0=B4=D0=B5=D1=82=20=D0=B2=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=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/CircularCloudLayouter.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 792fbdea7..63706e2d2 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -17,15 +17,6 @@ public CircularCloudLayouter(Point center) public Rectangle PutNextRectangle(Size rectangleSize) { - if (addedRectangles.Count == 0) - { - var rectangleStartPoint = - new Point(center.X - rectangleSize.Width / 2, center.Y - rectangleSize.Height / 2); - var firstRectangle = new Rectangle(rectangleStartPoint, rectangleSize); - addedRectangles.Add(firstRectangle); - return firstRectangle; - } - Rectangle rectangle; do From 09efbed9aae411c217ad68afbafca573bf6a9391 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 23:07:34 +0500 Subject: [PATCH 09/33] =?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=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D0=BF=D0=BE=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D1=81=D0=BF=D0=B8=D1=80=D0=B0=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/Tests/CircularCloudLayouterTests.cs | 45 ++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/cs/Tests/CircularCloudLayouterTests.cs b/cs/Tests/CircularCloudLayouterTests.cs index 818f41f09..d6db9ae0e 100644 --- a/cs/Tests/CircularCloudLayouterTests.cs +++ b/cs/Tests/CircularCloudLayouterTests.cs @@ -44,6 +44,31 @@ public void PutNextRectangle_ShouldAddedRectanglesDoNotIntersect(int countRectan .BeFalse(); } } + + [TestCase(10, 5, 15)] + [TestCase(50, 30, 100)] + [TestCase(100, 5, 50)] + public void CircleShape_ShouldBeCloseToCircle_WhenAddMultipleRectangles(int countRectangles, int minSideLength, + int maxSideLength) + { + var center = new Point(0, 0); + var cloudLayouter = new CircularCloudLayouter(center); + var rectangleSizes = GetGeneratedRectangleSizes(countRectangles, minSideLength, maxSideLength); + var addedRectangles = new List(); + + addedRectangles.AddRange(rectangleSizes.Select(t => cloudLayouter.PutNextRectangle(t))); + + var distances = addedRectangles + .Select(rectangle => GetDistanceBetweenCenterRectangleAndCenterCloud(rectangle, center)) + .ToArray(); + + for (var i = 1; i < distances.Length; i++) + { + var distanceBetweenRectangles = GetDistanceBetweenRectangles(addedRectangles[i], addedRectangles[i - 1]); + distances[i].Should().BeApproximately(distances[i - 1], distanceBetweenRectangles); + } + } + private static List GetGeneratedRectangleSizes(int countRectangles, int minSideLength, int maxSideLength) { @@ -60,4 +85,24 @@ private static List GetGeneratedRectangleSizes(int countRectangles, int mi return generatedSizes; } + + private static double GetDistanceBetweenCenterRectangleAndCenterCloud(Rectangle rectangle, Point center) + { + var centerRectangle = new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2); + + return GetDistanceBetweenPoints(centerRectangle, center); + } + + private static double GetDistanceBetweenRectangles(Rectangle rectangle1, Rectangle rectangle2) + { + var centerRectangle1 = new Point(rectangle1.X + rectangle1.Width / 2, rectangle1.Y + rectangle1.Height / 2); + var centerRectangle2 = new Point(rectangle2.X + rectangle2.Width / 2, rectangle2.Y + rectangle2.Height / 2); + + return GetDistanceBetweenPoints(centerRectangle1, centerRectangle2); + } + + private static double GetDistanceBetweenPoints(Point point1, Point point2) + { + return Math.Sqrt(Math.Pow(point1.X - point2.X, 2) + Math.Pow(point1.Y - point2.Y, 2)); + } } \ No newline at end of file From 2b2988d5f7fba00deb682f5f2a13de7e0ae8d9ca Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 23:44:54 +0500 Subject: [PATCH 10/33] =?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=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B8=D0=B2=D1=88=D0=B5=D0=B3?= =?UTF-8?q?=D0=BE=D1=81=D1=8F=20=D1=80=D0=B5=D0=B7=D1=83=D0=BB=D1=8C=D1=82?= =?UTF-8?q?=D0=B0=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TagsCloudVisualization.csproj | 4 ++ .../VisualizationCircularCloudLayout.cs | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs diff --git a/cs/TagsCloudVisualization/TagsCloudVisualization.csproj b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj index 3a6353295..e37eb9cfb 100644 --- a/cs/TagsCloudVisualization/TagsCloudVisualization.csproj +++ b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj @@ -6,4 +6,8 @@ enable + + + + diff --git a/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs b/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs new file mode 100644 index 000000000..994e3327c --- /dev/null +++ b/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs @@ -0,0 +1,39 @@ +using System.Drawing; +using System.Drawing.Imaging; + +namespace TagsCloudVisualization; +#pragma warning disable CA1416 + +public class VisualizationCircularCloudLayout +{ + public static void DrawAndSaveLayout(List rectangles, string fileName, string filePath) + { + const int padding = 10; + var minX = rectangles.Min(rectangle => rectangle.Left); + var minY = rectangles.Min(rectangle => rectangle.Top); + var maxX = rectangles.Max(rectangle => rectangle.Right); + var maxY = rectangles.Max(rectangle => rectangle.Bottom); + var width = maxX - minX + padding * 2; + var height = maxY - minY + padding * 2; + + var random = new Random(); + + using var bitmap = new Bitmap(width, height); + using var graphics = Graphics.FromImage(bitmap); + + graphics.Clear(Color.White); + + foreach (var rectangle in rectangles) + { + var shiftedRectangle = rectangle with { X = rectangle.X - minX + padding, Y = rectangle.Y - minY + padding }; + + var randomColor = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); + + using var brush = new SolidBrush(randomColor); + graphics.FillRectangle(brush, shiftedRectangle); + graphics.DrawRectangle(Pens.Black, shiftedRectangle); + } + + bitmap.Save(Path.Combine(filePath, fileName), ImageFormat.Png); + } +} \ No newline at end of file From 5e32c1285e9201a8427b6c92cd4277afcb73793a Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 23:56:48 +0500 Subject: [PATCH 11/33] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B8=D0=B7=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B8=20README.md=20=D1=84=D0=B0=D0=B9=D0=BB=20?= =?UTF-8?q?=D1=81=20=D0=BD=D0=B8=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/README.md | 3 +++ .../TagsCloudVisualization.csproj | 4 ++++ .../images/visualization100Rectangles.png | Bin 0 -> 16597 bytes .../images/visualization10Rectangles.png | Bin 0 -> 432 bytes .../images/visualization50Rectangles.png | Bin 0 -> 22166 bytes 5 files changed, 7 insertions(+) create mode 100644 cs/TagsCloudVisualization/README.md create mode 100644 cs/TagsCloudVisualization/images/visualization100Rectangles.png create mode 100644 cs/TagsCloudVisualization/images/visualization10Rectangles.png create mode 100644 cs/TagsCloudVisualization/images/visualization50Rectangles.png diff --git a/cs/TagsCloudVisualization/README.md b/cs/TagsCloudVisualization/README.md new file mode 100644 index 000000000..fd7c9ced8 --- /dev/null +++ b/cs/TagsCloudVisualization/README.md @@ -0,0 +1,3 @@ +![Визуализация десяти прямоугольников]("images\visualization10Rectangles.png") +![Визуализация пятидесяти прямоугольников]("images\visualization50Rectangles.png") +![Визуализация ста прямоугольников]("images\visualization100Rectangles.png") \ No newline at end of file diff --git a/cs/TagsCloudVisualization/TagsCloudVisualization.csproj b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj index e37eb9cfb..21f20a861 100644 --- a/cs/TagsCloudVisualization/TagsCloudVisualization.csproj +++ b/cs/TagsCloudVisualization/TagsCloudVisualization.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/cs/TagsCloudVisualization/images/visualization100Rectangles.png b/cs/TagsCloudVisualization/images/visualization100Rectangles.png new file mode 100644 index 0000000000000000000000000000000000000000..dcab3fbea213961cb29d994efb90b53fb4b433cc GIT binary patch literal 16597 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 LJ9Uz@j-LMy%Bd-% literal 0 HcmV?d00001 diff --git a/cs/TagsCloudVisualization/images/visualization10Rectangles.png b/cs/TagsCloudVisualization/images/visualization10Rectangles.png new file mode 100644 index 0000000000000000000000000000000000000000..c4aad3df019fcedeafbdb425384267e078626c5a GIT binary patch literal 432 zcmeAS@N?(olHy`uVBq!ia0vp^c0laJ!3HGx6;uBKDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(eheoCO|{#S9F5he4R}c>anMpaxe@7srr_xVPum`Y}6-9R0YJC3IfXlJiZj zp{5BNB<`_=w>Gh_SjlvFwZaAOKIMn!?(nCji@mcvdB3Er?Dy$Ea^Vr z-F+zA^?6gYHgCGny0Evk`)?ZM>-H45x0uU4v~}CDxSqLx%aL7&uA4x74D$Te%70Av X7g=nQb$)393}psSS3j3^P6w literal 0 HcmV?d00001 diff --git a/cs/TagsCloudVisualization/images/visualization50Rectangles.png b/cs/TagsCloudVisualization/images/visualization50Rectangles.png new file mode 100644 index 0000000000000000000000000000000000000000..7c844e29c7e3bb682c3498188fceec780da05b5d GIT binary patch literal 22166 zcmeHPdpwj|+qP?$5;{pJm2wutlyn-lGb5)_q#VLXQ7N{ZO*^5GoF^$$G;)d}N)A&* z4a&|QTU3NlB7>Zn`PO>WplI*?y}$jw`}&-|Jq_Jm(DbG`Tng zIM~?OxU{v@aBOUIP~gva!F=#Z=#ZT*_~!>_oTds}`m@#V!GC_VQ`S{xW4nD}(Wuot z@c)I!wM?Da*tm<~-w%%+lkjY8#!}j9%DdexI&yWUc;D@=d-v?JF+%qWw2Xx)M7|kq?mzxySTO*pZyZ#NSyt8ev3#PRzg0C6NLpI zT*CUV1RrB{MT&#K$K=HDMs;|d5tSYfK2A=?yBUIyX}i(+;_!CKiQ7}o`E=I!=obD2 zzV>wAmm*qpmM}mXeBJW{9CEvuzD~88Ke18{+(_F7zeneLg}~9DQGdh9hc&i1Lla!| z;-XW|aiT~@MT<<{2jT2xavk<8w^~5G+H%o4-i*nh&>xeRkI;(>Mo;4s%0BMaee{sX zxi3WG;6wSCv^!RgRj-)!%qD`@&XN1#^5GqN)oQD~kehkUBBmB!3c;vYzfJ;RwR2B;OJ(n1;RdEq=G`K9cZ=tJ8y zviMZ}iI%t4RzJzyv1d8Ig`(zv^bqbYKXD!BdZutLDULxk|IpYD|u`fVvO?*5~vsb(Kx9m z-+XT%rsXfK^dI~3&`^j>z{?0e<=_qccUEVa?@$!WiY7^5NSyn9ZgonNjep%xRK9jh zpHXMS*Ai;I8rD9Yb=?pFPM6d87d^g59VN0)bE1Oe%7jX`hAWrLz07WQMmr4gxBp1J z)x!R=9%ny~--6dBQZ?{|Fl3y=V}xsd8yaMlL8f?fdQ5pteO&3I9oeUd2lP_U4Zps3#>4lCjpf6R@`_6VL zD!gX1`1CW3r6g4<_3U5_SEc}kMi0E)-)^Gr z9p0Gn$R2Y5nj{c8{epb<(8Tx|*zv&*RbS0FsWWQY(UTuHMGLwM^ucxl>=CFAIuZzCW0ppAM=+UUXM>F^=coX*c_SEBFS-a&%7>}h} z1l_;!#oDwSlPN3GPW3U#P=9T-;Npr_B+y?<0bzk!pum5Z&*J0tJ(Sd%_>U|DQae|C z7J}H|{hTP*s+5Lm2g3oLIS2iQgo`cDRrd!r+RE*d7w^(7mG&p@I9%P;o}J{$g4Eu# zgav!FWl_+pfOb@SoXUeVSrUFw>UN!l9LswxM0!swp^p%bGVL^Y9hiF)`(>0Loz1i- zTWLRj!5E3aSZl`J8Z|MT;wIK`C3IZ5eL%Z$g>($FLpEcQ#W9mD-e~XJUQVEOOLiCXhL@%VP7OVrRsdD-9a2H>&y9BCJFc6!u}$11AB#l7 z5zh@%MXf3#^$F02ik0EDW!aI%ryS6>+ccA#_kdJl@CpBN)wGd&pfI$;IGwzDKDpIN z$rb~Gk$Q6a7$3i~rP}I&E1{DzQh9xYE#_V#FuQZ_R4o(75Zy#2j3ngsmNAmST!GP3W@r8(;QIX2qU3CR3jKYWgpbO!g_LY?_i zo#G!J$^&IM@;H2oT&lgN?g7O)XX_&Bk(PZHg7dwIoW^yAzxz6H@L*~~M7{%F{&vnm z8UD0832E##(2asRQx%;oW)cSS$3>KIR+NLg3m@Gaz4x%D>Ed(<^p5E7_`IiG_DvrC zR#iym8Z)Cmg*Ej6S#TEUKLWb867hJ9l;!5Spg-5Q_!&c^z?EW^eV5#m{1GAn$ zaLb9kP&v*Hw`tgcdal?NSxwj=u-VV=`HN%1VD|~#?bbbwyWdnYbSNKgN6H%yJZYya z<+@Z3+%`WxzUXY~Oe>IO z5;_Qj#1`wadiNX7guVlYPk4AWZ1UcK-KkVfkA1{+XswGGHaftddXYmiUF+Y!vc&A= zK|_pXwvGc5S@MNWV zt)vQ*c5%KNebt4G_VS(YJl(qu(I?%~X~=RK->(15kXUcj_St3S|Mz)IJx=RA zlcoF;eR`9bhtAJmiV*La%%Hio7p0rRlzIQ;9p*Wzt7iZ7T6NQI2W|@3I#8 z5cw=YzIgnX?_ig=40COAgatFd7%Z5LeqTR1kf`(?4J3}X=Dl$}*9{Y?f%9NFp}lLr z|0eHe4c9@kM(d>`b$~Lu@5Y1Ch#{13JsLY!vpjxM~L`v#5}Adi>L>3NR^ zVQrAK?K;@2+6`Z(XoC{L_OdOPvB;N&akqPD_!AZ4LnSr_m)6ds=meucX7;_L3bsW~ ziIqdKz)emEFJ}d96Ez}mR4Bz{&`zA};=OHp~$egdnZd&K4at=JHn~~`n^vI7niS^ zsB9j_vumDz+zSeMZhP+WMo+0^XKmNfj}c$0jTZy8VJy*y#m2m#HLK;-~J$eP9l8FbA4XiY}9-aY&;TF|u)RBqg+zku3{ z8r8n2$yNQ01J8XExSr17O+RnUZcEcKg?MG8YSd_Q=HSI_t^0K*r~G}x%Z&BmY2KN` zj%vOzv%Nh32;s+_YwmGiW2^jBXuK=AmyFT$+@HJyuTZ#j)fQM)ui5CO2N}!0`fK*J z9deX%3Fs(Qur5Z1^!2Nh*!$_tyHm~Xph6kX=Ag%G6V<=E^C+UE&(9CO3C5~=8I0&a?`D3G)f2T~$^W!`eC_AlzFzxb$KDP{CWfGTO!Vf{cE}6e zFla|C5n0-y<RAixGjtoOVZKw^DI6>vGiY>e4RrG#VPU$Y zJq+LwvSsPlyqUZ@f8xB^;b2;w1h=i*A7d9;pty-tM$cR~P6~OUNg&(mp}DEM$f&ep z!r0xhpx=rHm7*GLm6J4~_Sma@rjL82(g<_(Wse9A6_fnQ&qeFn0bV}l4bWm=(5D3h zUiS$UwUA6+GiF5wGhx})EwJA>>FP4mKJfhEXTBLO?}1q`A#Gj_JVr|P8-@hF#Vx^8 zp|UMi5p=w!8W5TN<`O&)$~K??POki2$nUhNxLvi_bo0Z5VKQ$!v10dd(e~>GvWr^M zhQSk(pP7@i5Rov$-%mThBR87L7>u#K0X!TBuU+0l0$t6iAeHSqj+`{@OR@xkyXZrx z%EOJ3S?%C)7v3`-ARv7cMBl>D(KKC@4o?Jei~3-6Sqb9AFZwwddxN8e(*_riuvmnB*_AC?swQz1x z4F6ghf|*80Aits-mAqool=>>U*qgENWO;JD%QEzV%7!`$G)B3RM&D?85sQjn%cg&= zTyvV4yMfLOB`&o%H!wE5mg(K2;J#;np-yAtF+P*8)#jIOf+WxeuiqAAJQ@iPQwlT5 zZpq_W^U?o=$k$OnF0@Y+&eOqh4FAyb*+HjbisuAkJFk?P4Dw5l?uPtjT{;>JHH+%# zE}YxFRi#l#=E$#GoI*l$zA;u2>RV#p|by1xaqzkoa|GbB}(r;c46K8Ms2h3_{Mm$O-q zN^B0E(~NkpPoRNJKdulgg(OS&?6td6H3ypR9U=UHGf>KwBov*kMHC(BcDCvEb;Th!;6BhT!Gcql9jx1(;q-+&DEF*3E9cL{P zHi}X-U>3MV7d?D;J@-!J3_d_2ICR&Z;h)9^noK#^6CzrxaDTk0h9EnM)xmm~baePF z<}Yd1zh=cV4Grf|cas;>2&g#naoO#E(O{Zpqb>d*@1Gr7{_Y3VdS1)~bGgdC1-W~p zpYL;R=fe^(Af8Wnt?ue1?v8VSva%AlmG8=CVl;Hh?7*{7KxO#nvqC`<>i=|sx6uPp zAp9{{s*URxP!pZT13y=p?Xy2i$8C9Te|ZHV7O1ZmnwVO`WMnX|DM_s`D2CP8*HIxL znmk#jkl1cbf=es?ojE z501{?+!W#W))7RgU%hVb3g!;}%*z1+aL@Lwu926LHVPwVe>zrnbFhIL+Om@-3sc*= zn3PYy40n}e@o;O1JtdPlQRfHoLPIY>Cc5TobgYD_=fAP-n*a2G9eyOXh}w_{@>@Zy zlN7@hjo-Fdeix`;zbN*EnCNU!G}U5k0owEKb>#kTN`z3kdy*BbO2;$6WU&~X0|AWXhoRxd_(;vB8!8(}vscUp@anazq?}l{2 z%AQqnrAW!B{3ixQYFpo#wWs(DaRtA5up9_cahF{)M!kGtamvB?S{y9r*uNJfi+P_$ z!zxu#Yv!@M+$2`*@;M&mW&#w?pfwgmi&4AyV_|2@E9e2F&YZ|5m)7Tx<`LexK51ww zo8M^8T27pl=RtKt68>YVQNIbOCROWVzbJMY9nEjDWkDAfmR@UxLAaXLZjuTdhT~^a zV0l_q|8}CFqu$F@Ml5-NAm3INXKF|jiy3K;9E$?gUueJRM7^`CG>WSzZvq9A{))hO zMd~Y)8yy+I@PIoC?h{odI{nC!`Y09{xtVsxJbl`&h1+cjBA^7lUO=6Y--r{ozVvjK zS1Y41S@B8w=z(g95h3%Lko5 zB+^Xd0tEDDMl3I`afI19 zK&_5sM13$dtw4d&{C$CpKk;j(npe`j!P8>C_ZbffZTe*;`5)S9OGaUFUjM<`?Q5FU z_i;AB2fmUVz&*|8N|iFLMCc8RmEU-yH{EVf5j<$3Yz`lw=^A!FDMta7!i|CZd={e3 zQ{&JTQ#=43bmMNn1Rg)+P!} zuJ7yZu=YWS=py$G5xYG6yP%ykd0=vPI>~NjFRa}>GJ+ayC&gf{ze&>wn3&x~7uYZp zRs{;hM(S5s!`&XveJ~B8Ghc;PcUyY+mtl3%_&MT~y8PvozF~^9^?uH#) z1s|M=i3?DKwubKgzZtzW7*&k9<;C82hS`D|)4Y&K6Ji-j%f2y4kPr^Wb`8H0Db^9Q zUlrIO1}wN57s@%N9l2fj3v+z$_wz7OerF8do0IbJZtvBOs& zu84)@t_J#A{tRKPVE7mBDw}%-GKnfhNuSay&C&Tk$LCx_5a4cKNd1+hmaK||1Efrn zgMK#?r^Odl-Dr;i2e@ZfsD-2=Na`h`VTg;UT+Arv$^2V_`y7o}w$2UUja{ zziEJare#Nxn6N5g8JU|!?yKpT5~hxj)ozcPHW_}4?S>P0;@|1V&w>eKYZlB|X3mEB zKSVRhIcQ!|V8eBw!3`BBG-lMS^7^r-O8xA%Y-N|c*84;Nef8S(nBR6LahLW~;7|T^ zBaJH7qySPznS%3W!x<$u(={RtOZcY`+`^8?{J#EUXxw{!(+K@Xjxc#Rwr)+Bl)0KE zR*eQHslzAqKk?PzuUC;A`!N)4kP-@Gnu7&=qBp8>%+30e7akjJ8RRz%0{Kw$y<9p~ zi>%bp;mJZ*esrVhS)Ta^6F#S~kQ+zno8oza86j0RW)QQ&+JR9~kZ6YvhHSDQG|gNh z!C9dJvaM&B@pv|_&4Yv5>MAZ}*#L54lLS{^a#DFiZ!AIY*y&-I5)(Syk@=^;R0nCs z!@R9o+l$QnwYMG_3A7s-5|ORhVrXGzTdwGaC`P3GkQ&QG(3UxOV>9hWybRLYUJH}9 zZKboWhUA!pL(jQEU65mYp02iw1PNaMaFV{dIdW2<1lLj)*LEp*_ps6LZNBR%%rimb3vVR+Z_JQpWZ4>URYMai@?n0N=0ZeYcHuKV(K+^l! zbcnBvUkLsCe{@(>r#4`vm9*lDNr98UL>E%$#W5L0G311Z(6g91w`z&~Wx&iVjOVk- zLTYhV6!P(i!b-#oNd&Z6F88D>D@vDx-vN9LDD`;D_M{Vln3eq^bk-)cMoSH;Z1w>0YvXwey!HgPY{iPBK3pwDbK7&}hNILH;C?QL zeZgcKIGGicfeh@tm(HpZd5wNAHo|!A6aufnfNgpbr%Af6fGTJlRrbF!C_CmRv_%J* zU;%im$ixJ&TablOh|FANarS9AL}iW2XHp<*kb_;7Bb8j_4*!+bS&)G_0ZXP>0eeKV zCj3WGFxd72Jaqz?1YXn!d)2DsK$e?!o+(}G5XK_Gg*N{>772<~53RnXiWud7z%Pd8(i_XoYqIPb0$ zyK)wJ2@6h;f{oL~{-!IgIlX(*ccjD{y)QRz_Xz%;lOVZm!cyheGTdbR9Vd+E+&AA? zXmB@3Rf7MfS!F%jJ$-+v8s+mspt)<;kk?+Dxr)}=WPsI>s>xDd`-lX-4eXiL4y1eJ zbj)|j+Zq}EysWQ->l892jSsf^#=)7L^4Kh}{|bH5o$l$Z&1r&k)lBw;$)M1+I?Gl; zyzc5)pbG}=57GH|9@Cw;{8wg2y}nBGwRJmup|M4P6J;-zr<}}QPOn;1 zTrSUNK{Gz-i(4GsNXGaR9c1%?Zp_~_sz zqvj~rsLwO6B&QSeu%E38`a7oK1wVo@#F|TiDgWC0RHu6#t7w%Yv!A&*v!ZXAr4K({{inmBBTHS literal 0 HcmV?d00001 From 7aa664f98fe1a1ab2084debd7ad06e1ad22b44e4 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 23:57:52 +0500 Subject: [PATCH 12/33] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BF=D1=83=D1=82=D1=8C=20=D0=BA=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=D0=BC=20?= =?UTF-8?q?=D0=B2=20=D1=84=D0=B0=D0=B9=D0=BB=D0=B5=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cs/TagsCloudVisualization/README.md b/cs/TagsCloudVisualization/README.md index fd7c9ced8..4ccdb692f 100644 --- a/cs/TagsCloudVisualization/README.md +++ b/cs/TagsCloudVisualization/README.md @@ -1,3 +1,3 @@ -![Визуализация десяти прямоугольников]("images\visualization10Rectangles.png") -![Визуализация пятидесяти прямоугольников]("images\visualization50Rectangles.png") -![Визуализация ста прямоугольников]("images\visualization100Rectangles.png") \ No newline at end of file +![Визуализация десяти прямоугольников]("images/visualization10Rectangles.png") +![Визуализация пятидесяти прямоугольников]("images/visualization50Rectangles.png") +![Визуализация ста прямоугольников]("images/visualization100Rectangles.png") \ No newline at end of file From 42db42a78280fef182583d19bf08f141f0077420 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Tue, 12 Nov 2024 23:58:49 +0500 Subject: [PATCH 13/33] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cs/TagsCloudVisualization/README.md b/cs/TagsCloudVisualization/README.md index 4ccdb692f..dca4a86c1 100644 --- a/cs/TagsCloudVisualization/README.md +++ b/cs/TagsCloudVisualization/README.md @@ -1,3 +1,3 @@ -![Визуализация десяти прямоугольников]("images/visualization10Rectangles.png") -![Визуализация пятидесяти прямоугольников]("images/visualization50Rectangles.png") -![Визуализация ста прямоугольников]("images/visualization100Rectangles.png") \ No newline at end of file +![Визуализация десяти прямоугольников](images/visualization10Rectangles.png) +![Визуализация пятидесяти прямоугольников](images/visualization50Rectangles.png) +![Визуализация ста прямоугольников](images/visualization100Rectangles.png) \ No newline at end of file From 07fd1a3c39998468d5ae70c8b8fac9102b6fb8ac Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Wed, 13 Nov 2024 00:05:18 +0500 Subject: [PATCH 14/33] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20CircularCloudLayouterTests.cs,=20=D0=B4=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20Setup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/Tests/CircularCloudLayouterTests.cs | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/cs/Tests/CircularCloudLayouterTests.cs b/cs/Tests/CircularCloudLayouterTests.cs index d6db9ae0e..4b55fd554 100644 --- a/cs/Tests/CircularCloudLayouterTests.cs +++ b/cs/Tests/CircularCloudLayouterTests.cs @@ -8,17 +8,21 @@ namespace Tests; [TestFixture] public class CircularCloudLayouterTests { - [TestCase(0, 0, 10, 15)] - [TestCase(2, 7, 5, 9)] - public void PutNextRectangle_ShouldRectangleInCenter_WhenAddFirstRectangle(int centerX, int centerY, - int rectangleWidth, int rectangleHeight) + private ICircularCloudLayouter cloudLayouter; + + [SetUp] + public void Setup() + { + cloudLayouter = new CircularCloudLayouter(new Point(0, 0)); + } + + [Test] + public void PutNextRectangle_ShouldRectangleInCenter_WhenAddFirstRectangle() { - var center = new Point(centerX, centerY); - var cloudLayouter = new CircularCloudLayouter(center); - var rectangleSize = new Size(rectangleWidth, rectangleHeight); + var rectangleSize = new Size(10, 15); var addedRectangle = cloudLayouter.PutNextRectangle(rectangleSize); - var expectedRectangleStartPoint = new Point(centerX - rectangleWidth / 2, centerY - rectangleHeight / 2); + var expectedRectangleStartPoint = new Point(-addedRectangle.Width / 2, - addedRectangle.Height / 2); addedRectangle.Location.Should().BeEquivalentTo(expectedRectangleStartPoint); } @@ -29,7 +33,6 @@ public void PutNextRectangle_ShouldRectangleInCenter_WhenAddFirstRectangle(int c public void PutNextRectangle_ShouldAddedRectanglesDoNotIntersect(int countRectangles, int minSideLength, int maxSideLength) { - var cloudLayouter = new CircularCloudLayouter(new Point(0, 0)); var rectangleSizes = GetGeneratedRectangleSizes(countRectangles, minSideLength, maxSideLength); var addedRectangles = new List(); @@ -51,15 +54,13 @@ public void PutNextRectangle_ShouldAddedRectanglesDoNotIntersect(int countRectan public void CircleShape_ShouldBeCloseToCircle_WhenAddMultipleRectangles(int countRectangles, int minSideLength, int maxSideLength) { - var center = new Point(0, 0); - var cloudLayouter = new CircularCloudLayouter(center); var rectangleSizes = GetGeneratedRectangleSizes(countRectangles, minSideLength, maxSideLength); var addedRectangles = new List(); addedRectangles.AddRange(rectangleSizes.Select(t => cloudLayouter.PutNextRectangle(t))); var distances = addedRectangles - .Select(rectangle => GetDistanceBetweenCenterRectangleAndCenterCloud(rectangle, center)) + .Select(rectangle => GetDistanceBetweenCenterRectangleAndCenterCloud(rectangle, new Point(0, 0))) .ToArray(); for (var i = 1; i < distances.Length; i++) From 0bd26197703ece96d6e30583c00fe88dfa15268d Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Wed, 13 Nov 2024 00:20:50 +0500 Subject: [PATCH 15/33] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20TearDown=20=D1=81=20=D0=B2=D0=B8=D0=B7=D1=83=D0=B0?= =?UTF-8?q?=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D0=B5=D0=B9=20=D0=B8=D0=B7?= =?UTF-8?q?=D0=BE=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81?= =?UTF-8?q?=D0=BB=D0=BE=D0=BC=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20=D1=82=D0=B5?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/Tests/CircularCloudLayouterTests.cs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/cs/Tests/CircularCloudLayouterTests.cs b/cs/Tests/CircularCloudLayouterTests.cs index 4b55fd554..a72ec7243 100644 --- a/cs/Tests/CircularCloudLayouterTests.cs +++ b/cs/Tests/CircularCloudLayouterTests.cs @@ -1,6 +1,7 @@ using System.Drawing; using FluentAssertions; using NUnit.Framework; +using NUnit.Framework.Interfaces; using TagsCloudVisualization; namespace Tests; @@ -9,11 +10,34 @@ namespace Tests; public class CircularCloudLayouterTests { private ICircularCloudLayouter cloudLayouter; + private List addedRectangles; [SetUp] public void Setup() { cloudLayouter = new CircularCloudLayouter(new Point(0, 0)); + addedRectangles = []; + } + + [TearDown] + public void TearDown() + { + if (TestContext.CurrentContext.Result.Outcome.Status != TestStatus.Failed) + return; + + var pathImageStored = TestContext.CurrentContext.TestDirectory + @"\imageFailedTests"; + + if (!Directory.Exists(pathImageStored)) + { + Directory.CreateDirectory(pathImageStored); + } + + var testName = TestContext.CurrentContext.Test.Name; + + VisualizationCircularCloudLayout.DrawAndSaveLayout(addedRectangles, $"{testName}.png", + pathImageStored); + + Console.WriteLine($@"Tag cloud visualization saved to file {pathImageStored}\{testName}.png"); } [Test] @@ -34,7 +58,6 @@ public void PutNextRectangle_ShouldAddedRectanglesDoNotIntersect(int countRectan int maxSideLength) { var rectangleSizes = GetGeneratedRectangleSizes(countRectangles, minSideLength, maxSideLength); - var addedRectangles = new List(); addedRectangles.AddRange(rectangleSizes.Select(t => cloudLayouter.PutNextRectangle(t))); @@ -55,7 +78,6 @@ public void CircleShape_ShouldBeCloseToCircle_WhenAddMultipleRectangles(int coun int maxSideLength) { var rectangleSizes = GetGeneratedRectangleSizes(countRectangles, minSideLength, maxSideLength); - var addedRectangles = new List(); addedRectangles.AddRange(rectangleSizes.Select(t => cloudLayouter.PutNextRectangle(t))); From 2e4a6c9c9dea014fefb2164d3855e60a034b815b Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Wed, 13 Nov 2024 09:19:09 +0500 Subject: [PATCH 16/33] =?UTF-8?q?=D0=9F=D0=BE=D0=BF=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20=D1=81=20=D0=B2?= =?UTF-8?q?=D0=B8=D0=B7=D1=83=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs b/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs index 994e3327c..d971293d5 100644 --- a/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs +++ b/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs @@ -18,7 +18,7 @@ public static void DrawAndSaveLayout(List rectangles, string fileName var random = new Random(); - using var bitmap = new Bitmap(width, height); + var bitmap = new Bitmap(width, height); using var graphics = Graphics.FromImage(bitmap); graphics.Clear(Color.White); @@ -29,7 +29,7 @@ public static void DrawAndSaveLayout(List rectangles, string fileName var randomColor = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); - using var brush = new SolidBrush(randomColor); + var brush = new SolidBrush(randomColor); graphics.FillRectangle(brush, shiftedRectangle); graphics.DrawRectangle(Pens.Black, shiftedRectangle); } From f92ef27e8ebc084f68e2981a345cae247ae451ea Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sat, 16 Nov 2024 14:36:21 +0500 Subject: [PATCH 17/33] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81?= =?UTF-8?q?=20=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82=D0=BC=D0=B0=20?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D0=BA=D0=BB=D0=B0=D0=B4=D0=BA=D0=B8=20=D0=B8?= =?UTF-8?q?=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20=D1=80=D0=B0=D1=81=D0=BA?= =?UTF-8?q?=D0=BB=D0=B0=D0=B4=D0=BA=D0=B8=20=D0=BF=D0=BE=20=D0=BA=D1=80?= =?UTF-8?q?=D1=83=D0=B3=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularLayoutRectanglesAlgorithm.cs | 6 ++++++ .../ILayoutRectanglesAlgorithm.cs | 8 ++++++++ 2 files changed, 14 insertions(+) create mode 100644 cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs create mode 100644 cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs diff --git a/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs new file mode 100644 index 000000000..0415149ec --- /dev/null +++ b/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs @@ -0,0 +1,6 @@ +namespace TagsCloudVisualization.LayoutRectanglesAlgorithms; + +public class CircularLayoutRectanglesAlgorithm +{ + +} \ No newline at end of file diff --git a/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs new file mode 100644 index 000000000..03565887c --- /dev/null +++ b/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs @@ -0,0 +1,8 @@ +using System.Drawing; + +namespace TagsCloudVisualization.LayoutRectanglesAlgorithms; + +public interface ILayoutRectanglesAlgorithm +{ + Rectangle PutNextRectangle(Size rectangleSize, int center); +} \ No newline at end of file From 5c9d9b7bb8bdef1a9195738e7315437e6916833a Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sat, 16 Nov 2024 14:47:01 +0500 Subject: [PATCH 18/33] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D1=8E=20=D1=80=D0=B0=D1=81=D0=BA=D0=BB=D0=B0=D0=B4=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=BF=D0=BE=20=D0=BA=D1=80=D1=83=D0=B3=D1=83=20=D0=B2=20?= =?UTF-8?q?=D0=BD=D0=BE=D0=B2=D1=8B=D0=B9=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularLayoutRectanglesAlgorithm.cs | 41 ++++++++++++++++++- .../ILayoutRectanglesAlgorithm.cs | 2 +- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs index 0415149ec..c033f1c19 100644 --- a/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs +++ b/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs @@ -1,6 +1,43 @@ -namespace TagsCloudVisualization.LayoutRectanglesAlgorithms; +using System.Drawing; -public class CircularLayoutRectanglesAlgorithm +namespace TagsCloudVisualization.LayoutRectanglesAlgorithms; + +public class CircularLayoutRectanglesAlgorithm : ILayoutRectanglesAlgorithm { + private readonly List addedRectangles = []; + private double currentAngleOfCircle; + private double currentRadiusOfCircle; + private const double OneDegree = Math.PI / 180; + private const double FullCircleRotation = 2 * Math.PI; + + public Rectangle PutNextRectangle(Size rectangleSize, Point cloudCenter) + { + Rectangle rectangle; + + do + { + var x = cloudCenter.X + (int)(currentRadiusOfCircle * Math.Cos(currentAngleOfCircle)) - rectangleSize.Width / 2; + var y = cloudCenter.Y + (int)(currentRadiusOfCircle * Math.Sin(currentAngleOfCircle)) - rectangleSize.Height / 2; + rectangle = new Rectangle(new Point(x, y), rectangleSize); + + // увеличиваем угол на 1 градус + currentAngleOfCircle += OneDegree; + + // проверяем не прошли ли целый круг + if (currentAngleOfCircle > FullCircleRotation) + { + currentAngleOfCircle = 0; + currentRadiusOfCircle++; + } + } while (IntersectWithAddedRectangles(rectangle)); + + addedRectangles.Add(rectangle); + + return rectangle; + } + private bool IntersectWithAddedRectangles(Rectangle rectangle) + { + return addedRectangles.Any(addedRectangle => addedRectangle.IntersectsWith(rectangle)); + } } \ No newline at end of file diff --git a/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs index 03565887c..99fe7f23d 100644 --- a/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs +++ b/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs @@ -4,5 +4,5 @@ namespace TagsCloudVisualization.LayoutRectanglesAlgorithms; public interface ILayoutRectanglesAlgorithm { - Rectangle PutNextRectangle(Size rectangleSize, int center); + Rectangle PutNextRectangle(Size rectangleSize, Point cloudCenter); } \ No newline at end of file From 353a7f508693c6192f846cce59cb1351630046b8 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sat, 16 Nov 2024 14:52:54 +0500 Subject: [PATCH 19/33] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20CircularCloudLayouter?= =?UTF-8?q?=20=D0=B8=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D1=81=20=D0=BF?= =?UTF-8?q?=D0=BE=D1=8F=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC=20=D0=BD?= =?UTF-8?q?=D0=BE=D0=B2=D0=BE=D0=B3=D0=BE=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80?= =?UTF-8?q?=D1=84=D0=B5=D0=B9=D1=81=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouter.cs | 35 +++---------------- cs/Tests/CircularCloudLayouterTests.cs | 4 ++- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 63706e2d2..c1435092d 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -1,48 +1,23 @@ using System.Drawing; +using TagsCloudVisualization.LayoutRectanglesAlgorithms; namespace TagsCloudVisualization; public class CircularCloudLayouter : ICircularCloudLayouter { private readonly Point center; - private readonly List addedRectangles; - private double currentAngleOfSpiral; - private double currentRadiusOfSpiral; + private readonly ILayoutRectanglesAlgorithm layoutRectanglesAlgorithm; - public CircularCloudLayouter(Point center) + public CircularCloudLayouter(Point center, ILayoutRectanglesAlgorithm layoutRectanglesAlgorithm) { this.center = center; - addedRectangles = new List(); + this.layoutRectanglesAlgorithm = layoutRectanglesAlgorithm; } public Rectangle PutNextRectangle(Size rectangleSize) { - Rectangle rectangle; - - do - { - var x = center.X + (int)(currentRadiusOfSpiral * Math.Cos(currentAngleOfSpiral)) - rectangleSize.Width / 2; - var y = center.Y + (int)(currentRadiusOfSpiral * Math.Sin(currentAngleOfSpiral)) - rectangleSize.Height / 2; - rectangle = new Rectangle(new Point(x, y), rectangleSize); - - // увеличиваем угол на 1 градус - currentAngleOfSpiral += Math.PI / 180; - - // проверяем не прошли ли целый круг - if (currentAngleOfSpiral > 2 * Math.PI) - { - currentAngleOfSpiral = 0; - currentRadiusOfSpiral++; - } - } while (IntersectWithAddedRectangles(rectangle)); - - addedRectangles.Add(rectangle); + var rectangle = layoutRectanglesAlgorithm.PutNextRectangle(rectangleSize, center); return rectangle; } - - private bool IntersectWithAddedRectangles(Rectangle rectangle) - { - return addedRectangles.Any(addedRectangle => addedRectangle.IntersectsWith(rectangle)); - } } \ No newline at end of file diff --git a/cs/Tests/CircularCloudLayouterTests.cs b/cs/Tests/CircularCloudLayouterTests.cs index a72ec7243..9afc24db2 100644 --- a/cs/Tests/CircularCloudLayouterTests.cs +++ b/cs/Tests/CircularCloudLayouterTests.cs @@ -3,6 +3,7 @@ using NUnit.Framework; using NUnit.Framework.Interfaces; using TagsCloudVisualization; +using TagsCloudVisualization.LayoutRectanglesAlgorithms; namespace Tests; @@ -15,7 +16,8 @@ public class CircularCloudLayouterTests [SetUp] public void Setup() { - cloudLayouter = new CircularCloudLayouter(new Point(0, 0)); + var circularLayoutAlgorithm = new CircularLayoutRectanglesAlgorithm(); + cloudLayouter = new CircularCloudLayouter(new Point(0, 0), circularLayoutAlgorithm); addedRectangles = []; } From 21dfe5205dbb3e5d308352c088efc382cfba933a Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sat, 16 Nov 2024 15:05:54 +0500 Subject: [PATCH 20/33] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0=20=D1=81=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8,=20=D0=BA=D0=BB=D0=B0?= =?UTF-8?q?=D1=81=D1=81=D0=B0=20=D1=81=20=D1=82=D0=B5=D1=81=D1=82=D0=B0?= =?UTF-8?q?=D0=BC=D0=B8=20=D0=B8=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=B2=D0=BD=D1=83=D1=82=D1=80=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayouterTests.csproj} | 0 ...CircularLayoutRectanglesAlgorithmTests.cs} | 43 +++++++++---------- cs/tdd.sln | 2 +- 3 files changed, 21 insertions(+), 24 deletions(-) rename cs/{Tests/Tests.csproj => CircularCloudLayouterTests/CircularCloudLayouterTests.csproj} (100%) rename cs/{Tests/CircularCloudLayouterTests.cs => CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs} (69%) diff --git a/cs/Tests/Tests.csproj b/cs/CircularCloudLayouterTests/CircularCloudLayouterTests.csproj similarity index 100% rename from cs/Tests/Tests.csproj rename to cs/CircularCloudLayouterTests/CircularCloudLayouterTests.csproj diff --git a/cs/Tests/CircularCloudLayouterTests.cs b/cs/CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs similarity index 69% rename from cs/Tests/CircularCloudLayouterTests.cs rename to cs/CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs index 9afc24db2..f386c17fc 100644 --- a/cs/Tests/CircularCloudLayouterTests.cs +++ b/cs/CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs @@ -5,10 +5,10 @@ using TagsCloudVisualization; using TagsCloudVisualization.LayoutRectanglesAlgorithms; -namespace Tests; +namespace CircularCloudLayouterTests; [TestFixture] -public class CircularCloudLayouterTests +public class CircularLayoutRectanglesAlgorithmTests { private ICircularCloudLayouter cloudLayouter; private List addedRectangles; @@ -16,8 +16,7 @@ public class CircularCloudLayouterTests [SetUp] public void Setup() { - var circularLayoutAlgorithm = new CircularLayoutRectanglesAlgorithm(); - cloudLayouter = new CircularCloudLayouter(new Point(0, 0), circularLayoutAlgorithm); + cloudLayouter = new CircularCloudLayouter(new Point(0, 0), new CircularLayoutRectanglesAlgorithm()); addedRectangles = []; } @@ -59,7 +58,7 @@ public void PutNextRectangle_ShouldRectangleInCenter_WhenAddFirstRectangle() public void PutNextRectangle_ShouldAddedRectanglesDoNotIntersect(int countRectangles, int minSideLength, int maxSideLength) { - var rectangleSizes = GetGeneratedRectangleSizes(countRectangles, minSideLength, maxSideLength); + var rectangleSizes = GenerateRectangleSizes(countRectangles, minSideLength, maxSideLength); addedRectangles.AddRange(rectangleSizes.Select(t => cloudLayouter.PutNextRectangle(t))); @@ -79,54 +78,52 @@ public void PutNextRectangle_ShouldAddedRectanglesDoNotIntersect(int countRectan public void CircleShape_ShouldBeCloseToCircle_WhenAddMultipleRectangles(int countRectangles, int minSideLength, int maxSideLength) { - var rectangleSizes = GetGeneratedRectangleSizes(countRectangles, minSideLength, maxSideLength); + var rectangleSizes = GenerateRectangleSizes(countRectangles, minSideLength, maxSideLength); addedRectangles.AddRange(rectangleSizes.Select(t => cloudLayouter.PutNextRectangle(t))); var distances = addedRectangles - .Select(rectangle => GetDistanceBetweenCenterRectangleAndCenterCloud(rectangle, new Point(0, 0))) + .Select(rectangle => CalculateDistanceBetweenCenterRectangleAndCenterCloud(rectangle, new Point(0, 0))) .ToArray(); for (var i = 1; i < distances.Length; i++) { - var distanceBetweenRectangles = GetDistanceBetweenRectangles(addedRectangles[i], addedRectangles[i - 1]); + var distanceBetweenRectangles = CalculateDistanceBetweenRectangles(addedRectangles[i], addedRectangles[i - 1]); distances[i].Should().BeApproximately(distances[i - 1], distanceBetweenRectangles); } } - private static List GetGeneratedRectangleSizes(int countRectangles, int minSideLength, int maxSideLength) + private static List GenerateRectangleSizes(int countRectangles, int minSideLength, int maxSideLength) { - var generatedSizes = new List(); var random = new Random(); - - for (var i = 0; i < countRectangles; i++) - { - var rectangleSize = new Size(random.Next(minSideLength, maxSideLength), - random.Next(minSideLength, maxSideLength)); - - generatedSizes.Add(rectangleSize); - } + + var generatedSizes = Enumerable.Range(0, countRectangles) + .Select(_ => new Size( + random.Next(minSideLength, maxSideLength), + random.Next(minSideLength, maxSideLength)) + ) + .ToList(); return generatedSizes; } - private static double GetDistanceBetweenCenterRectangleAndCenterCloud(Rectangle rectangle, Point center) + private static double CalculateDistanceBetweenCenterRectangleAndCenterCloud(Rectangle rectangle, Point center) { var centerRectangle = new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2); - return GetDistanceBetweenPoints(centerRectangle, center); + return CalculateDistanceBetweenPoints(centerRectangle, center); } - private static double GetDistanceBetweenRectangles(Rectangle rectangle1, Rectangle rectangle2) + private static double CalculateDistanceBetweenRectangles(Rectangle rectangle1, Rectangle rectangle2) { var centerRectangle1 = new Point(rectangle1.X + rectangle1.Width / 2, rectangle1.Y + rectangle1.Height / 2); var centerRectangle2 = new Point(rectangle2.X + rectangle2.Width / 2, rectangle2.Y + rectangle2.Height / 2); - return GetDistanceBetweenPoints(centerRectangle1, centerRectangle2); + return CalculateDistanceBetweenPoints(centerRectangle1, centerRectangle2); } - private static double GetDistanceBetweenPoints(Point point1, Point point2) + private static double CalculateDistanceBetweenPoints(Point point1, Point point2) { return Math.Sqrt(Math.Pow(point1.X - point2.X, 2) + Math.Pow(point1.Y - point2.Y, 2)); } diff --git a/cs/tdd.sln b/cs/tdd.sln index 918ebe748..051249e8b 100644 --- a/cs/tdd.sln +++ b/cs/tdd.sln @@ -9,7 +9,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "Samples\Samples. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TagsCloudVisualization", "TagsCloudVisualization\TagsCloudVisualization.csproj", "{E344A7C8-C0E8-4231-BAAD-E2774B855CDF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "Tests\Tests.csproj", "{86B722F4-6F6A-4773-B2E6-233B10DB7492}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CircularCloudLayouterTests", "CircularCloudLayouterTests\CircularCloudLayouterTests.csproj", "{86B722F4-6F6A-4773-B2E6-233B10DB7492}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 66bfc9ec83e33b9960dcfcc3457904e4fc0065a9 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sat, 16 Nov 2024 15:15:29 +0500 Subject: [PATCH 21/33] =?UTF-8?q?=D0=A0=D0=B0=D0=B7=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BE=D1=82=D1=80=D0=B8=D1=81=D0=BE=D0=B2=D0=BA?= =?UTF-8?q?=D1=83=20=D0=B8=20=D1=81=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B8=D0=B7=D0=BE=D0=B1=D1=80=D0=B0=D0=B6?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularLayoutRectanglesAlgorithmTests.cs | 6 +++-- .../VisualizationCircularCloudLayout.cs | 22 +++++++++++++------ 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/cs/CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs b/cs/CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs index f386c17fc..fdc1a3b42 100644 --- a/cs/CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs +++ b/cs/CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs @@ -1,4 +1,5 @@ using System.Drawing; +using System.Drawing.Imaging; using FluentAssertions; using NUnit.Framework; using NUnit.Framework.Interfaces; @@ -35,9 +36,10 @@ public void TearDown() var testName = TestContext.CurrentContext.Test.Name; - VisualizationCircularCloudLayout.DrawAndSaveLayout(addedRectangles, $"{testName}.png", - pathImageStored); + var bitmap = VisualizationCircularCloudLayout.DrawLayout(addedRectangles, 10); + VisualizationCircularCloudLayout.SaveLayout(bitmap, pathImageStored, $"{testName}.png", ImageFormat.Png); + Console.WriteLine($@"Tag cloud visualization saved to file {pathImageStored}\{testName}.png"); } diff --git a/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs b/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs index d971293d5..1bef0febd 100644 --- a/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs +++ b/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs @@ -6,15 +6,14 @@ namespace TagsCloudVisualization; public class VisualizationCircularCloudLayout { - public static void DrawAndSaveLayout(List rectangles, string fileName, string filePath) + public static Bitmap DrawLayout(List rectangles, int paddingFromBorders) { - const int padding = 10; var minX = rectangles.Min(rectangle => rectangle.Left); var minY = rectangles.Min(rectangle => rectangle.Top); var maxX = rectangles.Max(rectangle => rectangle.Right); var maxY = rectangles.Max(rectangle => rectangle.Bottom); - var width = maxX - minX + padding * 2; - var height = maxY - minY + padding * 2; + var width = maxX - minX + paddingFromBorders; + var height = maxY - minY + paddingFromBorders; var random = new Random(); @@ -25,7 +24,11 @@ public static void DrawAndSaveLayout(List rectangles, string fileName foreach (var rectangle in rectangles) { - var shiftedRectangle = rectangle with { X = rectangle.X - minX + padding, Y = rectangle.Y - minY + padding }; + var shiftedRectangle = rectangle with + { + X = rectangle.X - minX + paddingFromBorders, + Y = rectangle.Y - minY + paddingFromBorders + }; var randomColor = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); @@ -33,7 +36,12 @@ public static void DrawAndSaveLayout(List rectangles, string fileName graphics.FillRectangle(brush, shiftedRectangle); graphics.DrawRectangle(Pens.Black, shiftedRectangle); } - - bitmap.Save(Path.Combine(filePath, fileName), ImageFormat.Png); + + return bitmap; + } + + public static void SaveLayout(Bitmap bitmap, string filePath, string fileName, ImageFormat imageFormat) + { + bitmap.Save(Path.Combine(filePath, fileName), imageFormat); } } \ No newline at end of file From 492bdc1cf5b2ebc7a39fc2e8021b636ffa84ed6a Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sat, 16 Nov 2024 15:19:37 +0500 Subject: [PATCH 22/33] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=D0=B0=20?= =?UTF-8?q?=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82=D0=BC=D0=BE=D0=B2=20?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D0=BA=D0=BB=D0=B0=D0=B4=D0=BA=D0=B8=20=D0=B8?= =?UTF-8?q?=20=D1=81=D0=BE=D0=BF=D1=83=D1=82=D1=81=D1=82=D0=B2=D1=83=D1=8E?= =?UTF-8?q?=D1=89=D0=B8=D1=85=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...> CircularLayoutRectanglesInCloudAlgorithmTests.cs} | 6 +++--- cs/TagsCloudVisualization/CircularCloudLayouter.cs | 10 +++++----- .../ILayoutRectanglesAlgorithm.cs | 8 -------- .../CircularLayoutRectanglesInCloudAlgorithm.cs} | 4 ++-- .../ILayoutRectanglesInCloudAlgorithm.cs | 8 ++++++++ 5 files changed, 18 insertions(+), 18 deletions(-) rename cs/CircularCloudLayouterTests/{CircularLayoutRectanglesAlgorithmTests.cs => CircularLayoutRectanglesInCloudAlgorithmTests.cs} (96%) delete mode 100644 cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs rename cs/TagsCloudVisualization/{LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs => LayoutRectanglesInCloudAlgorithms/CircularLayoutRectanglesInCloudAlgorithm.cs} (90%) create mode 100644 cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutRectanglesInCloudAlgorithm.cs diff --git a/cs/CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs b/cs/CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs similarity index 96% rename from cs/CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs rename to cs/CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs index fdc1a3b42..30e3d8189 100644 --- a/cs/CircularCloudLayouterTests/CircularLayoutRectanglesAlgorithmTests.cs +++ b/cs/CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs @@ -4,12 +4,12 @@ using NUnit.Framework; using NUnit.Framework.Interfaces; using TagsCloudVisualization; -using TagsCloudVisualization.LayoutRectanglesAlgorithms; +using TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; namespace CircularCloudLayouterTests; [TestFixture] -public class CircularLayoutRectanglesAlgorithmTests +public class CircularLayoutRectanglesInCloudAlgorithmTests { private ICircularCloudLayouter cloudLayouter; private List addedRectangles; @@ -17,7 +17,7 @@ public class CircularLayoutRectanglesAlgorithmTests [SetUp] public void Setup() { - cloudLayouter = new CircularCloudLayouter(new Point(0, 0), new CircularLayoutRectanglesAlgorithm()); + cloudLayouter = new CircularCloudLayouter(new Point(0, 0), new CircularLayoutRectanglesInCloudAlgorithm()); addedRectangles = []; } diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index c1435092d..5ad8df145 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -1,22 +1,22 @@ using System.Drawing; -using TagsCloudVisualization.LayoutRectanglesAlgorithms; +using TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; namespace TagsCloudVisualization; public class CircularCloudLayouter : ICircularCloudLayouter { private readonly Point center; - private readonly ILayoutRectanglesAlgorithm layoutRectanglesAlgorithm; + private readonly ILayoutRectanglesInCloudAlgorithm layoutRectanglesInCloudAlgorithm; - public CircularCloudLayouter(Point center, ILayoutRectanglesAlgorithm layoutRectanglesAlgorithm) + public CircularCloudLayouter(Point center, ILayoutRectanglesInCloudAlgorithm layoutRectanglesInCloudAlgorithm) { this.center = center; - this.layoutRectanglesAlgorithm = layoutRectanglesAlgorithm; + this.layoutRectanglesInCloudAlgorithm = layoutRectanglesInCloudAlgorithm; } public Rectangle PutNextRectangle(Size rectangleSize) { - var rectangle = layoutRectanglesAlgorithm.PutNextRectangle(rectangleSize, center); + var rectangle = layoutRectanglesInCloudAlgorithm.PutNextRectangle(rectangleSize, center); return rectangle; } diff --git a/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs deleted file mode 100644 index 99fe7f23d..000000000 --- a/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/ILayoutRectanglesAlgorithm.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Drawing; - -namespace TagsCloudVisualization.LayoutRectanglesAlgorithms; - -public interface ILayoutRectanglesAlgorithm -{ - Rectangle PutNextRectangle(Size rectangleSize, Point cloudCenter); -} \ No newline at end of file diff --git a/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutRectanglesInCloudAlgorithm.cs similarity index 90% rename from cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs rename to cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutRectanglesInCloudAlgorithm.cs index c033f1c19..435211059 100644 --- a/cs/TagsCloudVisualization/LayoutRectanglesAlgorithms/CircularLayoutRectanglesAlgorithm.cs +++ b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutRectanglesInCloudAlgorithm.cs @@ -1,8 +1,8 @@ using System.Drawing; -namespace TagsCloudVisualization.LayoutRectanglesAlgorithms; +namespace TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; -public class CircularLayoutRectanglesAlgorithm : ILayoutRectanglesAlgorithm +public class CircularLayoutRectanglesInCloudAlgorithm : ILayoutRectanglesInCloudAlgorithm { private readonly List addedRectangles = []; private double currentAngleOfCircle; diff --git a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutRectanglesInCloudAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutRectanglesInCloudAlgorithm.cs new file mode 100644 index 000000000..0d10f299a --- /dev/null +++ b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutRectanglesInCloudAlgorithm.cs @@ -0,0 +1,8 @@ +using System.Drawing; + +namespace TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; + +public interface ILayoutRectanglesInCloudAlgorithm +{ + Rectangle PutNextRectangle(Size rectangleSize, Point cloudCenter); +} \ No newline at end of file From 19ccfbfe136b4072b4b898827026ed43dd1f90e6 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sun, 17 Nov 2024 21:18:37 +0500 Subject: [PATCH 23/33] =?UTF-8?q?=D0=92=D1=8B=D0=BD=D0=B5=D1=81=20=D0=BB?= =?UTF-8?q?=D0=BE=D0=B3=D0=B8=D0=BA=D1=83=20=D0=B2=D1=8B=D1=87=D0=B8=D1=81?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D0=BB=D0=B5=D0=B4=D1=83?= =?UTF-8?q?=D1=8E=D1=89=D0=B5=D0=B9=20=D1=82=D0=BE=D1=87=D0=BA=D0=B8=20?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D0=BF=D0=BE=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...arLayoutRectanglesInCloudAlgorithmTests.cs | 2 +- .../CircularCloudLayouter.cs | 27 ++++++++++-- .../CircularLayoutAlgorithm.cs | 41 ++++++++++++++++++ ...ircularLayoutRectanglesInCloudAlgorithm.cs | 43 ------------------- .../ILayoutAlgorithm.cs | 8 ++++ .../ILayoutRectanglesInCloudAlgorithm.cs | 8 ---- 6 files changed, 73 insertions(+), 56 deletions(-) create mode 100644 cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs delete mode 100644 cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutRectanglesInCloudAlgorithm.cs create mode 100644 cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutAlgorithm.cs delete mode 100644 cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutRectanglesInCloudAlgorithm.cs diff --git a/cs/CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs b/cs/CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs index 30e3d8189..50c7fd6cf 100644 --- a/cs/CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs +++ b/cs/CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs @@ -17,7 +17,7 @@ public class CircularLayoutRectanglesInCloudAlgorithmTests [SetUp] public void Setup() { - cloudLayouter = new CircularCloudLayouter(new Point(0, 0), new CircularLayoutRectanglesInCloudAlgorithm()); + cloudLayouter = new CircularCloudLayouter(new Point(0, 0), new CircularLayoutAlgorithm()); addedRectangles = []; } diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 5ad8df145..71cc8d010 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -6,18 +6,37 @@ namespace TagsCloudVisualization; public class CircularCloudLayouter : ICircularCloudLayouter { private readonly Point center; - private readonly ILayoutRectanglesInCloudAlgorithm layoutRectanglesInCloudAlgorithm; + private readonly ILayoutAlgorithm layoutAlgorithm; + private readonly List addedRectangles = []; - public CircularCloudLayouter(Point center, ILayoutRectanglesInCloudAlgorithm layoutRectanglesInCloudAlgorithm) + public CircularCloudLayouter(Point center, ILayoutAlgorithm layoutAlgorithm) { this.center = center; - this.layoutRectanglesInCloudAlgorithm = layoutRectanglesInCloudAlgorithm; + this.layoutAlgorithm = layoutAlgorithm; } public Rectangle PutNextRectangle(Size rectangleSize) { - var rectangle = layoutRectanglesInCloudAlgorithm.PutNextRectangle(rectangleSize, center); + Rectangle rectangle; + + do + { + var nextPoint = layoutAlgorithm.CalculateNextPoint(); + + var x = center.X + nextPoint.X - rectangleSize.Width / 2; + var y = center.Y + nextPoint.Y - rectangleSize.Height / 2; + + rectangle = new Rectangle(new Point(x, y), rectangleSize); + + } while (IntersectWithAddedRectangles(rectangle)); + addedRectangles.Add(rectangle); + return rectangle; } + + private bool IntersectWithAddedRectangles(Rectangle rectangle) + { + return addedRectangles.Any(addedRectangle => addedRectangle.IntersectsWith(rectangle)); + } } \ No newline at end of file diff --git a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs new file mode 100644 index 000000000..c28647c1a --- /dev/null +++ b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs @@ -0,0 +1,41 @@ +using System.Drawing; + +namespace TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; + +public class CircularLayoutAlgorithm : ILayoutAlgorithm +{ + private readonly double stepIncreasingAngle; + private readonly double stepIncreasingRadius; + private double currentAngleOfCircle; + private double currentRadiusOfCircle; + private const double OneDegree = Math.PI / 180; + private const double FullCircleRotation = 2 * Math.PI; + + public CircularLayoutAlgorithm(double stepIncreasingAngle = OneDegree, double stepIncreasingRadius = 1) + { + if (stepIncreasingAngle <= 0) + throw new ArgumentException("The parameter 'stepIncreasingAngle' is less than or equal to zero"); + if (stepIncreasingRadius <= 0) + throw new ArgumentException("The parameter 'stepIncreasingRadius' is less than or equal to zero"); + + this.stepIncreasingAngle = stepIncreasingAngle; + this.stepIncreasingRadius = stepIncreasingRadius; + } + + public Point CalculateNextPoint() + { + var x = (int)(currentRadiusOfCircle * Math.Cos(currentAngleOfCircle)); + var y = (int)(currentRadiusOfCircle * Math.Sin(currentAngleOfCircle)); + + currentAngleOfCircle += stepIncreasingAngle; + + // проверяем не прошли ли целый круг + if (currentAngleOfCircle > FullCircleRotation) + { + currentAngleOfCircle = 0; + currentRadiusOfCircle += stepIncreasingRadius; + } + + return new Point(x, y); + } +} \ No newline at end of file diff --git a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutRectanglesInCloudAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutRectanglesInCloudAlgorithm.cs deleted file mode 100644 index 435211059..000000000 --- a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutRectanglesInCloudAlgorithm.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System.Drawing; - -namespace TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; - -public class CircularLayoutRectanglesInCloudAlgorithm : ILayoutRectanglesInCloudAlgorithm -{ - private readonly List addedRectangles = []; - private double currentAngleOfCircle; - private double currentRadiusOfCircle; - private const double OneDegree = Math.PI / 180; - private const double FullCircleRotation = 2 * Math.PI; - - public Rectangle PutNextRectangle(Size rectangleSize, Point cloudCenter) - { - Rectangle rectangle; - - do - { - var x = cloudCenter.X + (int)(currentRadiusOfCircle * Math.Cos(currentAngleOfCircle)) - rectangleSize.Width / 2; - var y = cloudCenter.Y + (int)(currentRadiusOfCircle * Math.Sin(currentAngleOfCircle)) - rectangleSize.Height / 2; - rectangle = new Rectangle(new Point(x, y), rectangleSize); - - // увеличиваем угол на 1 градус - currentAngleOfCircle += OneDegree; - - // проверяем не прошли ли целый круг - if (currentAngleOfCircle > FullCircleRotation) - { - currentAngleOfCircle = 0; - currentRadiusOfCircle++; - } - } while (IntersectWithAddedRectangles(rectangle)); - - addedRectangles.Add(rectangle); - - return rectangle; - } - - private bool IntersectWithAddedRectangles(Rectangle rectangle) - { - return addedRectangles.Any(addedRectangle => addedRectangle.IntersectsWith(rectangle)); - } -} \ No newline at end of file diff --git a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutAlgorithm.cs new file mode 100644 index 000000000..55c4c2804 --- /dev/null +++ b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutAlgorithm.cs @@ -0,0 +1,8 @@ +using System.Drawing; + +namespace TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; + +public interface ILayoutAlgorithm +{ + Point CalculateNextPoint(); +} \ No newline at end of file diff --git a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutRectanglesInCloudAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutRectanglesInCloudAlgorithm.cs deleted file mode 100644 index 0d10f299a..000000000 --- a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/ILayoutRectanglesInCloudAlgorithm.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System.Drawing; - -namespace TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; - -public interface ILayoutRectanglesInCloudAlgorithm -{ - Rectangle PutNextRectangle(Size rectangleSize, Point cloudCenter); -} \ No newline at end of file From ad8646b64a2bd80c61d6c8728877f5c7efe4e57e Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sun, 17 Nov 2024 21:33:46 +0500 Subject: [PATCH 24/33] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BE=D0=B3=D1=80=D0=B0=D0=BD=D0=B8=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=81=D1=82=D1=80?= =?UTF-8?q?=D1=83=D0=BA=D1=82=D0=BE=D1=80=D0=B5=20=D0=B0=D0=BB=D0=B3=D0=BE?= =?UTF-8?q?=D1=80=D0=B8=D1=82=D0=BC=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularLayoutAlgorithm.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs index c28647c1a..17f17fa39 100644 --- a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs +++ b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs @@ -15,8 +15,8 @@ public CircularLayoutAlgorithm(double stepIncreasingAngle = OneDegree, double st { if (stepIncreasingAngle <= 0) throw new ArgumentException("The parameter 'stepIncreasingAngle' is less than or equal to zero"); - if (stepIncreasingRadius <= 0) - throw new ArgumentException("The parameter 'stepIncreasingRadius' is less than or equal to zero"); + if (stepIncreasingRadius == 0) + throw new ArgumentException("The parameter 'stepIncreasingRadius' is zero"); this.stepIncreasingAngle = stepIncreasingAngle; this.stepIncreasingRadius = stepIncreasingRadius; From e736a26ea2cab3fde5e15747c141851b7ca667f9 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sun, 17 Nov 2024 22:48:47 +0500 Subject: [PATCH 25/33] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=80=D0=B0=D0=B4=D0=B8=D1=83=D1=81=20=D0=B2=20=D0=B0?= =?UTF-8?q?=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularLayoutAlgorithm.cs | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs index 17f17fa39..19d82a9b6 100644 --- a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs +++ b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs @@ -4,6 +4,7 @@ namespace TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; public class CircularLayoutAlgorithm : ILayoutAlgorithm { + private readonly Point center; private readonly double stepIncreasingAngle; private readonly double stepIncreasingRadius; private double currentAngleOfCircle; @@ -11,13 +12,14 @@ public class CircularLayoutAlgorithm : ILayoutAlgorithm private const double OneDegree = Math.PI / 180; private const double FullCircleRotation = 2 * Math.PI; - public CircularLayoutAlgorithm(double stepIncreasingAngle = OneDegree, double stepIncreasingRadius = 1) + public CircularLayoutAlgorithm(Point center, double stepIncreasingAngle = OneDegree, double stepIncreasingRadius = 1) { - if (stepIncreasingAngle <= 0) - throw new ArgumentException("The parameter 'stepIncreasingAngle' is less than or equal to zero"); - if (stepIncreasingRadius == 0) - throw new ArgumentException("The parameter 'stepIncreasingRadius' is zero"); - + if (stepIncreasingRadius <= 0) + throw new ArgumentException("The parameter 'stepIncreasingRadius' is less than or equal to zero"); + if (stepIncreasingAngle == 0) + throw new ArgumentException("The parameter 'stepIncreasingAngle' is zero"); + + this.center = center; this.stepIncreasingAngle = stepIncreasingAngle; this.stepIncreasingRadius = stepIncreasingRadius; } @@ -29,8 +31,8 @@ public Point CalculateNextPoint() currentAngleOfCircle += stepIncreasingAngle; - // проверяем не прошли ли целый круг - if (currentAngleOfCircle > FullCircleRotation) + // проверяем не прошли ли целый круг или равен ли текущий радиус нулю + if (currentAngleOfCircle > FullCircleRotation || currentRadiusOfCircle == 0) { currentAngleOfCircle = 0; currentRadiusOfCircle += stepIncreasingRadius; From 66c278ff19d1d4967c6f075ec4ba5e7bab792704 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sun, 17 Nov 2024 23:36:00 +0500 Subject: [PATCH 26/33] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BD=D0=B0=D0=B7=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0=20=D1=81=20=D1=82?= =?UTF-8?q?=D0=B5=D1=81=D1=82=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TagsCloudVisiualizationTests.csproj} | 0 cs/tdd.sln | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename cs/{CircularCloudLayouterTests/CircularCloudLayouterTests.csproj => TagsCloudVisiualizationTests/TagsCloudVisiualizationTests.csproj} (100%) diff --git a/cs/CircularCloudLayouterTests/CircularCloudLayouterTests.csproj b/cs/TagsCloudVisiualizationTests/TagsCloudVisiualizationTests.csproj similarity index 100% rename from cs/CircularCloudLayouterTests/CircularCloudLayouterTests.csproj rename to cs/TagsCloudVisiualizationTests/TagsCloudVisiualizationTests.csproj diff --git a/cs/tdd.sln b/cs/tdd.sln index 051249e8b..eca0aa98a 100644 --- a/cs/tdd.sln +++ b/cs/tdd.sln @@ -9,7 +9,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Samples", "Samples\Samples. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TagsCloudVisualization", "TagsCloudVisualization\TagsCloudVisualization.csproj", "{E344A7C8-C0E8-4231-BAAD-E2774B855CDF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CircularCloudLayouterTests", "CircularCloudLayouterTests\CircularCloudLayouterTests.csproj", "{86B722F4-6F6A-4773-B2E6-233B10DB7492}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TagsCloudVisiualizationTests", "TagsCloudVisiualizationTests\TagsCloudVisiualizationTests.csproj", "{86B722F4-6F6A-4773-B2E6-233B10DB7492}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 61330d315e6636e8ac94d08fec354f5ffae6dcd7 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sun, 17 Nov 2024 23:37:22 +0500 Subject: [PATCH 27/33] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20=D1=80=D0=B0=D1=81?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2=D0=BA=D0=B8=20=D0=BF=D1=80?= =?UTF-8?q?=D1=8F=D0=BC=D0=BE=D1=83=D0=B3=D0=BE=D0=BB=D1=8C=D0=BD=D0=B8?= =?UTF-8?q?=D0=BA=D0=BE=D0=B2,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=20=D1=81=20=D1=83=D1=82?= =?UTF-8?q?=D0=B8=D0=BB=D0=B8=D1=82=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayoutTests.cs} | 45 ++++--------------- .../Utils/GeometryUtils.cs | 26 +++++++++++ 2 files changed, 35 insertions(+), 36 deletions(-) rename cs/{CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs => TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs} (62%) create mode 100644 cs/TagsCloudVisiualizationTests/Utils/GeometryUtils.cs diff --git a/cs/CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs b/cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs similarity index 62% rename from cs/CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs rename to cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs index 50c7fd6cf..e76c62e28 100644 --- a/cs/CircularCloudLayouterTests/CircularLayoutRectanglesInCloudAlgorithmTests.cs +++ b/cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs @@ -3,13 +3,14 @@ using FluentAssertions; using NUnit.Framework; using NUnit.Framework.Interfaces; +using TagsCloudVisiualizationTests.Utils; using TagsCloudVisualization; using TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; -namespace CircularCloudLayouterTests; +namespace TagsCloudVisiualizationTests; [TestFixture] -public class CircularLayoutRectanglesInCloudAlgorithmTests +public class CircularCloudLayoutTests { private ICircularCloudLayouter cloudLayouter; private List addedRectangles; @@ -17,7 +18,8 @@ public class CircularLayoutRectanglesInCloudAlgorithmTests [SetUp] public void Setup() { - cloudLayouter = new CircularCloudLayouter(new Point(0, 0), new CircularLayoutAlgorithm()); + var center = new Point(0, 0); + cloudLayouter = new CircularCloudLayouter(center, new CircularLayoutAlgorithm(center)); addedRectangles = []; } @@ -43,17 +45,6 @@ public void TearDown() Console.WriteLine($@"Tag cloud visualization saved to file {pathImageStored}\{testName}.png"); } - [Test] - public void PutNextRectangle_ShouldRectangleInCenter_WhenAddFirstRectangle() - { - var rectangleSize = new Size(10, 15); - - var addedRectangle = cloudLayouter.PutNextRectangle(rectangleSize); - var expectedRectangleStartPoint = new Point(-addedRectangle.Width / 2, - addedRectangle.Height / 2); - - addedRectangle.Location.Should().BeEquivalentTo(expectedRectangleStartPoint); - } - [TestCase(10, 5, 15)] [TestCase(50, 30, 100)] [TestCase(100, 5, 50)] @@ -85,12 +76,14 @@ public void CircleShape_ShouldBeCloseToCircle_WhenAddMultipleRectangles(int coun addedRectangles.AddRange(rectangleSizes.Select(t => cloudLayouter.PutNextRectangle(t))); var distances = addedRectangles - .Select(rectangle => CalculateDistanceBetweenCenterRectangleAndCenterCloud(rectangle, new Point(0, 0))) + .Select(rectangle => + GeometryUtils.CalculateDistanceBetweenCenterRectangleAndCenterCloud(rectangle, new Point(0, 0))) .ToArray(); for (var i = 1; i < distances.Length; i++) { - var distanceBetweenRectangles = CalculateDistanceBetweenRectangles(addedRectangles[i], addedRectangles[i - 1]); + var distanceBetweenRectangles = + GeometryUtils.CalculateDistanceBetweenRectangles(addedRectangles[i], addedRectangles[i - 1]); distances[i].Should().BeApproximately(distances[i - 1], distanceBetweenRectangles); } } @@ -109,24 +102,4 @@ private static List GenerateRectangleSizes(int countRectangles, int minSid return generatedSizes; } - - private static double CalculateDistanceBetweenCenterRectangleAndCenterCloud(Rectangle rectangle, Point center) - { - var centerRectangle = new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2); - - return CalculateDistanceBetweenPoints(centerRectangle, center); - } - - private static double CalculateDistanceBetweenRectangles(Rectangle rectangle1, Rectangle rectangle2) - { - var centerRectangle1 = new Point(rectangle1.X + rectangle1.Width / 2, rectangle1.Y + rectangle1.Height / 2); - var centerRectangle2 = new Point(rectangle2.X + rectangle2.Width / 2, rectangle2.Y + rectangle2.Height / 2); - - return CalculateDistanceBetweenPoints(centerRectangle1, centerRectangle2); - } - - private static double CalculateDistanceBetweenPoints(Point point1, Point point2) - { - return Math.Sqrt(Math.Pow(point1.X - point2.X, 2) + Math.Pow(point1.Y - point2.Y, 2)); - } } \ No newline at end of file diff --git a/cs/TagsCloudVisiualizationTests/Utils/GeometryUtils.cs b/cs/TagsCloudVisiualizationTests/Utils/GeometryUtils.cs new file mode 100644 index 000000000..f6ebfbd6c --- /dev/null +++ b/cs/TagsCloudVisiualizationTests/Utils/GeometryUtils.cs @@ -0,0 +1,26 @@ +using System.Drawing; + +namespace TagsCloudVisiualizationTests.Utils; + +public static class GeometryUtils +{ + public static double CalculateDistanceBetweenCenterRectangleAndCenterCloud(Rectangle rectangle, Point center) + { + var centerRectangle = new Point(rectangle.X + rectangle.Width / 2, rectangle.Y + rectangle.Height / 2); + + return CalculateDistanceBetweenPoints(centerRectangle, center); + } + + public static double CalculateDistanceBetweenRectangles(Rectangle rectangle1, Rectangle rectangle2) + { + var centerRectangle1 = new Point(rectangle1.X + rectangle1.Width / 2, rectangle1.Y + rectangle1.Height / 2); + var centerRectangle2 = new Point(rectangle2.X + rectangle2.Width / 2, rectangle2.Y + rectangle2.Height / 2); + + return CalculateDistanceBetweenPoints(centerRectangle1, centerRectangle2); + } + + public static double CalculateDistanceBetweenPoints(Point point1, Point point2) + { + return Math.Sqrt(Math.Pow(point1.X - point2.X, 2) + Math.Pow(point1.Y - point2.Y, 2)); + } +} \ No newline at end of file From c35b93453d4e629473d0de1de725b536f61fc6eb Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sun, 17 Nov 2024 23:38:04 +0500 Subject: [PATCH 28/33] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=20=D0=B4=D0=BE=D0=B1?= =?UTF-8?q?=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D1=80=D1=8F?= =?UTF-8?q?=D0=BC=D0=BE=D1=83=D0=B3=D0=BE=D0=BB=D1=8C=D0=BD=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/CircularCloudLayouter.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 71cc8d010..480a934e3 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -22,11 +22,10 @@ public Rectangle PutNextRectangle(Size rectangleSize) do { var nextPoint = layoutAlgorithm.CalculateNextPoint(); + + var rectangleLocation = nextPoint - rectangleSize / 2; - var x = center.X + nextPoint.X - rectangleSize.Width / 2; - var y = center.Y + nextPoint.Y - rectangleSize.Height / 2; - - rectangle = new Rectangle(new Point(x, y), rectangleSize); + rectangle = new Rectangle(rectangleLocation, rectangleSize); } while (IntersectWithAddedRectangles(rectangle)); From d9abf431aacca4de6af97319b9ea3cf24b6d97c0 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sun, 17 Nov 2024 23:44:13 +0500 Subject: [PATCH 29/33] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=BA=D0=BB=D0=B0?= =?UTF-8?q?=D1=81=D1=81=D1=8B=20=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D1=8B=20=D1=81=20=D0=B8=D0=B7=D0=BE=D0=B1=D1=80?= =?UTF-8?q?=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/Visualization/ImageDrawer.cs | 6 ++++++ cs/TagsCloudVisualization/Visualization/ImageSaver.cs | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 cs/TagsCloudVisualization/Visualization/ImageDrawer.cs create mode 100644 cs/TagsCloudVisualization/Visualization/ImageSaver.cs diff --git a/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs b/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs new file mode 100644 index 000000000..20f74569d --- /dev/null +++ b/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs @@ -0,0 +1,6 @@ +namespace TagsCloudVisualization.Visualization; + +public class ImageDrawer +{ + +} \ No newline at end of file diff --git a/cs/TagsCloudVisualization/Visualization/ImageSaver.cs b/cs/TagsCloudVisualization/Visualization/ImageSaver.cs new file mode 100644 index 000000000..9a74d41c1 --- /dev/null +++ b/cs/TagsCloudVisualization/Visualization/ImageSaver.cs @@ -0,0 +1,6 @@ +namespace TagsCloudVisualization.Visualization; + +public class ImageSaver +{ + +} \ No newline at end of file From 32744397fe0573d26492af7aba833b3790018e84 Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Sun, 17 Nov 2024 23:47:23 +0500 Subject: [PATCH 30/33] =?UTF-8?q?=D0=9F=D0=B5=D1=80=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=20=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D1=83=20=D0=BE=D1=82?= =?UTF-8?q?=D1=80=D0=B8=D1=81=D0=BE=D0=B2=D0=BA=D0=B8=20=D0=B8=20=D1=81?= =?UTF-8?q?=D0=BE=D1=85=D1=80=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B2?= =?UTF-8?q?=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20=D0=BA=D0=BB=D0=B0=D1=81?= =?UTF-8?q?=D1=81=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularCloudLayoutTests.cs | 5 +- .../Visualization/ImageDrawer.cs | 38 ++++++++++++++- .../Visualization/ImageSaver.cs | 10 +++- .../VisualizationCircularCloudLayout.cs | 47 ------------------- 4 files changed, 47 insertions(+), 53 deletions(-) delete mode 100644 cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs diff --git a/cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs b/cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs index e76c62e28..fdce6b155 100644 --- a/cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs +++ b/cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs @@ -6,6 +6,7 @@ using TagsCloudVisiualizationTests.Utils; using TagsCloudVisualization; using TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; +using TagsCloudVisualization.Visualization; namespace TagsCloudVisiualizationTests; @@ -38,9 +39,9 @@ public void TearDown() var testName = TestContext.CurrentContext.Test.Name; - var bitmap = VisualizationCircularCloudLayout.DrawLayout(addedRectangles, 10); + var bitmap = ImageDrawer.DrawLayout(addedRectangles, 10); - VisualizationCircularCloudLayout.SaveLayout(bitmap, pathImageStored, $"{testName}.png", ImageFormat.Png); + ImageSaver.Save(bitmap, pathImageStored, $"{testName}.png", ImageFormat.Png); Console.WriteLine($@"Tag cloud visualization saved to file {pathImageStored}\{testName}.png"); } diff --git a/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs b/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs index 20f74569d..dd7d46fff 100644 --- a/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs +++ b/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs @@ -1,6 +1,40 @@ -namespace TagsCloudVisualization.Visualization; +using System.Drawing; + +namespace TagsCloudVisualization.Visualization; public class ImageDrawer { - + public static Bitmap DrawLayout(List rectangles, int paddingFromBorders) + { + var minX = rectangles.Min(rectangle => rectangle.Left); + var minY = rectangles.Min(rectangle => rectangle.Top); + var maxX = rectangles.Max(rectangle => rectangle.Right); + var maxY = rectangles.Max(rectangle => rectangle.Bottom); + var width = maxX - minX + paddingFromBorders; + var height = maxY - minY + paddingFromBorders; + + var random = new Random(); + + var bitmap = new Bitmap(width, height); + using var graphics = Graphics.FromImage(bitmap); + + graphics.Clear(Color.White); + + foreach (var rectangle in rectangles) + { + var shiftedRectangle = rectangle with + { + X = rectangle.X - minX + paddingFromBorders, + Y = rectangle.Y - minY + paddingFromBorders + }; + + var randomColor = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); + + var brush = new SolidBrush(randomColor); + graphics.FillRectangle(brush, shiftedRectangle); + graphics.DrawRectangle(Pens.Black, shiftedRectangle); + } + + return bitmap; + } } \ No newline at end of file diff --git a/cs/TagsCloudVisualization/Visualization/ImageSaver.cs b/cs/TagsCloudVisualization/Visualization/ImageSaver.cs index 9a74d41c1..d9183a3fc 100644 --- a/cs/TagsCloudVisualization/Visualization/ImageSaver.cs +++ b/cs/TagsCloudVisualization/Visualization/ImageSaver.cs @@ -1,6 +1,12 @@ -namespace TagsCloudVisualization.Visualization; +using System.Drawing; +using System.Drawing.Imaging; + +namespace TagsCloudVisualization.Visualization; public class ImageSaver { - + public static void Save(Bitmap bitmap, string filePath, string fileName, ImageFormat imageFormat) + { + bitmap.Save(Path.Combine(filePath, fileName), imageFormat); + } } \ No newline at end of file diff --git a/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs b/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs deleted file mode 100644 index 1bef0febd..000000000 --- a/cs/TagsCloudVisualization/VisualizationCircularCloudLayout.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Drawing; -using System.Drawing.Imaging; - -namespace TagsCloudVisualization; -#pragma warning disable CA1416 - -public class VisualizationCircularCloudLayout -{ - public static Bitmap DrawLayout(List rectangles, int paddingFromBorders) - { - var minX = rectangles.Min(rectangle => rectangle.Left); - var minY = rectangles.Min(rectangle => rectangle.Top); - var maxX = rectangles.Max(rectangle => rectangle.Right); - var maxY = rectangles.Max(rectangle => rectangle.Bottom); - var width = maxX - minX + paddingFromBorders; - var height = maxY - minY + paddingFromBorders; - - var random = new Random(); - - var bitmap = new Bitmap(width, height); - using var graphics = Graphics.FromImage(bitmap); - - graphics.Clear(Color.White); - - foreach (var rectangle in rectangles) - { - var shiftedRectangle = rectangle with - { - X = rectangle.X - minX + paddingFromBorders, - Y = rectangle.Y - minY + paddingFromBorders - }; - - var randomColor = Color.FromArgb(random.Next(256), random.Next(256), random.Next(256)); - - var brush = new SolidBrush(randomColor); - graphics.FillRectangle(brush, shiftedRectangle); - graphics.DrawRectangle(Pens.Black, shiftedRectangle); - } - - return bitmap; - } - - public static void SaveLayout(Bitmap bitmap, string filePath, string fileName, ImageFormat imageFormat) - { - bitmap.Save(Path.Combine(filePath, fileName), imageFormat); - } -} \ No newline at end of file From d3f04e663d9e38bb36855c149740d8bc8eb9b6cf Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Mon, 18 Nov 2024 12:14:50 +0500 Subject: [PATCH 31/33] =?UTF-8?q?=D0=A3=D0=B1=D1=80=D0=B0=D0=BB=20=D1=82?= =?UTF-8?q?=D0=BE=D1=87=D0=BA=D1=83=20=D1=86=D0=B5=D0=BD=D1=82=D1=80=D0=B0?= =?UTF-8?q?=20=D0=B8=D0=B7=20=D0=B0=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82?= =?UTF-8?q?=D0=BC=D0=B0=20=D1=80=D0=B0=D1=81=D1=81=D1=82=D0=B0=D0=BD=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B8,=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=B5?= =?UTF-8?q?=D1=81=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0=D1=86=D0=B8=D1=8E?= =?UTF-8?q?=20=D0=BF=D1=80=D1=8F=D0=BC=D0=BE=D1=83=D0=B3=D0=BE=D0=BB=D1=8C?= =?UTF-8?q?=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 --- .../CircularCloudLayoutTests.cs | 21 +++---------------- .../Utils/GeometryUtils.cs | 14 +++++++++++++ .../CircularCloudLayouter.cs | 4 +--- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs b/cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs index fdce6b155..10ce5148b 100644 --- a/cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs +++ b/cs/TagsCloudVisiualizationTests/CircularCloudLayoutTests.cs @@ -20,7 +20,7 @@ public class CircularCloudLayoutTests public void Setup() { var center = new Point(0, 0); - cloudLayouter = new CircularCloudLayouter(center, new CircularLayoutAlgorithm(center)); + cloudLayouter = new CircularCloudLayouter(new CircularLayoutAlgorithm(center)); addedRectangles = []; } @@ -52,7 +52,7 @@ public void TearDown() public void PutNextRectangle_ShouldAddedRectanglesDoNotIntersect(int countRectangles, int minSideLength, int maxSideLength) { - var rectangleSizes = GenerateRectangleSizes(countRectangles, minSideLength, maxSideLength); + var rectangleSizes = GeometryUtils.GenerateRectangleSizes(countRectangles, minSideLength, maxSideLength); addedRectangles.AddRange(rectangleSizes.Select(t => cloudLayouter.PutNextRectangle(t))); @@ -72,7 +72,7 @@ public void PutNextRectangle_ShouldAddedRectanglesDoNotIntersect(int countRectan public void CircleShape_ShouldBeCloseToCircle_WhenAddMultipleRectangles(int countRectangles, int minSideLength, int maxSideLength) { - var rectangleSizes = GenerateRectangleSizes(countRectangles, minSideLength, maxSideLength); + var rectangleSizes = GeometryUtils.GenerateRectangleSizes(countRectangles, minSideLength, maxSideLength); addedRectangles.AddRange(rectangleSizes.Select(t => cloudLayouter.PutNextRectangle(t))); @@ -88,19 +88,4 @@ public void CircleShape_ShouldBeCloseToCircle_WhenAddMultipleRectangles(int coun distances[i].Should().BeApproximately(distances[i - 1], distanceBetweenRectangles); } } - - - private static List GenerateRectangleSizes(int countRectangles, int minSideLength, int maxSideLength) - { - var random = new Random(); - - var generatedSizes = Enumerable.Range(0, countRectangles) - .Select(_ => new Size( - random.Next(minSideLength, maxSideLength), - random.Next(minSideLength, maxSideLength)) - ) - .ToList(); - - return generatedSizes; - } } \ No newline at end of file diff --git a/cs/TagsCloudVisiualizationTests/Utils/GeometryUtils.cs b/cs/TagsCloudVisiualizationTests/Utils/GeometryUtils.cs index f6ebfbd6c..d4ec01cef 100644 --- a/cs/TagsCloudVisiualizationTests/Utils/GeometryUtils.cs +++ b/cs/TagsCloudVisiualizationTests/Utils/GeometryUtils.cs @@ -23,4 +23,18 @@ public static double CalculateDistanceBetweenPoints(Point point1, Point point2) { return Math.Sqrt(Math.Pow(point1.X - point2.X, 2) + Math.Pow(point1.Y - point2.Y, 2)); } + + public static List GenerateRectangleSizes(int countRectangles, int minSideLength, int maxSideLength) + { + var random = new Random(); + + var generatedSizes = Enumerable.Range(0, countRectangles) + .Select(_ => new Size( + random.Next(minSideLength, maxSideLength), + random.Next(minSideLength, maxSideLength)) + ) + .ToList(); + + return generatedSizes; + } } \ No newline at end of file diff --git a/cs/TagsCloudVisualization/CircularCloudLayouter.cs b/cs/TagsCloudVisualization/CircularCloudLayouter.cs index 480a934e3..36501df94 100644 --- a/cs/TagsCloudVisualization/CircularCloudLayouter.cs +++ b/cs/TagsCloudVisualization/CircularCloudLayouter.cs @@ -5,13 +5,11 @@ namespace TagsCloudVisualization; public class CircularCloudLayouter : ICircularCloudLayouter { - private readonly Point center; private readonly ILayoutAlgorithm layoutAlgorithm; private readonly List addedRectangles = []; - public CircularCloudLayouter(Point center, ILayoutAlgorithm layoutAlgorithm) + public CircularCloudLayouter(ILayoutAlgorithm layoutAlgorithm) { - this.center = center; this.layoutAlgorithm = layoutAlgorithm; } From 44309c3de28e21f72f62f6b2c1e73e29de4c6d4c Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Mon, 18 Nov 2024 15:49:41 +0500 Subject: [PATCH 32/33] =?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=D1=8B=20=D0=BD=D0=B0=20=D0=B0?= =?UTF-8?q?=D0=BB=D0=B3=D0=BE=D1=80=D0=B8=D1=82=D0=BC=20=D0=BF=D0=BE=20?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D1=87=D0=B5=D1=82=D1=83=20=D1=82=D0=BE=D1=87?= =?UTF-8?q?=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CircularLayoutAlgorithmTests.cs | 91 +++++++++++++++++++ .../CircularLayoutAlgorithm.cs | 8 +- 2 files changed, 95 insertions(+), 4 deletions(-) create mode 100644 cs/TagsCloudVisiualizationTests/CircularLayoutAlgorithmTests.cs diff --git a/cs/TagsCloudVisiualizationTests/CircularLayoutAlgorithmTests.cs b/cs/TagsCloudVisiualizationTests/CircularLayoutAlgorithmTests.cs new file mode 100644 index 000000000..43d00e428 --- /dev/null +++ b/cs/TagsCloudVisiualizationTests/CircularLayoutAlgorithmTests.cs @@ -0,0 +1,91 @@ +using System.Drawing; +using FluentAssertions; +using NUnit.Framework; +using TagsCloudVisiualizationTests.Utils; +using TagsCloudVisualization.LayoutRectanglesInCloudAlgorithms; + +namespace TagsCloudVisiualizationTests; + +[TestFixture] +public class CircularLayoutAlgorithmTests +{ + [TestCase(0)] + [TestCase(-5)] + public void Constructor_ShouldArgumentException_WhenStepIncreasingRadiusHasInvalidValue(int stepIncreasingRadius) + { + var action = () => + { + _ = new CircularLayoutAlgorithm(new Point(0, 0), stepIncreasingRadius: stepIncreasingRadius); + }; + + action + .Should() + .Throw() + .WithMessage("The parameter 'stepIncreasingRadius' is less than or equal to zero"); + } + + [Test] + public void Constructor_ShouldArgumentException_WhenStepIncreasingAngleIsZero() + { + var action = () => + { + _ = new CircularLayoutAlgorithm(new Point(0, 0), stepIncreasingAngle: 0); + }; + + action + .Should() + .Throw() + .WithMessage("The parameter 'stepIncreasingAngle' is zero"); + } + + [TestCase(0, 0)] + [TestCase(-4, 5)] + public void CalculateNextPoint_ShouldPointIsCenter_WhenCalculateFirstPoint(int centerCoordinateX, int centerCoordinateY) + { + var center = new Point(centerCoordinateY, centerCoordinateY); + var circularLayoutAlgorithm = new CircularLayoutAlgorithm(center); + + var nextPoint = circularLayoutAlgorithm.CalculateNextPoint(); + + nextPoint.Should().Be(center); + } + + [TestCase(2)] + [TestCase(7)] + public void CalculateNextPoint_ShouldIncreaseRadius_WhenCalculateTwoPoints(int stepIncreasingRadius) + { + var circularLayoutAlgorithm = + new CircularLayoutAlgorithm(new Point(0, 0), stepIncreasingRadius: stepIncreasingRadius); + + var firstPoint = circularLayoutAlgorithm.CalculateNextPoint(); + var secondPoint = circularLayoutAlgorithm.CalculateNextPoint(); + var distanceBetweenPoints = GeometryUtils.CalculateDistanceBetweenPoints(firstPoint, secondPoint); + + distanceBetweenPoints.Should().Be(stepIncreasingRadius); + } + + [TestCase(Math.PI / 4)] + [TestCase(Math.PI / 2)] + public void CalculateNextPoint_ShouldIncreaseAngle_WhenCalculateThreePoints(double stepIncreasingAngle) + { + var stepIncreasingRadius = 2; + var center = new Point(0, 0); + var circularLayoutAlgorithm = new CircularLayoutAlgorithm( + center, + stepIncreasingRadius: stepIncreasingRadius, + stepIncreasingAngle: stepIncreasingAngle + ); + + _ = circularLayoutAlgorithm.CalculateNextPoint(); + var secondPoint = circularLayoutAlgorithm.CalculateNextPoint(); + var thirdPoint = circularLayoutAlgorithm.CalculateNextPoint(); + var distanceBetweenCenterAndSecondPoint = GeometryUtils.CalculateDistanceBetweenPoints(center, secondPoint); + var distanceBetweenCenterAndThirdPoint = GeometryUtils.CalculateDistanceBetweenPoints(center, thirdPoint); + + // проверяем, что точки не равны + secondPoint.Should().NotBe(thirdPoint); + // проверяем, что точки в пределах круга с одним радиусом + distanceBetweenCenterAndSecondPoint.Should().BeLessThanOrEqualTo(stepIncreasingRadius); + distanceBetweenCenterAndThirdPoint.Should().BeLessThanOrEqualTo(stepIncreasingRadius); + } +} \ No newline at end of file diff --git a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs index 19d82a9b6..e82a44892 100644 --- a/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs +++ b/cs/TagsCloudVisualization/LayoutRectanglesInCloudAlgorithms/CircularLayoutAlgorithm.cs @@ -6,13 +6,13 @@ public class CircularLayoutAlgorithm : ILayoutAlgorithm { private readonly Point center; private readonly double stepIncreasingAngle; - private readonly double stepIncreasingRadius; + private readonly int stepIncreasingRadius; private double currentAngleOfCircle; private double currentRadiusOfCircle; private const double OneDegree = Math.PI / 180; private const double FullCircleRotation = 2 * Math.PI; - public CircularLayoutAlgorithm(Point center, double stepIncreasingAngle = OneDegree, double stepIncreasingRadius = 1) + public CircularLayoutAlgorithm(Point center, double stepIncreasingAngle = OneDegree, int stepIncreasingRadius = 1) { if (stepIncreasingRadius <= 0) throw new ArgumentException("The parameter 'stepIncreasingRadius' is less than or equal to zero"); @@ -26,8 +26,8 @@ public CircularLayoutAlgorithm(Point center, double stepIncreasingAngle = OneDeg public Point CalculateNextPoint() { - var x = (int)(currentRadiusOfCircle * Math.Cos(currentAngleOfCircle)); - var y = (int)(currentRadiusOfCircle * Math.Sin(currentAngleOfCircle)); + var x = center.X + (int)(currentRadiusOfCircle * Math.Cos(currentAngleOfCircle)); + var y = center.Y + (int)(currentRadiusOfCircle * Math.Sin(currentAngleOfCircle)); currentAngleOfCircle += stepIncreasingAngle; From 938e8d8f1c17c1320828eff7cd1e47d29f939b7a Mon Sep 17 00:00:00 2001 From: Ilya4rh Date: Mon, 18 Nov 2024 15:53:31 +0500 Subject: [PATCH 33/33] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=B2=20=D0=BA=D0=BB=D0=B0=D1=81=D1=81=D0=B0=D1=85=20=D1=80?= =?UTF-8?q?=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20=D1=81=20=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B1=D1=80=D0=B0=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cs/TagsCloudVisualization/Visualization/ImageDrawer.cs | 1 + cs/TagsCloudVisualization/Visualization/ImageSaver.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs b/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs index dd7d46fff..9578a66c7 100644 --- a/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs +++ b/cs/TagsCloudVisualization/Visualization/ImageDrawer.cs @@ -2,6 +2,7 @@ namespace TagsCloudVisualization.Visualization; +#pragma warning disable CA1416 public class ImageDrawer { public static Bitmap DrawLayout(List rectangles, int paddingFromBorders) diff --git a/cs/TagsCloudVisualization/Visualization/ImageSaver.cs b/cs/TagsCloudVisualization/Visualization/ImageSaver.cs index d9183a3fc..57113ba21 100644 --- a/cs/TagsCloudVisualization/Visualization/ImageSaver.cs +++ b/cs/TagsCloudVisualization/Visualization/ImageSaver.cs @@ -1,6 +1,7 @@ using System.Drawing; using System.Drawing.Imaging; +#pragma warning disable CA1416 namespace TagsCloudVisualization.Visualization; public class ImageSaver