Skip to content
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

Бочаров Александр #239

Open
wants to merge 55 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
dba44ba
Создал проект TagsCloudVisualization.csproj
Geratoptus Nov 12, 2024
860ea63
Создал интерфейс для раскладки ICircularCloudLayouter.cs
Geratoptus Nov 12, 2024
05a0c8d
Создал интерфейс для генератора точек спирали
Geratoptus Nov 12, 2024
d09a20a
Добавил точку входа
Geratoptus Nov 12, 2024
d9c7e60
Сделал красный тест для конструктора FermatSpiralPointsGenerator.cs
Geratoptus Nov 12, 2024
460a2a7
Теперь конструктор FermatSpiralPointsGenerator проходит тест
Geratoptus Nov 12, 2024
db7c7db
Создал красный тест для метода GeneratePoints
Geratoptus Nov 12, 2024
0a99597
Теперь тест для метода GeneratePoints зеленый
Geratoptus Nov 12, 2024
bb1ac16
FermatSpiralPointsGenerator рефактор
Geratoptus Nov 12, 2024
841ebab
Создал CircularCloudLayouter.cs
Geratoptus Nov 12, 2024
a845257
Создал CircularCloudLayouterTest.cs с красным тестом для метода PutNe…
Geratoptus Nov 12, 2024
e4781ff
Теперь тест для метода PutNextRectangle зеленый
Geratoptus Nov 12, 2024
3453061
Теперь проект структурирован по папочкам
Geratoptus Nov 12, 2024
0d68ef1
Теперь namespace'ы в соответствии с папочками
Geratoptus Nov 12, 2024
d5f2308
Поставил System.Drawing.Common для Bitmap
Geratoptus Nov 12, 2024
207550c
Сделал тестам правильные using'и namespace'ов
Geratoptus Nov 12, 2024
62e8194
Поправил using'и в тестах
Geratoptus Nov 12, 2024
a58e58c
Добавил интерфейс для Visualizer'а
Geratoptus Nov 12, 2024
844342c
Добавил дефолтную реализацию DefaultVisualizer.cs
Geratoptus Nov 12, 2024
a80b1b5
Теперь в Main'е производится раскладка с параметрами и затем сохранен…
Geratoptus Nov 12, 2024
a2d65c2
Добавил README.MD с картинками
Geratoptus Nov 12, 2024
bc3bee5
README.MD теперь должен нормально отображаться
Geratoptus Nov 12, 2024
1ff2cf2
Теперь README.MD точно должен нормально отображаться
Geratoptus Nov 12, 2024
756d96f
Забыл TagsCloudVisualizationTests закоммитить
Geratoptus Nov 12, 2024
892ddff
Добавил заготовку для RandomExtension.cs
Geratoptus Nov 16, 2024
f4cfcbf
Добавил красный тест для RandomExtension
Geratoptus Nov 16, 2024
695e7bb
RandomExtension.cs RandomSize теперь тест зеленый
Geratoptus Nov 16, 2024
a34defe
RandomExtensionTest.cs добавил красный тест для RandomSize
Geratoptus Nov 16, 2024
6cfeff1
RandomExtension.cs теперь тест в RandomExtensionTest.cs зеленый
Geratoptus Nov 16, 2024
5d13c28
Внедрение RandomExtension в проект
Geratoptus Nov 16, 2024
ea2cbe0
RandomExtension.cs
Geratoptus Nov 16, 2024
406c706
RandomExtensionTest.cs добавил красный тест для RandomPoint
Geratoptus Nov 16, 2024
edc6940
RandomExtension.cs RandomPoint теперь возвращает точку (тест зеленый)
Geratoptus Nov 16, 2024
20691cd
RandomExtensionTest.cs добавил красный тест для RandomPoint
Geratoptus Nov 16, 2024
8cecf86
RandomExtension.cs
Geratoptus Nov 16, 2024
c3d866c
CircularCloudLayouterTest.cs
Geratoptus Nov 16, 2024
3212d00
EnumeratorExtensionTest.cs добавил красный тест для EnumeratorExtensi…
Geratoptus Nov 16, 2024
6fc3289
EnumeratorExtension.cs ToIEnumerable теперь возвращает ожидаемую посл…
Geratoptus Nov 16, 2024
e36483e
IVisualizer.cs CreateBitmap теперь не закрепляет в поведении зависимо…
Geratoptus Nov 16, 2024
726c074
DefaultVisualizer.cs зависимость от bitmapSize вынесена в конструктор
Geratoptus Nov 16, 2024
2a11755
CircularCloudLayouter.cs
Geratoptus Nov 16, 2024
8ccf2cf
Визуальные правки
Geratoptus Nov 16, 2024
7406a83
Program.cs
Geratoptus Nov 16, 2024
90e8a33
Добавил класс DefaultBitmapSaver.cs
Geratoptus Nov 17, 2024
5dd291e
DefaultVisualizer.cs добавил оцентровку изображения
Geratoptus Nov 17, 2024
73975fe
Program.cs внедрил DefaultBitmapSaver
Geratoptus Nov 17, 2024
e6c6850
CircularCloudLayouterTest.cs
Geratoptus Nov 17, 2024
cb80328
DefaultBitmapSaverTest.cs добавил тесты для DefaultBitmapSaver'a
Geratoptus Nov 17, 2024
7187ba4
CircularCloudLayouter.cs добавил обработку случая, если был передан к…
Geratoptus Nov 17, 2024
8383574
EnumeratorExtensionTest.cs добавлен тест, проверяющий, что ToIEnumera…
Geratoptus Nov 18, 2024
2f4ea39
RectangleExtensionTest.cs добавил красные тесты для RectangleExtensio…
Geratoptus Nov 18, 2024
eed36d8
RectangleExtension.cs теперь тесты зеленые
Geratoptus Nov 18, 2024
d7e118d
CircularCloudLayouterTest.cs
Geratoptus Nov 18, 2024
d23b83b
CircularCloudLayouter.cs
Geratoptus Nov 18, 2024
71a3298
CircularCloudLayouterTest.cs добавлен тест PutNextRectangle_ShouldThr…
Geratoptus Nov 18, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions cs/TagsCloudVisualization/CloudLayouters/CircularCloudLayouter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System.Drawing;
using TagsCloudVisualization.Extensions;
using TagsCloudVisualization.PointsGenerators;

