Skip to content

Commit e98afd7

Browse files
committed
Added several Dynamic Rectangle grids (Root-N Rectangle, Golden Rectangle).
1 parent 57f5676 commit e98afd7

5 files changed

Lines changed: 243 additions & 0 deletions

File tree

Src/ScreenGrid.Models/Geometry/Rectangle.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,22 @@ public double Bottom
5959
}
6060
}
6161

62+
public double CenterX
63+
{
64+
get
65+
{
66+
return this.X + this.Width / 2.0;
67+
}
68+
}
69+
70+
public double CenterY
71+
{
72+
get
73+
{
74+
return this.Y + this.Height / 2.0;
75+
}
76+
}
77+
6278
public bool IsEmpty
6379
{
6480
get

Src/ScreenGrid.Models/Grids/GridCreator.cs

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ public static Point TransformPoint(
8484
/// <returns>List of lines</returns>
8585
public static IEnumerable<Line> CreateGrid(GridType gridType, double width, double height, bool isRotated)
8686
{
87+
var actualAspectRatio = CalculateAspectRatio(width, height, isRotated);
88+
8789
switch (gridType)
8890
{
8991
case GridType.None:
@@ -368,6 +370,113 @@ public static IEnumerable<Line> CreateGrid(GridType gridType, double width, doub
368370
throw new ArgumentOutOfRangeException(gridType.ToString());
369371
}
370372

373+
return lines;
374+
}
375+
////case GridType.OneDotFiveRectangle:
376+
//// {
377+
//// var rectangle = CalculateDynamicRectangleExtents(1.5 / RatioConstants.One, actualAspectRatio);
378+
//// var lines = CreateRootNRectangle(rectangle);
379+
//// // TODO: armature
380+
//// return lines;
381+
//// }
382+
case GridType.GoldenRectangle:
383+
{
384+
var rectangle = CalculateDynamicRectangleExtents(RatioConstants.Phi / RatioConstants.One, actualAspectRatio);
385+
var lines = CreateRootNRectangle(rectangle);
386+
387+
var w = rectangle.Width * RatioConstants.Phi3D8;
388+
var h = rectangle.Height * RatioConstants.Phi3D8;
389+
390+
lines.Add(new Line(rectangle.Left, rectangle.Top + h, rectangle.Right, rectangle.Top + h));
391+
lines.Add(new Line(rectangle.Left, rectangle.Bottom - h, rectangle.Right, rectangle.Bottom - h));
392+
lines.Add(new Line(rectangle.Left + w, rectangle.Top, rectangle.Left + w, rectangle.Bottom));
393+
lines.Add(new Line(rectangle.Right - w, rectangle.Top, rectangle.Right - w, rectangle.Bottom));
394+
// Left
395+
lines.Add(new Line(rectangle.Left, rectangle.Top, rectangle.Left + w, rectangle.Bottom));
396+
lines.Add(new Line(rectangle.Left, rectangle.Bottom, rectangle.Left + w, rectangle.Top));
397+
// Right
398+
lines.Add(new Line(rectangle.Right, rectangle.Top, rectangle.Right - w, rectangle.Bottom));
399+
lines.Add(new Line(rectangle.Right, rectangle.Bottom, rectangle.Right - w, rectangle.Top));
400+
401+
return lines;
402+
}
403+
////case GridType.RootPhiRectangle:
404+
//// {
405+
//// var rectangle = CalculateDynamicRectangleExtents(RatioConstants.RootPhi / RatioConstants.One, actualAspectRatio);
406+
//// // TODO: armature
407+
//// return CreateRootNRectangle(rectangle);
408+
//// }
409+
case GridType.Root2Rectangle:
410+
{
411+
var rectangle = CalculateDynamicRectangleExtents(RatioConstants.Root2 / RatioConstants.One, actualAspectRatio);
412+
var lines = CreateRootNRectangle(rectangle);
413+
lines.Add(new Line(rectangle.Left, RatioConstants.Half, rectangle.Right, RatioConstants.Half));
414+
lines.Add(new Line(RatioConstants.Half, rectangle.Top, RatioConstants.Half, rectangle.Bottom));
415+
lines.Add(new Line(rectangle.Left, rectangle.Bottom, RatioConstants.Half, rectangle.Top));
416+
lines.Add(new Line(rectangle.Left, rectangle.Top, RatioConstants.Half, rectangle.Bottom));
417+
lines.Add(new Line(RatioConstants.Half, rectangle.Bottom, rectangle.Right, rectangle.Top));
418+
lines.Add(new Line(RatioConstants.Half, rectangle.Top, rectangle.Right, rectangle.Bottom));
419+
return lines;
420+
}
421+
case GridType.Root3Rectangle:
422+
{
423+
var rectangle = CalculateDynamicRectangleExtents(RatioConstants.Root3 / RatioConstants.One, actualAspectRatio);
424+
var lines = CreateRootNRectangle(rectangle);
425+
lines.AddRange(CreateRegularLines(rectangle, 2));
426+
var w = rectangle.Width / 3.0;
427+
// Left
428+
lines.Add(new Line(rectangle.Left, rectangle.Top, rectangle.Left + w, rectangle.Bottom));
429+
lines.Add(new Line(rectangle.Left, rectangle.Bottom, rectangle.Left + w, rectangle.Top));
430+
// Right
431+
lines.Add(new Line(rectangle.Right, rectangle.Top, rectangle.Right - w, rectangle.Bottom));
432+
lines.Add(new Line(rectangle.Right, rectangle.Bottom, rectangle.Right - w, rectangle.Top));
433+
// Two horizontals
434+
var h = rectangle.Height / 3.0;
435+
lines.Add(new Line(rectangle.Left, rectangle.Top + h, rectangle.Right, rectangle.Top + h));
436+
lines.Add(new Line(rectangle.Left, rectangle.Bottom - h, rectangle.Right, rectangle.Bottom - h));
437+
return lines;
438+
}
439+
case GridType.Root4Rectangle:
440+
{
441+
var rectangle = CalculateDynamicRectangleExtents(RatioConstants.Root4 / RatioConstants.One, actualAspectRatio);
442+
var lines = CreateRootNRectangle(rectangle);
443+
lines.AddRange(CreateRegularLines(rectangle, 3));
444+
var w = rectangle.Width / 4.0;
445+
// Left
446+
lines.Add(new Line(rectangle.Left, rectangle.Top, rectangle.Left + w, rectangle.Bottom));
447+
lines.Add(new Line(rectangle.Left, rectangle.Bottom, rectangle.Left + w, rectangle.Top));
448+
// Right
449+
lines.Add(new Line(rectangle.Right, rectangle.Top, rectangle.Right - w, rectangle.Bottom));
450+
lines.Add(new Line(rectangle.Right, rectangle.Bottom, rectangle.Right - w, rectangle.Top));
451+
452+
lines.Add(new Line(rectangle.Left, rectangle.Bottom, rectangle.CenterX, rectangle.Top));
453+
lines.Add(new Line(rectangle.Right, rectangle.Bottom, rectangle.CenterX, rectangle.Top));
454+
lines.Add(new Line(rectangle.Left, rectangle.Top, rectangle.CenterX, rectangle.Bottom));
455+
lines.Add(new Line(rectangle.Right, rectangle.Top, rectangle.CenterX, rectangle.Bottom));
456+
// Two horizontals
457+
var h = rectangle.Height / 4.0;
458+
lines.Add(new Line(rectangle.Left, rectangle.Top + h, rectangle.Right, rectangle.Top + h));
459+
lines.Add(new Line(rectangle.Left, rectangle.Bottom - h, rectangle.Right, rectangle.Bottom - h));
460+
461+
return lines;
462+
}
463+
case GridType.Root5Rectangle:
464+
{
465+
var rectangle = CalculateDynamicRectangleExtents(RatioConstants.Root5 / RatioConstants.One, actualAspectRatio);
466+
var lines = CreateRootNRectangle(rectangle);
467+
lines.AddRange(CreateRegularLines(rectangle, 4));
468+
var w = rectangle.Width / 5.0;
469+
// Left
470+
lines.Add(new Line(rectangle.Left, rectangle.Top, rectangle.Left + w, rectangle.Bottom));
471+
lines.Add(new Line(rectangle.Left, rectangle.Bottom, rectangle.Left + w, rectangle.Top));
472+
// Right
473+
lines.Add(new Line(rectangle.Right, rectangle.Top, rectangle.Right - w, rectangle.Bottom));
474+
lines.Add(new Line(rectangle.Right, rectangle.Bottom, rectangle.Right - w, rectangle.Top));
475+
476+
var h = rectangle.Height / 5.0;
477+
lines.Add(new Line(rectangle.Left, rectangle.CenterY, rectangle.Right, rectangle.CenterY));
478+
lines.Add(new Line(rectangle.Left, rectangle.Top + h, rectangle.Right, rectangle.Top + h));
479+
lines.Add(new Line(rectangle.Left, rectangle.Bottom - h, rectangle.Right, rectangle.Bottom - h));
371480
return lines;
372481
}
373482
default:
@@ -377,6 +486,80 @@ public static IEnumerable<Line> CreateGrid(GridType gridType, double width, doub
377486
}
378487
}
379488

489+
private static double CalculateAspectRatio(double width, double height, bool isRotated = false)
490+
{
491+
return ((isRotated) ? (height / width) : (width / height));
492+
}
493+
494+
private static Rectangle CalculateDynamicRectangleExtents(double desiredAspectRatio, double actualAspectRatio)
495+
{
496+
double left, right, top, bottom;
497+
498+
if (desiredAspectRatio < actualAspectRatio)
499+
{
500+
var w = desiredAspectRatio / actualAspectRatio;
501+
left = RatioConstants.Half - w / 2.0;
502+
right = RatioConstants.Half + w / 2.0;
503+
top = RatioConstants.Zero;
504+
bottom = RatioConstants.One;
505+
}
506+
else
507+
{
508+
var h = actualAspectRatio / desiredAspectRatio;
509+
left = RatioConstants.Zero;
510+
right = RatioConstants.One;
511+
top = RatioConstants.Half - h / 2.0;
512+
bottom = RatioConstants.Half + h / 2.0;
513+
}
514+
515+
return new Rectangle { X = left, Y = top, Width = right - left, Height = bottom - top };
516+
}
517+
518+
private static List<Line> CreateRootNRectangle(Rectangle rectangle)
519+
{
520+
double left, right, top, bottom;
521+
left = rectangle.Left;
522+
right = rectangle.Right;
523+
top = rectangle.Top;
524+
bottom = rectangle.Bottom;
525+
526+
var lines = new List<Line>();
527+
528+
lines.Add(new Line(left, top, left, bottom));
529+
lines.Add(new Line(right, top, right, bottom));
530+
lines.Add(new Line(left, top, right, top));
531+
lines.Add(new Line(left, bottom, right, bottom));
532+
533+
// Main diagonals
534+
lines.Add(new Line(left, top, right, bottom));
535+
lines.Add(new Line(left, bottom, right, top));
536+
537+
return lines;
538+
}
539+
540+
private static IList<Line> CreateRegularLines(Rectangle rectangle, int numSplits)
541+
{
542+
var lines = new List<Line>();
543+
544+
var step = 1.0 / ((double)(numSplits + 1));
545+
var horizontalStep = step * rectangle.Width;
546+
//var verticalStep = step * rectangle.Height;
547+
for (var i = 0; i < numSplits; i++)
548+
{
549+
lines.Add(new Line(
550+
rectangle.Left + (i + 1) * horizontalStep,
551+
rectangle.Top,
552+
rectangle.Left + (i + 1) * horizontalStep,
553+
rectangle.Bottom));
554+
//if ((gridType == GridType.Root2Rectangle) || (gridType == GridType.Root3Rectangle))
555+
//{
556+
// lines.Add(new Line(left, top + (i + 1) * verticalStep, right, top + (i + 1) * verticalStep));
557+
//}
558+
}
559+
560+
return lines;
561+
}
562+
380563
private static List<Line> StretchToRectangleWithAspectRatio(List<Line> lines, double aspect, double left, double right, double top, double bottom)
381564
{
382565
if (aspect < RatioConstants.Phi)

Src/ScreenGrid.Models/Grids/GridModeItem.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ public static IEnumerable<GridModeItem> List
4848
new GridModeItem(GridType.GoldenSpiralZoomed, "Golden Spiral"),
4949
new GridModeItem(GridType.FibonacciRectanglesStretched, "Fibonacci Rectangles (stretched)"),
5050
new GridModeItem(GridType.GoldenSpiralStretched, "Golden Spiral (stretched)"),
51+
// TODO: new GridModeItem(GridType.OneDotFiveRectangle, "1.5 Rectangle"),
52+
new GridModeItem(GridType.GoldenRectangle, "Golden (Phi) Rectangle"),
53+
// TODO: new GridModeItem(GridType.RootPhiRectangle, "Root-Phi Rectangle"),
54+
new GridModeItem(GridType.Root2Rectangle, "Root-2 Rectangle"),
55+
new GridModeItem(GridType.Root3Rectangle, "Root-3 Rectangle"),
56+
new GridModeItem(GridType.Root4Rectangle, "Root-4 Rectangle"),
57+
new GridModeItem(GridType.Root5Rectangle, "Root-5 Rectangle"),
5158
};
5259
}
5360
}

