Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System.Drawing;
using TagsCloudVisualization.PointGenerator;


namespace TagsCloudVisualization.CircularCloudLayouter;

public class CircularCloudLayouter : ICloudLayouter
{
private readonly List<Rectangle> rectangles = [];

private readonly IPointGenerator pointGenerator;

private readonly int maxPointsPerRectangle;

public CircularCloudLayouter(Point center, int maxPointsPerRectangle, IPointGenerator pointGenerator)
{
ArgumentNullException.ThrowIfNull(pointGenerator);

if (center.X <= 0 || center.Y <= 0)
throw new ArgumentException("Center should be greater than 0");

if (maxPointsPerRectangle <= 0)
throw new ArgumentException("maxPointsPerRectangle must be greater than 0");

this.maxPointsPerRectangle = maxPointsPerRectangle;
this.pointGenerator = pointGenerator;
}


public Rectangle PutNextRectangle(Size rectangleSize)
{
if (rectangleSize.Width <= 0 || rectangleSize.Height <= 0)
throw new ArgumentException("Rectangle size must be positive");

var points = pointGenerator
.GetPoints()
.Take(maxPointsPerRectangle);


foreach (var point in points)
{
var rectangle = new Rectangle(point, rectangleSize);
for (var i = rectangles.Count - 1; i >= 0; i--)
{
if (rectangles[i].IntersectsWith(rectangle))
goto NextPoint;
}

rectangles.Add(rectangle);
return rectangle;
NextPoint: ;
}

throw new ArgumentException($"Failed to find place for the {rectangles.Count} rectangle");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Drawing;

namespace TagsCloudVisualization.CircularCloudLayouter;

public interface ICloudLayouter
{
Rectangle PutNextRectangle(Size rectangleSize);
}
Binary file added cs/TagsCloudVisualization/Image/cloud.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added cs/TagsCloudVisualization/Image/cloud1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added cs/TagsCloudVisualization/Image/cloud2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions cs/TagsCloudVisualization/ImageSaver/IImageSaver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Drawing;

namespace TagsCloudVisualization;

public interface IImageSaver
{
void Save(Bitmap bitmap, string fileName);
}
26 changes: 26 additions & 0 deletions cs/TagsCloudVisualization/ImageSaver/ImageSaver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Drawing;
using System.Drawing.Imaging;

namespace TagsCloudVisualization;

public class ImageSaver : IImageSaver
{
public void Save(Bitmap bitmap, string fileName)
{
var projectDir = GetProjectDirectory();
var imagesDir = Path.Combine(projectDir, "Image");
Directory.CreateDirectory(imagesDir);
var path = Path.Combine(imagesDir, fileName);
bitmap.Save(path, ImageFormat.Png);
}

private static string GetProjectDirectory()
{
var dir = new DirectoryInfo(Environment.CurrentDirectory);
while (dir != null && !dir.GetFiles("*.csproj").Any())
{
dir = dir.Parent;
}
return dir?.FullName ?? Environment.CurrentDirectory;
}
}
8 changes: 8 additions & 0 deletions cs/TagsCloudVisualization/PointGenerator/IPointGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Drawing;

namespace TagsCloudVisualization.PointGenerator;

public interface IPointGenerator
{
public IEnumerable<Point> GetPoints();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Интерфейс не используется

}
34 changes: 34 additions & 0 deletions cs/TagsCloudVisualization/PointGenerator/SpiralPointGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Drawing;

namespace TagsCloudVisualization.PointGenerator;

public class SpiralPointGenerator : IPointGenerator
{
private readonly Point center;
private readonly double radius;
private readonly double angle;

public SpiralPointGenerator(Point center, double radius = 2, double angle = double.Pi/40)
{
if (center.X < 0 || center.Y < 0)
throw new ArgumentException("Center coordinates must be non-negative");
if (radius <= 0)
throw new ArgumentException("Radius must be positive");
this.radius = radius;
this.angle = angle;
this.center = center;
}

public IEnumerable<Point> GetPoints()
{
var currentAngle = 0.0;
while (true)
{
var vector = radius * currentAngle / (2 * Math.PI);
var x = center.X + (int)Math.Round(Math.Cos(currentAngle) * vector);
var y = center.Y + (int)Math.Round(Math.Sin(currentAngle) * vector);
yield return new Point(x, y);
currentAngle += angle;
}
}
}
38 changes: 38 additions & 0 deletions cs/TagsCloudVisualization/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Drawing;
using TagsCloudVisualization.PointGenerator;

namespace TagsCloudVisualization;

public static class Program
{
private static void Main()
{
var imageWidth = 2500;
var imageHeight = 2500;
var imageCenter = new Point(imageWidth / 2, imageHeight / 2);
var rectangleSize = new Size(200, 80);
var imageSize = new Size(imageWidth, imageHeight);

var rectangles = CreateRandomSizeRectangles(150, imageCenter, rectangleSize);
var cloudRenderer = new TagCloudRenderer(imageSize);
var imageSaver = new ImageSaver();

var image = cloudRenderer.CreateRectangleCloud(rectangles);
imageSaver.Save(image, "cloud.png");
}

private static IEnumerable<Rectangle> CreateRandomSizeRectangles(int count, Point center, Size rectangleSize,
double minScaleFactor = 0.4, int maxPointsPerRectangle = 100000)
{
var pointGenerator = new SpiralPointGenerator(center);
var layouter = new CircularCloudLayouter.CircularCloudLayouter(center, maxPointsPerRectangle, pointGenerator);
var random = new Random(10);
for (var i = 0; i < count; i++)
{
var rnd = random.NextDouble() + minScaleFactor;
var rndWidth = (int)Math.Round(rectangleSize.Width * rnd);
var rndHeight = (int)Math.Round(rectangleSize.Height * rnd);
yield return layouter.PutNextRectangle(new Size(rndWidth, rndHeight));
}
}
}
2 changes: 2 additions & 0 deletions cs/TagsCloudVisualization/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
![cloud1.png](Image/cloud1.png)
![cloud2.png](Image/cloud2.png)
8 changes: 8 additions & 0 deletions cs/TagsCloudVisualization/Render/ICloudRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using System.Drawing;

namespace TagsCloudVisualization;

public interface ICloudRenderer
{
public Bitmap CreateRectangleCloud(IEnumerable<Rectangle> rectangles);

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.

Не совсем понял, что требуется

}
19 changes: 19 additions & 0 deletions cs/TagsCloudVisualization/Render/TagCloudRenderer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Drawing;

namespace TagsCloudVisualization;

public class TagCloudRenderer(Size imageSize) : ICloudRenderer
{
public Bitmap CreateRectangleCloud(IEnumerable<Rectangle> rectangles)
{
var bitmap = new Bitmap(imageSize.Width, imageSize.Height);

using var graphics = Graphics.FromImage(bitmap);
graphics.Clear(Color.FromArgb(0, 34, 43));
var pen = new Pen(Color.FromArgb(212, 85, 0), 2);
foreach (var rect in rectangles)
graphics.DrawRectangle(pen, rect);

return bitmap;
}
}
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>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="10.0.0" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=imagesaver/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=render/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
Loading