namespace TagsCloudVisualization.CloudLayouters;

public class CircularCloudLayouter(Point layoutCenter, IPointsGenerator pointsGenerator) : ICircularCloudLayouter
{
private const string FiniteGeneratorExceptionMessage =
"В конструктор CircularCloudLayouter был передан конечный генератор точек";
private readonly IEnumerator<Point> pointEnumerator = pointsGenerator
.GeneratePoints(layoutCenter)
.GetEnumerator();
private readonly List<Rectangle> layoutRectangles = [];

public CircularCloudLayouter(Point layoutCenter, double radius, double angleOffset) :
this(layoutCenter, new FermatSpiralPointsGenerator(radius, angleOffset))
{

}

public Rectangle PutNextRectangle(Size rectangleSize)
{
var rectangle = pointEnumerator
.ToIEnumerable()
.Select(point => new Rectangle()
.CreateRectangleWithCenter(point, rectangleSize))
.FirstOrDefault(rectangle => !layoutRectangles.Any(rectangle.IntersectsWith));

if (rectangle.IsEmpty)
throw new InvalidOperationException(FiniteGeneratorExceptionMessage);

layoutRectangles.Add(rectangle);
return rectangle;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Drawing;

namespace TagsCloudVisualization.CloudLayouters;

public interface ICircularCloudLayouter
{
public Rectangle PutNextRectangle(Size rectangleSize);
}
10 changes: 10 additions & 0 deletions cs/TagsCloudVisualization/Extensions/EnumeratorExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace TagsCloudVisualization.Extensions;

public static class EnumeratorExtension
{
public static IEnumerable<T> ToIEnumerable<T>(this IEnumerator<T> enumerator) {
while ( enumerator.MoveNext() ) {
yield return enumerator.Current;
}
}
}
21 changes: 21 additions & 0 deletions cs/TagsCloudVisualization/Extensions/RandomExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Drawing;

namespace TagsCloudVisualization.Extensions;

public static class RandomExtension
{
public static Size RandomSize(this Random random, int minValue=1, int maxValue=int.MaxValue)
{
if (minValue <= 0)
throw new ArgumentOutOfRangeException(nameof(minValue), "minValue must be positive");
if (minValue > maxValue)
throw new ArgumentOutOfRangeException(nameof(minValue), "minValue must be less than maxValue");

return new Size(random.Next(minValue, maxValue), random.Next(minValue, maxValue));
}

public static Point RandomPoint(this Random random, int minValue=int.MinValue, int maxValue=int.MaxValue)
{
return new Point(random.Next(minValue, maxValue), random.Next(minValue, maxValue));
}
}
25 changes: 25 additions & 0 deletions cs/TagsCloudVisualization/Extensions/RectangleExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System.Drawing;

namespace TagsCloudVisualization.Extensions;

public static class RectangleExtension
{
public static Rectangle CreateRectangleWithCenter(this Rectangle rectangle, Point center, Size rectangleSize)
{
var x = center.X - rectangleSize.Width / 2;
var y = center.Y - rectangleSize.Height / 2;
return new Rectangle(x, y, rectangleSize.Width, rectangleSize.Height);
}

public static double GetDistanceToMostRemoteCorner(this Rectangle rectangle, Point startingPoint)
{
Point[] corners = [
new(rectangle.X, rectangle.Y),
new(rectangle.X + rectangle.Width, rectangle.Y),
new(rectangle.X, rectangle.Y + rectangle.Height),
new(rectangle.X + rectangle.Width, rectangle.Y + rectangle.Height)];
return corners.Max(corner =>
Math.Sqrt((startingPoint.X - corner.X) * (startingPoint.X - corner.X) +
(startingPoint.Y - corner.Y) * (startingPoint.Y - corner.Y)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Drawing;

namespace TagsCloudVisualization.PointsGenerators;

public class FermatSpiralPointsGenerator : IPointsGenerator
{
private readonly double angleOffset;
private readonly double radius;

private double OffsetPerRadian => radius / (2 * Math.PI);

public FermatSpiralPointsGenerator(double radius, double angleOffset)
{
if (radius <= 0)
throw new ArgumentException("radius must be greater than 0", nameof(radius));
if (angleOffset <= 0)
throw new ArgumentException("angleOffset must be greater than 0", nameof(angleOffset));

this.angleOffset = angleOffset * Math.PI / 180;
this.radius = radius;
}

public IEnumerable<Point> GeneratePoints(Point spiralCenter)
{
double angle = 0;

while (true)
{
yield return GetPointByPolarCoordinates(spiralCenter, angle);
angle += angleOffset;
}
}

private Point GetPointByPolarCoordinates(Point spiralCenter, double angle)
{
var radiusVector = OffsetPerRadian * angle;

var x = (int)Math.Round(
radiusVector * Math.Cos(angle) + spiralCenter.X);
Geratoptus marked this conversation as resolved.
Show resolved Hide resolved
var y = (int)Math.Round(
radiusVector * Math.Sin(angle) + spiralCenter.Y);

return new Point(x, y);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Drawing;

namespace TagsCloudVisualization.PointsGenerators;

public interface IPointsGenerator
{
public IEnumerable<Point> GeneratePoints(Point startPoint);
}
45 changes: 45 additions & 0 deletions cs/TagsCloudVisualization/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using TagsCloudVisualization.CloudLayouters;
using TagsCloudVisualization.Extensions;
using TagsCloudVisualization.Savers;
using TagsCloudVisualization.Visualizers;

namespace TagsCloudVisualization;

public static class Program
{
private const int ImageWidth = 1920;
private const int ImageHeight = 1080;

private const int RectanglesNumber = 1000;
private const int MinRectangleSize = 10;
private const int MaxRectangleSize = 50;

private const double LayoutRadius = 1;
private const double LayoutAngleOffset = 0.5;

private const string ImagesDirectory = "images";

public static void Main()
{
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;

var center = new Point(ImageWidth / 2, ImageHeight / 2);
var cloudLayouter = new CircularCloudLayouter(center, LayoutRadius, LayoutAngleOffset);
var random = new Random();
var rectangles = Enumerable
.Range(0, RectanglesNumber)
.Select(_ => cloudLayouter.PutNextRectangle(random.RandomSize
(MinRectangleSize, MaxRectangleSize)))
.ToArray();

var visualizer = new DefaultVisualizer(new Size(ImageWidth, ImageHeight));
var bitmap = visualizer.CreateBitmap(rectangles);
var saver = new DefaultBitmapSaver(ImagesDirectory);

saver.SaveBitmap(bitmap,
$"{RectanglesNumber}_{LayoutRadius}_{LayoutAngleOffset}_TagCloud.jpg");
}
}
6 changes: 6 additions & 0 deletions cs/TagsCloudVisualization/README.MD
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
1000 4-угольников, радиус=1, шаг спирали равен 0.5
<img src="images/1000_1_0,5_TagCloud.jpg">
1000 4-угольников, радиус=1, шаг спирали равен 5
<img src="images/1000_1_5_TagCloud.jpg">
1000 4-угольников, радиус=100, шаг спирали равен 0.5
<img src="images/1000_100_0,5_TagCloud.jpg">
13 changes: 13 additions & 0 deletions cs/TagsCloudVisualization/Savers/DefaultBitmapSaver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System.Drawing;
using System.Drawing.Imaging;

namespace TagsCloudVisualization.Savers;

public class DefaultBitmapSaver(string bitmapDirectory="images") : IBitmapSaver
{
public void SaveBitmap(Bitmap bitmap, string filename)
{
Directory.CreateDirectory(bitmapDirectory);
bitmap.Save(Path.Combine(bitmapDirectory, filename), ImageFormat.Jpeg);
}
}
8 changes: 8 additions & 0 deletions cs/TagsCloudVisualization/Savers/IBitmapSaver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Drawing;

namespace TagsCloudVisualization.Savers;

public interface IBitmapSaver
{
public void SaveBitmap(Bitmap bitmap, string filename);
}
14 changes: 14 additions & 0 deletions cs/TagsCloudVisualization/TagsCloudVisualization.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="6.0.0" />
</ItemGroup>
Comment on lines +10 to +12

Choose a reason for hiding this comment

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

Почему именно 6.0.0? Есть ведь новее: 9.0.0


</Project>
33 changes: 33 additions & 0 deletions cs/TagsCloudVisualization/Visualizers/DefaultVisualizer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Drawing;

namespace TagsCloudVisualization.Visualizers;

public class DefaultVisualizer(Size bitmapSize) : IVisualizer
{
private Point bitmapCenter = new(bitmapSize.Width / 2, bitmapSize.Height / 2);

public Bitmap CreateBitmap(IEnumerable<Rectangle> rectangles)
{
var bitmap = new Bitmap(bitmapSize.Width, bitmapSize.Height);

var deltaWidth = bitmapCenter.X - rectangles.First().X;
var deltaHeight = bitmapCenter.Y - rectangles.First().Y;

using var graphics = Graphics.FromImage(bitmap);
foreach (var rectangle in rectangles)
{
var pen = new Pen(Color.DeepPink);
graphics.DrawRectangle(pen,
CenterRectangle(rectangle, deltaWidth, deltaHeight));
}

return bitmap;
}

private Rectangle CenterRectangle(Rectangle rectangle, int deltaWidth, int deltaHeight)
{
var centeredRectanglePos = new Point(rectangle.Location.X + deltaWidth,
rectangle.Location.Y + deltaHeight);
return new Rectangle(centeredRectanglePos, rectangle.Size);
}
}
7 changes: 7 additions & 0 deletions cs/TagsCloudVisualization/Visualizers/IVisualizer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TagsCloudVisualization.Visualizers;
using System.Drawing;

public interface IVisualizer
{
public Bitmap CreateBitmap(IEnumerable<Rectangle> rectangles);
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading