-
Notifications
You must be signed in to change notification settings - Fork 276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Алешев Руслан #215
base: master
Are you sure you want to change the base?
Алешев Руслан #215
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Drawing; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using FluentAssertions; | ||
using NUnit.Framework; | ||
|
||
namespace TagsCloudVisualization | ||
{ | ||
public class CircularCloudLayouter | ||
{ | ||
private readonly Point center; | ||
private List<Rectangle> cloud; | ||
|
||
//Spiral coeffs | ||
int i = 0; | ||
float it = (float)Math.PI / 21; | ||
float ri = 50; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Нужны говорящие имена, модификаторы доступа, мб еще какие-нибудь. Можно даже |
||
|
||
public CircularCloudLayouter(Point center) | ||
{ | ||
if (center.X <= 0 || center.Y <= 0) | ||
throw new ArgumentException("Central point coordinates should be in positive"); | ||
cloud = new List<Rectangle>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. В |
||
this.center = center; | ||
} | ||
|
||
public Rectangle PutNextRectangle(Size rectSize) | ||
{ | ||
if (rectSize.Width <= 0 || rectSize.Height <= 0) | ||
throw new ArgumentException("Size width and height should be positive"); | ||
|
||
if (!cloud.Any()) | ||
return new Rectangle(center, rectSize); | ||
|
||
Rectangle rect; | ||
|
||
while (true) | ||
{ | ||
bool findPlace = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Здесь и во многих других местах - |
||
var point = GetNextPoint(); | ||
|
||
rect = new Rectangle(new Point(point.X - rectSize.Width / 2, point.Y - rectSize.Height / 2), rectSize); | ||
foreach (var previous in cloud) | ||
{ | ||
if (rect.IntersectsWith(previous)) | ||
{ | ||
findPlace = false; | ||
break; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если знаком с |
||
|
||
if (findPlace) | ||
break; | ||
} | ||
|
||
return rect; | ||
} | ||
|
||
public List<Rectangle> CreateCloud(List<Size> rectangleSizes) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тут 2 варианта:
Еще, мне как потенциальному пользователю твоего класса не ясна его роль. Например, что если я вызову этот метод 2 раза? Список старых прямоугольников очистится, но функция продолжить работать со старого индекса, получится не оч. Нужно решить как оно должно себя вести - пересоздавать или дополнять и дать соответствующее название |
||
{ | ||
cloud = new List<Rectangle>(); | ||
|
||
foreach (var rectangleSize in rectangleSizes) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если знаком с |
||
{ | ||
cloud.Add(PutNextRectangle(rectangleSize)); | ||
} | ||
|
||
return cloud; | ||
} | ||
|
||
public Image CreateImage() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Обычно такое называют |
||
{ | ||
Bitmap image = new Bitmap(center.X * 2, center.Y * 2); | ||
Graphics gr = Graphics.FromImage(image); | ||
Pen pen = new Pen(Color.White); | ||
|
||
gr.Clear(Color.Black); | ||
gr.DrawRectangles(pen, cloud.ToArray()); | ||
|
||
return image; | ||
} | ||
|
||
private Point GetNextPoint() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если знаком с перечислениями, было бы наглядно переписать на |
||
{ | ||
float r = (float)Math.Sqrt(ri * i); | ||
float t = it * i; | ||
float x = (float)(r * Math.Cos(t) + center.X); | ||
float y = (float)(r * Math.Sin(t) + center.Y); | ||
i++; | ||
|
||
//Console.WriteLine("{0} {1}", x, y); | ||
|
||
return new Point((int)x, (int)y); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System; | ||
using FluentAssertions; | ||
using NUnit.Framework; | ||
using System.Drawing; | ||
using TagsCloudVisualization; | ||
|
||
namespace TagCloudVisualisation | ||
{ | ||
class Program | ||
{ | ||
public static void Main() | ||
{ | ||
var layouter = new CircularCloudLayouter(new Point(600, 300)); | ||
|
||
var sizes = new List<Size>(); | ||
var rnd = new Random(); | ||
|
||
for (int i = 0; i < 200; i++) | ||
{ | ||
sizes.Add(new Size(rnd.Next(1, 50), rnd.Next(1, 50))); | ||
} | ||
|
||
var c = layouter.CreateCloud(sizes); | ||
|
||
var image = layouter.CreateImage(); | ||
|
||
image.Save("cloud.png"); | ||
Console.WriteLine("Image saved to file cloud.png"); | ||
} | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Примеры | ||
|
||
![](Examples/LandscapeCloud200Rectangles.png) | ||
![](Examples/PortraitCloud200Rectangles.png) | ||
![](Examples/SquareCloud100Rectangles.png) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
using NUnit.Framework; | ||
using FluentAssertions; | ||
using System.Drawing; | ||
using static System.Net.Mime.MediaTypeNames; | ||
|
||
namespace TagsCloudVisualization | ||
{ | ||
[TestFixture] | ||
public class TagCloudVisualisationTest | ||
{ | ||
//[SetUp] | ||
//public void GenerateRandomSizes() | ||
//{ | ||
|
||
//} | ||
|
||
[TestCase(-1, -1)] | ||
[TestCase(1, -1)] | ||
[TestCase(-1, 1)] | ||
[TestCase(0, 0)] | ||
public void CircularCloudLayouterConstructor_ThrowExceptionOnIncorrectCentralPoins(int x, int y) | ||
{ | ||
Action a = () => new CircularCloudLayouter(new Point(x, y)); | ||
a.Should().Throw<ArgumentException>(); | ||
} | ||
|
||
[TestCase(1)] | ||
[TestCase(123)] | ||
public void CreateCloud_ReturnCorrectNumberOfRectangles(int rectCount) | ||
{ | ||
var layouter = new CircularCloudLayouter(new Point(50, 50)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
var sizes = new List<Size>(); | ||
|
||
for (int i = 0; i < rectCount; i++) | ||
{ | ||
sizes.Add(new Size(1, 1)); | ||
} | ||
|
||
var rects = layouter.CreateCloud(sizes); | ||
|
||
rects.Count().Should().Be(rectCount); | ||
} | ||
|
||
[Test] | ||
public void PutNextRectangle_ShouldReturnRectangle() | ||
{ | ||
var layouter = new CircularCloudLayouter(new Point(50, 50)); | ||
layouter.PutNextRectangle(new Size(1, 2)).Should().BeOfType(typeof(Rectangle)); | ||
} | ||
|
||
[TestCase(1, 1)] | ||
[TestCase(20, 1)] | ||
[TestCase(256, 255)] | ||
[TestCase(1, 20)] | ||
public void PutNextRectangle_ShouldReturnRectangleOfCorrectSize(int width, int height) | ||
{ | ||
var layouter = new CircularCloudLayouter(new Point(500, 500)); | ||
var rect = layouter.PutNextRectangle(new Size(width, height)); | ||
rect.Width.Should().Be(width); | ||
rect.Height.Should().Be(height); | ||
} | ||
|
||
[TestCase(-1, 1)] | ||
[TestCase(1, -1)] | ||
[TestCase(0, 1)] | ||
[TestCase(1, 0)] | ||
public void PutNextRectangle_ShouldThrowExceptionOnIncorrectSize(int width, int height) | ||
{ | ||
var layouter = new CircularCloudLayouter(new Point(50, 50)); | ||
Action a = () => layouter.PutNextRectangle(new Size(width, height)); | ||
a.Should().Throw<ArgumentException>(); | ||
} | ||
|
||
[TestCase(10)] | ||
[TestCase(20)] | ||
[TestCase(200)] | ||
public void CreateCloud_RectanglesShouldNotIntersect(int rectCount) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Если это попытка отрисовать облако при падении теста, то кажется что ты несколько неправильно понял задачу. Тебе нужен некий кусок кода, который вызовется при невыполнении любого условия из тестов выше, откуда-то возьмет входные данные теста и попробует отрисовать |
||
{ | ||
var layouter = new CircularCloudLayouter(new Point(500, 500)); | ||
var sizes = new List<Size>(); | ||
var rnd = new Random(); | ||
|
||
for (int i = 0; i < rectCount; i++) | ||
{ | ||
sizes.Add(new Size(rnd.Next(1, 100), rnd.Next(1, 100))); | ||
} | ||
|
||
var cloud = layouter.CreateCloud(sizes); | ||
|
||
for (int i = 0; i < cloud.Count; i++) | ||
{ | ||
for (int j = i; j < cloud.Count; j++) | ||
{ | ||
if (i == j) continue; | ||
var isIntersect = cloud[i].IntersectsWith(cloud[j]); | ||
if (isIntersect) | ||
{ | ||
var img = layouter.CreateImage(); | ||
|
||
//mark intersection | ||
Graphics gr = Graphics.FromImage(img); | ||
Pen pen = new Pen(Color.Red); | ||
gr.DrawRectangle(pen, cloud[i]); | ||
gr.DrawRectangle(pen, cloud[j]); | ||
string filename = "error - " + DateTime.Now.ToString("H - mm - ss") + ".png"; | ||
img.Save(filename); | ||
Console.WriteLine("Tag cloud visualization saved to file {0}", filename); | ||
} | ||
|
||
isIntersect.Should().BeFalse(); | ||
} | ||
} | ||
} | ||
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net6.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<GenerateProgramFile>false</GenerateProgramFile> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="FluentAssertions" Version="6.12.0" /> | ||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" /> | ||
<PackageReference Include="NUnit" Version="4.0.0" /> | ||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" /> | ||
<PackageReference Include="System.Drawing.Common" Version="8.0.0" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
| ||
Microsoft Visual Studio Solution File, Format Version 12.00 | ||
# Visual Studio Version 17 | ||
VisualStudioVersion = 17.7.34202.233 | ||
MinimumVisualStudioVersion = 10.0.40219.1 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TagsCloudVisualization", "TagsCloudVisualization.csproj", "{85DD6D7B-7811-4117-8B54-A4ECC712D5C8}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{85DD6D7B-7811-4117-8B54-A4ECC712D5C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{85DD6D7B-7811-4117-8B54-A4ECC712D5C8}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{85DD6D7B-7811-4117-8B54-A4ECC712D5C8}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{85DD6D7B-7811-4117-8B54-A4ECC712D5C8}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
GlobalSection(ExtensibilityGlobals) = postSolution | ||
SolutionGuid = {5BEAA608-2B32-428E-815C-F8F19E0DF0B8} | ||
EndGlobalSection | ||
EndGlobal |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Лучше
IList
, а то и вовсеICollection
. Это позволит не привязываться к реализации коллекции и поменять ее в любой момент