From 7633368a64aa2b3b2c06a021ae4296e05ca6f374 Mon Sep 17 00:00:00 2001 From: Boris Date: Fri, 8 Nov 2024 14:31:21 +0100 Subject: [PATCH] Support rotation in boundingbox --- GdsSharp.Lib/Extensions.cs | 3 ++- GdsSharp.Lib/GdsPoint.cs | 8 ++++++++ .../Elements/GdsArrayReferenceElement.cs | 18 ++++++++++++++++- .../Elements/GdsStructureReferenceElement.cs | 20 ++++++++++++++++++- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/GdsSharp.Lib/Extensions.cs b/GdsSharp.Lib/Extensions.cs index 2b3df9e..37d31b1 100644 --- a/GdsSharp.Lib/Extensions.cs +++ b/GdsSharp.Lib/Extensions.cs @@ -1,10 +1,11 @@ using System.Numerics; -using GdsSharp.Lib.NonTerminals; namespace GdsSharp.Lib; public static class GdsExtensions { + public const float Deg2Rad = MathF.PI / 180; + /// /// Rotates a vector by the given angle in radians. /// diff --git a/GdsSharp.Lib/GdsPoint.cs b/GdsSharp.Lib/GdsPoint.cs index 36f8524..88401fb 100644 --- a/GdsSharp.Lib/GdsPoint.cs +++ b/GdsSharp.Lib/GdsPoint.cs @@ -49,4 +49,12 @@ public override string ToString() { return $"({X}, {Y})"; } + + public GdsPoint Rotate(float sin, float cos) + { + return new GdsPoint( + cos * X - sin * Y, + sin * X + cos * Y + ); + } } \ No newline at end of file diff --git a/GdsSharp.Lib/NonTerminals/Elements/GdsArrayReferenceElement.cs b/GdsSharp.Lib/NonTerminals/Elements/GdsArrayReferenceElement.cs index 6a3ad6b..e704efe 100644 --- a/GdsSharp.Lib/NonTerminals/Elements/GdsArrayReferenceElement.cs +++ b/GdsSharp.Lib/NonTerminals/Elements/GdsArrayReferenceElement.cs @@ -22,7 +22,23 @@ public GdsBoundingBox GetBoundingBox(GdsStructure.StructureProvider structurePro var boundingBox = structure.GetBoundingBox(structureProvider); if (boundingBox.IsEmpty) return boundingBox; - var boundingBoxes = Points.Select(p => new GdsBoundingBox(p + boundingBox.Min, p + boundingBox.Max)); + IEnumerable boundingBoxes; + if (Transformation.Angle != 0) + { + var (sin, cos) = MathF.SinCos((float)Transformation.Angle * GdsExtensions.Deg2Rad); + boundingBoxes = Points.Select(p => new GdsBoundingBox( + p + boundingBox.Min.Rotate(sin, cos), + p + boundingBox.Max.Rotate(sin, cos) + )); + } + else + { + boundingBoxes = Points.Select(p => new GdsBoundingBox( + p + boundingBox.Min, + p + boundingBox.Max) + ); + } + return new GdsBoundingBox(boundingBoxes); } } \ No newline at end of file diff --git a/GdsSharp.Lib/NonTerminals/Elements/GdsStructureReferenceElement.cs b/GdsSharp.Lib/NonTerminals/Elements/GdsStructureReferenceElement.cs index 99886e6..de6ea02 100644 --- a/GdsSharp.Lib/NonTerminals/Elements/GdsStructureReferenceElement.cs +++ b/GdsSharp.Lib/NonTerminals/Elements/GdsStructureReferenceElement.cs @@ -4,6 +4,7 @@ namespace GdsSharp.Lib.NonTerminals.Elements; public class GdsStructureReferenceElement : IGdsElement { + private const float Deg2Rad = MathF.PI / 180; public required string StructureName { get; set; } public GdsStrans Transformation { get; set; } = new(); public List Points { get; set; } = new(); @@ -20,7 +21,24 @@ public GdsBoundingBox GetBoundingBox(GdsStructure.StructureProvider structurePro var boundingBox = structure.GetBoundingBox(structureProvider); if (boundingBox.IsEmpty) return boundingBox; - var boundingBoxes = Points.Select(p => new GdsBoundingBox(p + boundingBox.Min, p + boundingBox.Max)); + + IEnumerable boundingBoxes; + if (Transformation.Angle != 0) + { + var (sin, cos) = MathF.SinCos((float)Transformation.Angle * GdsExtensions.Deg2Rad); + boundingBoxes = Points.Select(p => new GdsBoundingBox( + p + boundingBox.Min.Rotate(sin, cos), + p + boundingBox.Max.Rotate(sin, cos) + )); + } + else + { + boundingBoxes = Points.Select(p => new GdsBoundingBox( + p + boundingBox.Min, + p + boundingBox.Max) + ); + } + return new GdsBoundingBox(boundingBoxes); } } \ No newline at end of file