Src/ScreenGrid.Models/Grids/GridType.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,32 @@ public enum GridType
6464
/// Golden Spiral (stretched to area extents)
6565
/// </summary>
6666
GoldenSpiralStretched,
67+
68+
/// <summary>
69+
/// 1.5 Rectangle
70+
/// </summary>
71+
// TODO: OneDotFiveRectangle,
72+
73+
/// <summary>
74+
/// Golden rectangle or Auron (1:φ)
75+
/// </summary>
76+
GoldenRectangle,
77+
78+
/// <summary>
79+
/// Root-Phi or Penton (1:√φ)
80+
/// </summary>
81+
// TODO: RootPhiRectangle,
82+
83+
/// <summary>
84+
/// Root-2 or Diagon (1:√2)
85+
/// </summary>
86+
Root2Rectangle,
87+
88+
89+
Root3Rectangle,
90+
91+
Root4Rectangle,
92+
93+
Root5Rectangle,
6794
}
6895
}

Src/ScreenGrid.Models/Grids/RatioConstants.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ static class RatioConstants
2525

2626
public static readonly double OneSixth = 1.0 / 6.0;
2727

28+
public static readonly double RootPhi = Math.Sqrt(Phi);
29+
30+
public static readonly double Root2 = Math.Sqrt(2.0);
31+
32+
public static readonly double Root3 = Math.Sqrt(3.0);
33+
34+
public static readonly double Root4 = Math.Sqrt(4.0);
35+
36+
public static readonly double Root5 = Math.Sqrt(5.0);
37+
2838
/// <summary>
2939
/// 1.358456
3040
/// </summary>

0 commit comments

Comments
 (0)