Skip to content

Commit baf6605

Browse files
committed
feat: Circle2D.IntersectWith(LineSegment2D)
1 parent fb0314b commit baf6605

3 files changed

Lines changed: 32 additions & 14 deletions

File tree

src/Spatial.Tests/Euclidean/Circle2DTests.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using MathNet.Spatial.Euclidean;
33
using NUnit.Framework;
44

@@ -69,9 +69,23 @@ public void CircleIntersectWithLine2D(string sc, double radius, string sps, stri
6969
var actual = circle.IntersectWith(line);
7070
Assert.That(actual.Length, Is.EqualTo(2));
7171

72-
var expected = new [] { Point2D.Parse(esp0), Point2D.Parse(esp1) };
72+
var expected = new[] { Point2D.Parse(esp0), Point2D.Parse(esp1) };
7373
AssertGeometry.AreEqual(actual[0], expected[0]);
7474
AssertGeometry.AreEqual(actual[1], expected[1]);
7575
}
76+
77+
[TestCase("0,0", 1.41421356 /*=sqrt(2)*/, "0,0", "+1,+1", "+1,+1")]
78+
[TestCase("0,0", 1, "0,0", "+1,0", "+1,0")]
79+
[TestCase("0,0", 1, "0,0", "0,+1", "0,+1")]
80+
public void CircleIntersectWithLineSegment2D(string sCenter, double radius, string sStart, string sEnd, string sExpected)
81+
{
82+
var circle = new Circle2D(Point2D.Parse(sCenter), radius);
83+
var segment = new LineSegment2D(Point2D.Parse(sStart), Point2D.Parse(sEnd));
84+
var actual = circle.IntersectWith(segment);
85+
Assert.That(actual.Length, Is.EqualTo(1));
86+
87+
var expected = Point2D.Parse(sExpected);
88+
AssertGeometry.AreEqual(actual[0], expected);
89+
}
7690
}
7791
}

src/Spatial/Euclidean/Circle2D.cs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using MathNet.Spatial.Internals;
1+
using MathNet.Spatial.Internals;
22
using System;
33
using System.Diagnostics.Contracts;
44
using System.Linq;
@@ -177,20 +177,20 @@ private double[] findParameterTs(Line2D line)
177177
return ts;
178178
}
179179

180-
if (discriminant.IsNearlyEqualTo(0, 1e-6))
181-
{
182-
var t = -b / (2 * a);
183-
return new[] { Point2D.OfVector((s + t * d).ToVector()) };
184-
}
185-
186-
187-
var t1 = (-b - Math.Sqrt(b * b - 4 * a * c)) / (2 * a);
188-
var t2 = (-b + Math.Sqrt(b * b - 4 * a * c)) / (2 * a);
189-
var ts = new double[] { t1, t2 };
190-
var result = ts.Select(t => Point2D.OfVector((s + t * d).ToVector())).ToArray();
180+
/// <summary>
181+
/// Returns intersection a point2D array if this circle and the given line have the intersections
182+
/// </summary>
183+
/// <param name="line">the given line-segment</param>
184+
/// <returns>intersections as a Point2D Array, depending on the count.</returns>
185+
public Point2D[] IntersectWith(LineSegment2D line)
186+
{
187+
var ts = findParameterTs(line.ToLine2D())
188+
.Where(t => 0 <= t && t <= line.Length);
189+
var result = ts.Select(t => line.StartPoint + t * line.Direction).ToArray();
191190
return result;
192191
}
193192

193+
194194
/// <summary>
195195
/// Returns a value to indicate if a pair of circles are equal
196196
/// </summary>

src/Spatial/Euclidean/LineSegment2D.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,5 +236,9 @@ void IXmlSerializable.WriteXml(XmlWriter writer)
236236
writer.WriteElement("StartPoint", StartPoint);
237237
writer.WriteElement("EndPoint", EndPoint);
238238
}
239+
240+
/// <summary>convert this to Line2D </summary>
241+
/// <returns>converted Line2D object</returns>
242+
public Line2D ToLine2D() => new Line2D(StartPoint, EndPoint);
239243
}
240244
}

0 commit comments

Comments
 (0)