diff --git a/GsaGH/Parameters/0_Model/GsaGridLine.cs b/GsaGH/Parameters/0_Model/GsaGridLine.cs index a0a92b4b7..bfb0e5900 100644 --- a/GsaGH/Parameters/0_Model/GsaGridLine.cs +++ b/GsaGH/Parameters/0_Model/GsaGridLine.cs @@ -35,6 +35,7 @@ public GsaGridLine(Arc arc, string label = "") { if (arc.Plane.ZAxis.Z < 0) { arc = new Arc(arc.EndPoint, arc.MidPoint, arc.StartPoint); } + Curve = new PolyCurve(); Curve.Append(arc); @@ -60,12 +61,19 @@ public GsaGridLine(Arc arc, string label = "") { } public GsaGridLine(Line line, string label = "") { + bool IsCounterClockwise = Vector3d.CrossProduct(Vector3d.XAxis, line.UnitTangent).Z >= 0; + double radians = Vector3d.VectorAngle(Vector3d.XAxis, line.UnitTangent); + double vectorAngle = RadiansToDegrees(radians); + if (!IsCounterClockwise) { + vectorAngle = 360 - vectorAngle; + } + GridLine = new GridLine(label) { Shape = GridLineShape.Line, X = line.From.X, Y = line.From.Y, Length = line.Length, - Theta1 = Vector3d.VectorAngle(new Vector3d(1, 0, 0), line.UnitTangent) * 180 / Math.PI + Theta1 = vectorAngle }; Curve = new PolyCurve(); Curve.Append(line); @@ -73,6 +81,11 @@ public GsaGridLine(Line line, string label = "") { UpdatePreview(); } + private static double RadiansToDegrees(double radians) + { + return radians * 180 / Math.PI; + } + internal static Arc ToArc(GridLine gridLine) { var center = new Point3d(gridLine.X, gridLine.Y, 0); double angleRadians = (gridLine.Theta2 - gridLine.Theta1) * Math.PI / 180.0; @@ -93,6 +106,7 @@ internal static PolyCurve ToCurve(GridLine gridLine) { Arc arc = ToArc(gridLine); curve.Append(arc); } + return curve; } @@ -126,8 +140,8 @@ public GsaGridLine(GsaGridLine other) { public override string ToString() { string label = GridLine.Label != "" ? $"{GridLine.Label} " : string.Empty; string type = GridLine.Shape == GridLineShape.Arc ? "Shape: Arc " : string.Empty; - string s = $"{label}{type}X:{GridLine.X} Y:{GridLine.Y} Length:" + - $"{GridLine.Length} Orientation:{GridLine.Theta1}°"; + string s = $"{label}{type}X:{GridLine.X} Y:{GridLine.Y} Length:" + + $"{GridLine.Length} Orientation:{GridLine.Theta1}°"; if (GridLine.Shape == GridLineShape.Arc) { s.Replace("Orientation", "Theta1"); s += " Theta2:" + GridLine.Theta2 + "°"; @@ -147,8 +161,12 @@ internal void UpdatePreview() { if (segment == null) { return; } + if (Curve.IsLinear()) { - Points = new Point3d[2] { segment.PointAtStart, segment.PointAtEnd }; + Points = new Point3d[2] { + segment.PointAtStart, + segment.PointAtEnd + }; } else { Points = segment.DivideEquidistant(segment.GetLength() / 360.0); } diff --git a/GsaGHTests/3_Components/0_Model/GsaGridLineTests.cs b/GsaGHTests/3_Components/0_Model/GsaGridLineTests.cs new file mode 100644 index 000000000..9be5d0a4e --- /dev/null +++ b/GsaGHTests/3_Components/0_Model/GsaGridLineTests.cs @@ -0,0 +1,44 @@ +using GsaGH.Parameters; + +using Rhino.Geometry; + +using Xunit; + +namespace GsaGHTests.Model { + [Collection("GrasshopperFixture collection")] + public class GsaGridLineTests { + + [Fact] + public void ShouldReturnZeroForParallelLine() { + var line = new Line(Point3d.Origin, new Point3d(1, 0, 0)); + var gsaGridLine = new GsaGridLine(line, string.Empty); + + Assert.Equal(0, gsaGridLine.GridLine.Theta1, precision: 5); + } + + [Fact] + public void ShouldCalculateAngleBetweenXAxisAndLine() { + var line = new Line(Point3d.Origin, new Point3d(1, 1, 0)); + var gsaGridLine = new GsaGridLine(line, string.Empty); + + Assert.Equal(45, gsaGridLine.GridLine.Theta1, precision: 5); + } + + [Fact] + public void ShouldProvideTheClockwiseAngle() { + var line = new Line(Point3d.Origin, new Point3d(1, -1, 0)); + var gsaGridLine = new GsaGridLine(line, string.Empty); + + Assert.Equal(315, gsaGridLine.GridLine.Theta1, precision: 5); + } + + [Fact] + public void ShouldProvideTheClockwiseAngle2() { + var line = new Line(Point3d.Origin, new Point3d(-1, -1, 0)); + var gsaGridLine = new GsaGridLine(line, string.Empty); + + Assert.Equal(225, gsaGridLine.GridLine.Theta1, precision: 5); + } + + } +}