-
Notifications
You must be signed in to change notification settings - Fork 32
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
Брозовский Максим #11
base: master
Are you sure you want to change the base?
Changes from 4 commits
5453288
b6288bd
afd86e6
de0ed04
327d8fb
c5ef143
c7671c0
80c03cc
1eba8f1
3cda932
510a712
94c11d8
aa7e004
a462b92
69a8c1f
ccf1bbb
1091338
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,40 @@ | ||
using SkiaSharp; | ||
using TagCloud.PointsGenerator; | ||
|
||
namespace TagCloud.CloudLayouter; | ||
|
||
public class CircularCloudLayouter(SKPoint center) : ICloudLayouter | ||
{ | ||
private const double OptimalRadius = 1; | ||
private const double OptimalAngleOffset = 0.5; | ||
|
||
private readonly List<SKRect> rectangles = []; | ||
private readonly SpiralPointsGenerator pointsGenerator = new(center, OptimalRadius, OptimalAngleOffset); | ||
|
||
public SKPoint Center => center; | ||
public IEnumerable<SKRect> Rectangles => rectangles; | ||
|
||
public SKRect PutNextRectangle(SKSize rectangleSize) | ||
{ | ||
while (true) | ||
{ | ||
var rectanglePosition = pointsGenerator.GetNextPoint(); | ||
var rectangle = CreateRectangleWithCenter(rectanglePosition, rectangleSize); | ||
|
||
if (rectangles.Any(rectangle.IntersectsWith)) continue; | ||
|
||
rectangles.Add(rectangle); | ||
|
||
return rectangle; | ||
} | ||
} | ||
|
||
private static SKRect CreateRectangleWithCenter(SKPoint center, SKSize rectangleSize) | ||
{ | ||
var left = center.X - rectangleSize.Width / 2; | ||
var top = center.Y - rectangleSize.Height / 2; | ||
|
||
return new SKRect(left, top, left + rectangleSize.Width, top + rectangleSize.Height); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using SkiaSharp; | ||
|
||
namespace TagCloud.CloudLayouter; | ||
|
||
public interface ICloudLayouter | ||
{ | ||
public SKRect PutNextRectangle(SKSize rectangleSize); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using SkiaSharp; | ||
|
||
namespace TagCloud.PointsGenerator; | ||
|
||
public interface IPointsGenerator | ||
{ | ||
public SKPoint GetNextPoint(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using SkiaSharp; | ||
|
||
namespace TagCloud.PointsGenerator; | ||
|
||
public class SpiralPointsGenerator : IPointsGenerator | ||
{ | ||
private readonly double angleOffset; | ||
private readonly double radius; | ||
private readonly SKPoint start; | ||
private double angle; | ||
|
||
public SpiralPointsGenerator(SKPoint start, double radius, double angleOffset) | ||
{ | ||
if (radius <= 0) | ||
throw new ArgumentException("radius must be greater than 0"); | ||
if (angleOffset <= 0) | ||
throw new ArgumentException("angleOffset must be greater than 0"); | ||
|
||
this.angleOffset = angleOffset * Math.PI / 180; | ||
this.radius = radius; | ||
this.start = start; | ||
} | ||
|
||
public SKPoint GetNextPoint() | ||
{ | ||
var nextPoint = GetPointByPolarCords(); | ||
angle += angleOffset; | ||
return nextPoint; | ||
} | ||
|
||
private SKPoint GetPointByPolarCords() | ||
{ | ||
var offsetPerRadian = radius / (2 * Math.PI); | ||
var radiusVector = offsetPerRadian * angle; | ||
|
||
var x = (int)Math.Round(radiusVector * Math.Cos(angle) + start.X); | ||
var y = (int)Math.Round(radiusVector * Math.Sin(angle) + start.Y); | ||
|
||
return new SKPoint(x, y); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="CsvHelper" Version="33.0.1" /> | ||
<PackageReference Include="DocX" Version="3.0.1" /> | ||
<PackageReference Include="SkiaSharp" Version="3.116.1" /> | ||
<PackageReference Include="WeCantSpell.Hunspell" Version="5.2.1" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using TagCloud.Visualization; | ||
using TagCloud.WordsFilter; | ||
using TagCloud.WordsReader; | ||
|
||
namespace TagCloud; | ||
|
||
public class TagCloudGenerator(IWordsReader reader, TagCloudImageGenerator imageGenerator, | ||
IEnumerable<IWordsFilter> filters) | ||
{ | ||
public string GenerateTagCloud() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
namespace TagCloud.Utility; | ||
|
||
public static class EnumerableExtensions | ||
{ | ||
public static string Join(this IEnumerable<string> words, string separator = "") => string.Join(separator, words); | ||
|
||
public static IEnumerable<string> ToLower(this IEnumerable<string> words) => words.Select(w => w.ToLower()); | ||
} | ||
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. Как будто лишняя оболочка уже существующих методов 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. Убрал |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
using SkiaSharp; | ||
|
||
namespace TagCloud.Utility; | ||
|
||
public static class RandomExtensions | ||
{ | ||
public static SKSize NextSkSize(this Random random, int minValue, int maxValue) | ||
{ | ||
if (minValue <= 0) | ||
throw new ArgumentOutOfRangeException(nameof(minValue), "minValue must be greater than 0"); | ||
if (maxValue < minValue) | ||
throw new ArgumentOutOfRangeException(nameof(maxValue), "maxValue must be greater than minValue"); | ||
|
||
return new SKSize(random.Next(minValue, maxValue), random.Next(minValue, maxValue)); | ||
} | ||
|
||
public static SKPoint NextSkPoint(this Random random, int minValue, int maxValue) => | ||
new (random.Next(minValue, maxValue), random.Next(minValue, maxValue)); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
using SkiaSharp; | ||
|
||
namespace TagCloud.Visualization; | ||
|
||
public class TagCloudImageGenerator(SKSizeI Size, SKTypeface fontFamily ,SKColor background, SKColor foreground) | ||
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 SKBitmap CreateBitmap(List<SKRect> rectangles) | ||
{ | ||
var bitmap = new SKBitmap(Size.Width, Size.Height); | ||
var canvas = new SKCanvas(bitmap); | ||
var paint = new SKPaint | ||
{ | ||
Color = SKColors.Black, | ||
Style = SKPaintStyle.Stroke | ||
}; | ||
|
||
canvas.Clear(SKColors.White); | ||
|
||
var xOffset = bitmap.Width / 2f - rectangles.First().Location.X; | ||
var yOffset = bitmap.Height / 2f - rectangles.First().Location.Y; | ||
|
||
foreach (var rectangle in rectangles) | ||
{ | ||
rectangle.Offset(xOffset, yOffset); | ||
canvas.DrawRect(rectangle, paint); | ||
} | ||
|
||
return bitmap; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using SkiaSharp; | ||
|
||
namespace TagCloud.Visualization; | ||
|
||
public static class TagCloudSaver | ||
{ | ||
private const int ImageQuality = 80; | ||
private const string DefaultImageDirectory = "../../../imgs"; | ||
|
||
public static string Save(SKBitmap bitmap, string filePath, | ||
SKEncodedImageFormat format = SKEncodedImageFormat.Png) | ||
{ | ||
var defaultImagePath = Path.Combine(DefaultImageDirectory, $"{DateTime.Now:yy-MM-dd-HH-mm}"); | ||
var path = Path.GetDirectoryName(filePath) ?? defaultImagePath; | ||
Directory.CreateDirectory(path); | ||
var formatName = Enum.GetName(typeof(SKEncodedImageFormat), format)!.ToLower(); | ||
using var file = File.OpenWrite($"{filePath}.{formatName}"); | ||
bitmap.Encode(format, ImageQuality).SaveTo(file); | ||
|
||
return path; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace TagCloud.WordsFilter; | ||
|
||
public class BoringWordsFilter : IWordsFilter | ||
{ | ||
// TODO: implement me | ||
public List<string> ApplyFilter(List<string> words) | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace TagCloud.WordsFilter; | ||
|
||
public interface IWordsFilter | ||
{ | ||
// Applying filter on list of words | ||
List<string> ApplyFilter(List<string> words); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace TagCloud.WordsReader; | ||
|
||
public class CsvFileReader : IWordsReader | ||
{ | ||
// TODO: implement me | ||
public List<string> ReadWords() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace TagCloud.WordsReader; | ||
|
||
public class FileReader : IWordsReader | ||
{ | ||
// TODO: implement me | ||
public List<string> ReadWords() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace TagCloud.WordsReader; | ||
|
||
public interface IWordsReader | ||
{ | ||
// Reads words from filestream | ||
List<string> ReadWords(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
namespace TagCloud.WordsReader; | ||
|
||
public class WordFileReader : IWordsReader | ||
{ | ||
// TODO: implement me | ||
public List<string> ReadWords() | ||
{ | ||
throw new NotImplementedException(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
namespace TagCloudClient; | ||
|
||
public class Options | ||
{ | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
| ||
namespace TagCloudClient; | ||
|
||
internal class Program | ||
{ | ||
public static void Main(string[] args) | ||
{ | ||
// TODO: console application goes here | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\TagCloud\TagCloud.csproj" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Autofac" Version="8.2.0" /> | ||
<PackageReference Include="CommandLineParser" Version="2.9.1" /> | ||
</ItemGroup> | ||
|
||
</Project> |
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.
Можно вынести в какой-нибудь класс конфигурации для настройки layouter'a и передавать в него как настройки