-
Notifications
You must be signed in to change notification settings - Fork 307
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
Зиновьева Милана #244
base: master
Are you sure you want to change the base?
Зиновьева Милана #244
Changes from 8 commits
47e27fe
80c6f63
627f537
0b4df01
85cbeba
8f0befd
76bfcc8
d4fb1cd
4a2c28a
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,58 @@ | ||
using System.Drawing; | ||
using TagsCloudVisualization; | ||
|
||
namespace DrawingTagsCloudVisualization; | ||
|
||
public class DrawingExamples | ||
{ | ||
static void Main() | ||
{ | ||
DrawImage_DecreasingRectangles120(); | ||
DrawImage_MixedRectangles320(); | ||
DrawImage_EqualsRectangles250(); | ||
} | ||
|
||
public static void DrawImage_EqualsRectangles250() | ||
{ | ||
var tempLayouter = new CircularCloudLayouter(new Point(400, 400)); | ||
for (int i = 0; i < 250; i++) | ||
tempLayouter.PutNextRectangle(new Size(10, 5)); | ||
DrawingTagsCloud drawingTagsCloud = new DrawingTagsCloud(new Point(tempLayouter.CenterCloud.X * 2, tempLayouter.CenterCloud.Y * 2), tempLayouter.GetRectangles); | ||
drawingTagsCloud.SaveToFile("EqualsRectangles250.png"); | ||
} | ||
|
||
public static void DrawImage_MixedRectangles320() | ||
{ | ||
var tempLayouter = new CircularCloudLayouter(new Point(400, 400)); | ||
var rectanglesSizes = new List<Size> | ||
{ | ||
new Size(10, 5), | ||
new Size(8, 8), | ||
new Size(12, 3), | ||
new Size(6, 10) | ||
}; | ||
for (int i = 0; i < 80; i++) | ||
{ | ||
foreach (var size in rectanglesSizes) | ||
tempLayouter.PutNextRectangle(size); | ||
} | ||
DrawingTagsCloud drawingTagsCloud = new DrawingTagsCloud(new Point(tempLayouter.CenterCloud.X * 2, tempLayouter.CenterCloud.Y * 2), tempLayouter.GetRectangles); | ||
drawingTagsCloud.SaveToFile("MixedRectangles320.png"); | ||
} | ||
|
||
public static void DrawImage_DecreasingRectangles120() | ||
{ | ||
var tempLayouter = new CircularCloudLayouter(new Point(400, 400)); | ||
tempLayouter.PutNextRectangle(new Size(160, 180)); | ||
for (int i = 0; i < 80; i++) | ||
{ | ||
tempLayouter.PutNextRectangle(new Size(60, 40)); | ||
} | ||
for (int i = 0; i < 39; i++) | ||
{ | ||
tempLayouter.PutNextRectangle(new Size(20, 25)); | ||
} | ||
DrawingTagsCloud drawingTagsCloud = new DrawingTagsCloud(new Point(tempLayouter.CenterCloud.X * 2, tempLayouter.CenterCloud.Y * 2), tempLayouter.GetRectangles); | ||
drawingTagsCloud.SaveToFile("DecreasingRectangles120.png"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using Microsoft.Maui.Graphics; | ||
using Microsoft.Maui.Graphics.Skia; | ||
using System.Drawing; | ||
|
||
namespace DrawingTagsCloudVisualization; | ||
|
||
public class DrawingTagsCloud | ||
{ | ||
private readonly System.Drawing.Point centercloud; | ||
private readonly List<Rectangle> rectangles; | ||
|
||
public DrawingTagsCloud(System.Drawing.Point center, List<Rectangle> rectanglesInput) | ||
{ | ||
this.centercloud = center; | ||
this.rectangles = rectanglesInput; | ||
} | ||
|
||
public void SaveToFile(string filePath) | ||
{ | ||
using var bitmapContext = new SkiaBitmapExportContext(800, 800, 2.0f); | ||
|
||
var canvas = bitmapContext.Canvas; | ||
canvas.FontColor = Colors.Black; | ||
canvas = Draw(canvas); | ||
using var image = bitmapContext.Image; | ||
using var stream = File.OpenWrite(filePath); | ||
image.Save(stream); | ||
} | ||
|
||
private ICanvas Draw(ICanvas canvas) | ||
{ | ||
canvas.FillColor = Colors.Blue; | ||
canvas.FontColor = Colors.Black; | ||
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. Зачем ты дважды задала цвет шрифту? |
||
|
||
foreach (var rect in rectangles) | ||
{ | ||
canvas.FillRectangle(rect.X, rect.Y, rect.Width, rect.Height); | ||
} | ||
return canvas; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
|
||
<IsPackable>false</IsPackable> | ||
<IsTestProject>false</IsTestProject> | ||
<OutputType>Exe</OutputType> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Maui.Graphics" Version="9.0.0" /> | ||
<PackageReference Include="Microsoft.Maui.Graphics.Skia" Version="9.0.0" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="../TagsCloudVisualization/TagsCloudVisualization.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
Увеличивающися по размеру прямоугольники | ||
![alt text](DecreasingRectangles120.png) | ||
|
||
|
||
Одинаковые прямоугольники | ||
![alt text](EqualsRectangles250.png) | ||
|
||
|
||
Прямоугольники разных размеров | ||
![alt text](MixedRectangles320.png) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
using System.Drawing; | ||
|
||
namespace TagsCloudVisualization; | ||
|
||
public class CircularCloudLayouter | ||
{ | ||
private Spiral spiral; | ||
private Point centerСloud; | ||
|
||
private List<Rectangle> rectangles; | ||
|
||
public Point CenterCloud => centerСloud; | ||
|
||
public List<Rectangle> GetRectangles => rectangles; | ||
|
||
public CircularCloudLayouter(Point center) | ||
{ | ||
this.centerСloud = center; | ||
this.spiral = new Spiral(center); | ||
this.rectangles = new List<Rectangle>(); | ||
} | ||
|
||
public Rectangle PutNextRectangle(Size rectangleSize) | ||
{ | ||
if (rectangleSize.IsEmpty) | ||
{ | ||
throw new ArgumentNullException("rectangle is empty"); | ||
} | ||
if (rectangleSize.Height <= 0 || rectangleSize.Width <= 0) | ||
{ | ||
throw new ArgumentOutOfRangeException("side less or equal zero"); | ||
} | ||
Rectangle tempRectangle; | ||
do | ||
{ | ||
Point nextPoint = spiral.GetNextPoint(); | ||
tempRectangle = new Rectangle(new Point(nextPoint.X, nextPoint.Y), rectangleSize); | ||
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. так же можно было использовать with expression |
||
} | ||
while (IsRectangleIntersect(tempRectangle)); | ||
if (rectangles.Count > 1) | ||
tempRectangle = TryToMoveRectangleNearToCenter(tempRectangle); | ||
rectangles.Add(tempRectangle); | ||
return tempRectangle; | ||
} | ||
|
||
private Rectangle TryToMoveRectangleNearToCenter(Rectangle rectangle) | ||
{ | ||
while (true) | ||
{ | ||
var tempRectangle = rectangle; | ||
if (rectangle.X != centerСloud.X) | ||
{ | ||
var directionX = rectangle.X < centerСloud.X ? 1 : -1; | ||
rectangle = CanMove(rectangle, true, directionX); | ||
} | ||
if (rectangle.Y != centerСloud.Y) | ||
{ | ||
var directionY = rectangle.Y < centerСloud.Y ? 1 : -1; | ||
rectangle = CanMove(rectangle, false, directionY); | ||
} | ||
|
||
if (tempRectangle.Equals(rectangle)) | ||
break; | ||
} | ||
return rectangle; | ||
} | ||
|
||
private Rectangle CanMove(Rectangle rectangle, bool isX, int direction) | ||
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.
|
||
{ | ||
var shiftPoint = isX ? new Point(direction, 0) : new Point(0, direction); | ||
var movedRectangle = new Rectangle( | ||
new Point(rectangle.X + shiftPoint.X, rectangle.Y + shiftPoint.Y), | ||
rectangle.Size); | ||
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. Посмотри на with expression |
||
|
||
if (!IsRectangleIntersect(movedRectangle)) | ||
{ | ||
rectangle = movedRectangle; | ||
} | ||
return rectangle; | ||
} | ||
|
||
private bool IsRectangleIntersect(Rectangle rectangleChecked) => | ||
rectangles.Any(rectangleChecked.IntersectsWith); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
using System.Drawing; | ||
|
||
namespace TagsCloudVisualization; | ||
|
||
public class Spiral | ||
{ | ||
private readonly Point startPoint; | ||
private readonly double radiusStep; | ||
private readonly double angleStep; | ||
private double currentAngle; | ||
|
||
public Spiral(Point startPoint, double radiusStep = 1) | ||
{ | ||
if (radiusStep <= 0) throw new ArgumentOutOfRangeException(nameof(radiusStep), "radius step must be positive"); | ||
|
||
this.angleStep = Math.PI / 180; | ||
this.startPoint = startPoint; | ||
this.radiusStep = radiusStep; | ||
this.currentAngle = 0; | ||
} | ||
|
||
public Point GetNextPoint() | ||
{ | ||
var radius = radiusStep * currentAngle; | ||
|
||
var x = (int)(startPoint.X + radius * Math.Cos(currentAngle)); | ||
var y = (int)(startPoint.Y + radius * Math.Sin(currentAngle)); | ||
currentAngle += angleStep; | ||
|
||
return new Point(x, y); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
|
||
<IsPackable>false</IsPackable> | ||
<IsTestProject>false</IsTestProject> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="NUnit" Version="3.14.0" /> | ||
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" /> | ||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.1"> | ||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||
<PrivateAssets>all</PrivateAssets> | ||
</PackageReference> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<Using Include="NUnit.Framework" /> | ||
</ItemGroup> | ||
Comment on lines
+12
to
+23
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. Неиспользуемые пакеты стоит удалять из проекта |
||
|
||
</Project> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
using NUnit.Framework; | ||
using FluentAssertions; | ||
using System.Drawing; | ||
using TagsCloudVisualization; | ||
|
||
namespace TagsCloudVisualizationTests; | ||
|
||
public class TestsSpiral | ||
{ | ||
|
||
Spiral currentSpiral; | ||
[SetUp] | ||
public void SetUp() | ||
{ | ||
currentSpiral = new Spiral(new Point(0, 0)); | ||
} | ||
|
||
[Test] | ||
public void Spiral_ThrowingWhenRadiusNonPositive() | ||
{ | ||
Action action = new Action(() => new Spiral(new Point(0, 0), -9)); | ||
action.Should().Throw<ArgumentOutOfRangeException>().Which.Message.Should().Contain("radius step must be positive"); | ||
} | ||
|
||
[Test] | ||
public void GetNextPoint_CenterPointSetting() | ||
{ | ||
currentSpiral.GetNextPoint().Should().Be(new Point(0, 0)); | ||
} | ||
|
||
[Test] | ||
public void GetNextPoint_SeveralPointSetting() | ||
{ | ||
for (int i = 0; i < 180; i++) | ||
{ | ||
currentSpiral.GetNextPoint(); | ||
} | ||
currentSpiral.GetNextPoint().Should().Be(new Point((int)-Math.PI, 0)); | ||
} | ||
|
||
} |
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.
Указание типа точки можно сделать короче