-
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
Калентьев Илья tg: @m1nus0ne #22
base: master
Are you sure you want to change the base?
Changes from all 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,9 @@ | ||
using System.Drawing; | ||
using TagCloud; | ||
|
||
namespace TagCloudTests; | ||
|
||
public interface ICloudDrawer | ||
{ | ||
void Draw(List<TextRectangle> rectangle); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
using System.Drawing; | ||
using TagCloud.Extensions; | ||
using TagCloudTests; | ||
|
||
namespace TagCloud; | ||
|
||
public class TagCloudDrawer : ICloudDrawer | ||
{ | ||
private readonly string path; | ||
private readonly IColorSelector selector; | ||
private readonly string name; | ||
private readonly Font font; | ||
|
||
private TagCloudDrawer(string path, string name, IColorSelector selector, Font font) | ||
{ | ||
this.path = path; | ||
this.selector = selector; | ||
this.font = font; | ||
this.name = name; | ||
} | ||
|
||
public void Draw(List<TextRectangle> rectangles) | ||
{ | ||
if (rectangles.Count == 0) | ||
throw new ArgumentException("Empty rectangles list"); | ||
|
||
var containingRect = rectangles | ||
.Select(r => r.Rectangle) | ||
.GetMinimalContainingRectangle(); | ||
|
||
using var bitmap = new Bitmap(containingRect.Width + 2, containingRect.Height + 2); | ||
using var graphics = Graphics.FromImage(bitmap); | ||
|
||
graphics.DrawStrings( | ||
selector, | ||
rectangles | ||
.Select(rect => rect.OnLocation(-containingRect.X + rect.X, -containingRect.Y + rect.Y)) | ||
.ToArray() | ||
); | ||
|
||
SaveToFile(bitmap); | ||
} | ||
|
||
private void SaveToFile(Bitmap bitmap) | ||
{ | ||
var pathToFile = @$"{path}\{name}"; | ||
bitmap.Save(pathToFile); | ||
Console.WriteLine($"Tag cloud visualization saved to file {path}"); | ||
} | ||
|
||
public static TagCloudDrawer Create(string path, string name, Font font, IColorSelector selector) | ||
{ | ||
if (!Directory.Exists(path)) | ||
throw new ArgumentException("Directory does not exist"); | ||
return new TagCloudDrawer(path, name, selector, font); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using System.Drawing; | ||
|
||
namespace TagCloud; | ||
|
||
public class CloudLayouter | ||
{ | ||
private List<Rectangle> rectangles; | ||
private ICloudShaper shaper; | ||
|
||
public IReadOnlyList<Rectangle> Rectangles => rectangles; | ||
|
||
public CloudLayouter(ICloudShaper shaper) | ||
{ | ||
rectangles = new List<Rectangle>(); | ||
this.shaper = shaper; | ||
} | ||
|
||
public Rectangle PutNextRectangle(Size size) | ||
{ | ||
if (size.Width <= 0) | ||
throw new ArgumentException("Size width must be positive number"); | ||
if (size.Height <= 0) | ||
throw new ArgumentException("Size height must be positive number"); | ||
|
||
Rectangle rectangle = Rectangle.Empty; | ||
foreach (var point in shaper.GetPossiblePoints()) | ||
{ | ||
rectangle = new Rectangle(point, size); | ||
if (!Rectangles.Any(rect => rect.IntersectsWith(rectangle))) | ||
break; | ||
} | ||
|
||
rectangles.Add(rectangle); | ||
return rectangle; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using System.Drawing; | ||
|
||
namespace TagCloud; | ||
|
||
public interface ICloudShaper | ||
{ | ||
IEnumerable<Point> GetPossiblePoints(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
using System.Drawing; | ||
|
||
namespace TagCloud; | ||
|
||
public class SpiralCloudShaper : ICloudShaper | ||
{ | ||
private Point center; | ||
private double coefficient; | ||
private double deltaAngle; | ||
|
||
private SpiralCloudShaper(Point center, double coefficient, double deltaAngle) | ||
{ | ||
this.center = center; | ||
this.deltaAngle = deltaAngle; | ||
this.coefficient = coefficient; | ||
} | ||
|
||
public IEnumerable<Point> GetPossiblePoints() | ||
{ | ||
var currentAngle = 0D; | ||
var position = center; | ||
var previousPoint = position; | ||
while(true) | ||
{ | ||
while (position == previousPoint) | ||
{ | ||
currentAngle += deltaAngle; | ||
previousPoint = position; | ||
position = CalculatePointByCurrentAngle(currentAngle); | ||
} | ||
yield return position; | ||
previousPoint = position; | ||
position = CalculatePointByCurrentAngle(currentAngle); | ||
} | ||
} | ||
|
||
private Point CalculatePointByCurrentAngle(double angle) | ||
{ | ||
return new Point( | ||
center.X + (int)(coefficient * angle * Math.Cos(angle)), | ||
center.Y + (int)(coefficient * angle * Math.Sin(angle)) | ||
); | ||
} | ||
|
||
public static SpiralCloudShaper Create(Point center, double coefficient = 0.1, double deltaAngle = 0.1) | ||
{ | ||
if (coefficient <= 0) | ||
throw new ArgumentException("Spiral coefficient must be positive number"); | ||
if (deltaAngle <= 0) | ||
throw new ArgumentException("Spiral delta angle must be positive number"); | ||
return new SpiralCloudShaper(center, coefficient, deltaAngle); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System.Drawing; | ||
using TagCloudTests; | ||
|
||
namespace TagCloud; | ||
|
||
public class ConstantColorSelector : IColorSelector | ||
{ | ||
private Color color; | ||
public ConstantColorSelector(Color color) | ||
{ | ||
this.color = color; | ||
} | ||
|
||
public Color SetColor() => color; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
using System.Drawing; | ||
|
||
namespace TagCloudTests; | ||
|
||
public class GrayScaleColorSelector : IColorSelector | ||
{ | ||
private readonly Random random = new(DateTime.Now.Microsecond); | ||
|
||
public Color SetColor() | ||
{ | ||
var gray = random.Next(100, 200); | ||
return Color.FromArgb(gray, gray, gray); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
using System.Drawing; | ||
|
||
namespace TagCloudTests; | ||
|
||
public interface IColorSelector | ||
{ | ||
Color SetColor(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System.Drawing; | ||
|
||
namespace TagCloud.ColorSelectors; | ||
|
||
public class RandomColorSelector | ||
{ | ||
private readonly Random random = new(DateTime.Now.Microsecond); | ||
|
||
public Color SetColor() | ||
{ | ||
var color = random.Next(0, 255); | ||
return Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255)); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using System.Drawing; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace TagCloud.Extensions; | ||
|
||
public static class ColorConverter | ||
{ | ||
public static bool TryConvert(string hexString, out Color color) | ||
{ | ||
color = default; | ||
var colorHexRegExp = new Regex(@"^#([A-Fa-f0-9]{6})$"); | ||
if (colorHexRegExp.Count(hexString) != 1) | ||
return false; | ||
var rgbValue = hexString | ||
.Replace("#", "") | ||
.Chunk(2) | ||
.Select(chars => Convert.ToInt32(new string(chars), 16)) | ||
.ToArray(); | ||
Comment on lines
+14
to
+18
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. rgb коды могут задаваться 3 hex цифрами |
||
color = Color.FromArgb(rgbValue[0], rgbValue[1], rgbValue[2]); | ||
return true; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System.Drawing; | ||
using TagCloudTests; | ||
|
||
namespace TagCloud.Extensions; | ||
|
||
public static class GraphicsExtensions | ||
{ | ||
public static void DrawStrings(this Graphics graphics, IColorSelector selector, TextRectangle[] rectangles) | ||
{ | ||
using var brush = new SolidBrush(selector.SetColor()); | ||
foreach (var rectangle in rectangles) | ||
{ | ||
graphics.DrawString(rectangle.Text, rectangle.Font, brush, rectangle.X, rectangle.Y); | ||
brush.Color = selector.SetColor(); | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
using System.Drawing; | ||
|
||
namespace TagCloud.Extensions; | ||
|
||
public static class PointExtension | ||
{ | ||
public static double GetDistanceTo(this Point first, Point second) | ||
{ | ||
return Math.Sqrt((first.X - second.X) * (first.X - second.X) + (first.Y - second.Y) * (first.Y - second.Y)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
using System.Drawing; | ||
|
||
namespace TagCloud.Extensions; | ||
|
||
public static class RectangleEnumerableExtensions | ||
{ | ||
public static bool HasIntersectedRectangles(this IEnumerable<Rectangle> rectangles) | ||
{ | ||
return rectangles | ||
.SelectMany( | ||
(x, i) => rectangles.Skip(i + 1), | ||
(x, y) => Tuple.Create(x, y) | ||
) | ||
.Any(tuple => tuple.Item1.IntersectsWith(tuple.Item2)); | ||
} | ||
|
||
public static Rectangle GetMinimalContainingRectangle(this IEnumerable<Rectangle> rectangles) | ||
{ | ||
int minX = int.MaxValue, minY = int.MaxValue; | ||
int maxX = int.MinValue, maxY = int.MinValue; | ||
|
||
foreach (var rectangle in rectangles) | ||
{ | ||
if (rectangle.X < minX) | ||
minX = rectangle.X; | ||
if (rectangle.Y < minY) | ||
minY = rectangle.Y; | ||
if (rectangle.Right > maxX) | ||
maxX = rectangle.Right; | ||
if (rectangle.Bottom > maxY) | ||
maxY = rectangle.Bottom; | ||
} | ||
|
||
return new Rectangle(minX, minY, maxX - minX, maxY- minY); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
using CommandLine; | ||
|
||
namespace TagCloudApplication; | ||
|
||
public class Options | ||
{ | ||
[Option('d', "destination", HelpText = "Set destination path.", Default = @"..\..\..\Results")] | ||
public string DestinationPath { get; set; } | ||
|
||
[Option('s', "source", HelpText = "Set source path.", Default = @"..\..\..\Results\text.txt")] | ||
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 string SourcePath { get; set; } | ||
|
||
[Option('n', "name", HelpText = "Set name.", Default = "default.png")] | ||
public string Name { get; set; } | ||
|
||
[Option('c', "color", | ||
HelpText = """ | ||
Set color. | ||
random - Random colors | ||
#F0F0F0 - Color hex code | ||
""", | ||
Default = "random")] | ||
public string ColorScheme { get; set; } | ||
|
||
[Option('f', "font", HelpText = "Set font.", Default = "Arial")] | ||
public string Font { get; set; } | ||
|
||
[Option("size", HelpText = "Set font size.", Default = 20)] | ||
public int FontSize { get; set; } | ||
|
||
[Option("unusedParts", | ||
HelpText = """ | ||
Set unused parts of speech. | ||
A - прилагательное | ||
ADV - наречие | ||
ADVPRO - местоименное наречие | ||
ANUM - числительное-прилагательное | ||
APRO - местоимение-прилагательное | ||
COM - часть композита - сложного слова | ||
CONJ - союз | ||
INTJ - междометие | ||
NUM - числительное | ||
PART - частица | ||
PR - предлог | ||
S - существительное | ||
SPRO - местоимение-существительное | ||
V - глагол | ||
""", | ||
Default = new[] { "PR", "PART", "CONJ", "INTJ" })] | ||
public string[] UnusedPartsOfSpeech { get; set; } | ||
|
||
[Option("density", HelpText = "Set density.", Default = 0.1)] | ||
public double Density { get; set; } | ||
|
||
[Option("width", HelpText = "Set width.", Default = 100)] | ||
public int Width { get; set; } | ||
|
||
|
||
[Option("height", HelpText = "Set height.", Default = 100)] | ||
public int Height { get; set; } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// See https://aka.ms/new-console-template for more information | ||
|
||
Console.WriteLine("Hello, World!"); |
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.
Сейчас это не так важно, потому, что код запуститься только на windows из-за зависимостей, но на будущее, для обьединения путей стоит использовать Path.Combine или хотя бы Path.PathSeparator