Skip to content

Глейзер Роман#274

Open
RomanGleyzer wants to merge 22 commits into
kontur-courses:masterfrom
RomanGleyzer:master
Open

Глейзер Роман#274
RomanGleyzer wants to merge 22 commits into
kontur-courses:masterfrom
RomanGleyzer:master

Conversation

@RomanGleyzer

@RomanGleyzer RomanGleyzer commented Nov 28, 2025

Copy link
Copy Markdown

…ayouter

На первый вызов PutNextRectangle создает прямоугольник по центру
Прямоугольники должны лежать как можно ближе друг к другу
Облако растет относительно центра, а не какой-то рандомной точки
Облако получается круглым, а не овальным
Допускаем, что центр облака может немного сместиться, но не сильно
Теперь используется общий угол для спирали
Спираль сделал более плотной
Чуть-чуть поработал над улучшением читаемости

[SetUp]
public void SetUp()
{

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Давай не будем выносить это в setUp потому что пользы это не приносит, а читабельность ухудшает

private const int VisualizationScale = 5;
private const int VisualizationPadding = 10;

private Point _center;

@masssha1308 masssha1308 Dec 1, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

В тестах нет кейсов с разными center, хорошо бы добавить. Сейчас с помощью редактирования center в тесте это сделать не получится (layouter всегда создается с центром (0,0)). Давай уберем SetUp и общие поля

var fileName = $"{DateTime.UtcNow.ToString(FileNameTimestampFormat)}_{Guid.NewGuid().ToString(GuidFormat)}.{FailureImagesFileExtension}";
var filePath = Path.Combine(outDir, fileName);

new CloudVisualizer(_layouter.CreatedRectangles, filePath, VisualizationScale, VisualizationPadding).Visualize();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CloudVisualizer.Visualize() освобождает disposable объекты?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CloudVisualizer.Visualize() освобождает disposable объекты?

Да, в методе Visualize класса CloudVisualizer IDisposable объекты обернуты в using var


[TearDown]
public void TearDown()
{

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Давай вынесем логику визуализации в отдельный метод

var rectangles = new Rectangle[count];

for (var i = 0; i < count; i++)
rectangles[i] = _layouter.PutNextRectangle(DefaultRectangleSize);

@masssha1308 masssha1308 Dec 1, 2025

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Давай будем создавать прямоугольники разных размеров для точности тестов. Еще можно добавить тесты по типу "сначала маленькие, потом большие прямоугольники", "сначала большие, потом маленькие", "большие и маленькие вперемешку" и т.д.


for (var i = 0; i < rectangles.Length; i++)
for (var j = i + 1; j < rectangles.Length; j++)
rectangles[i].IntersectsWith(rectangles[j]).Should().BeFalse();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Упадет с неинформативной ошибкой "Expected boolean to be False, but found True.", стоит добавить больше информации о проблеме

rectangles[i].IntersectsWith(rectangles[j]).Should().BeFalse();
}

// Облако должно быть достаточно плотным

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

комментарии можно перенести в test description

[Test]
public void PutNextRectangle_ManyRectangles_BoundingRectangleContainsCenter()
{
var rectangles = CreateRandomRectangles(CreatedRectanglesLimit);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тест пройдет если центр будет в одном углу BoundingRectangle, а все прямоугольники в противоположном. Давай усилим проверку?

[Test]
public void PutNextRectangle_ManyRectangles_ShapeHasCircularAspectRatio()
{
var rectangles = CreateRandomRectangles(CreatedRectanglesLimit);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тест пройдет в любом кейсе если BoundingRectangle будет квадратом, но это не гарантирует что облако будет круглым. Например, в кейсе когда облако будет в форме креста тест не упадет. Давай усилим проверку


var centerOffsetRatio = distanceFromRequiredCenter / maxSize;

centerOffsetRatio.Should().BeLessThanOrEqualTo(MaxAllowedCenterOffsetRatio);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20% кажется многовато на первый взгляд, почему именно такое значение?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20% кажется многовато на первый взгляд, почему именно такое значение?

Скорее было выбрано экспериментально. Был выбор между 0.1 и 0.2. Решил остановиться на 0.2. В коммите 4c9542f заменил на 0.1

// Минимум половина ограничивающего прямоугольника должна быть занята прямоугольниками
private const double ExpectedMinDensity = 0.5;

// Допустимое значение смещения центра облака (не более 20 процентов от размера облака)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

комментарии можно убрать, они дублируют код


namespace TagsCloudVisualization;

public class CircularCloudLayouterTests

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хорошо бы добавить тесты на пограничные кейсы


public List<Rectangle> CreatedRectangles => _createdRectangles;

public Rectangle PutNextRectangle(Size rectangleSize)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хорошо бы добавить валидацию входных данных

{
while (true)
{
var pointOnSpiral = GetNextSpiralPoint();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Если я правильно поняла алгоритм, то для прямоугольника (1000,1000) будет 1000 итераций. Давай регулировать GetNextSpiralPoint исходя из размера следующего прямоугольника


private double _currentAngle;

public List<Rectangle> CreatedRectangles => _createdRectangles;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Лучше возвращать readonly коллекцию, т.к. в другом случае коллекцию можно изменить извне


public class CircularCloudLayouter(Point center)
{
// Шага 0.1 радиан достаточно для плотного наполнения спирали прямоугольниками

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Здеь тоже комментарии избыточны


private static Rectangle CreateRectangle(Size size, int centerX, int centerY)
{
var left = centerX - size.Width / 2;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для нечетных размеров будет смещение?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Для нечетных размеров будет смещение?

Да, для нечетных размеров центр сместится на 0.5 пикселя относительно заданной точки

Comment thread cs/CloudLayouterVisualizer/README.md Outdated
@@ -0,0 +1,7 @@
# 50 прямоугольников размером 30x20:

<img width="2220" height="2190" alt="cloud_50_30x20" src="https://github.com/user-attachments/assets/149dc4a1-f847-4988-9ef5-169d69dd08dc" />

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Такие ссылки в readme лучше не использовать. 1 - они временные, 2 - не отображаются в превью, 3 - не посмотреть без интернета

Comment thread cs/CloudLayouterVisualizer/README.md Outdated
@@ -0,0 +1,7 @@
# 50 прямоугольников размером 30x20:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Хочется больше описания: какой алгоритм, какой центр и т.д.

{
var center = DefaultCenter;

var sizes = Enumerable

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Размеры формируются также как в PutNextRectangle_LargeThenSmallRectangles_DoNotIntersect

graphics.Clear(BackgroundColor);

using var fillBrush = new SolidBrush(RectangleFillColor);
using var font = new Font(FontFamilyName, FontSize);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

не используется?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants