Browse Source

Spatial: remove obsolete functionality

spatial
Christoph Ruegg 8 years ago
parent
commit
425e4dae22
  1. 8
      src/Numerics.Tests/Spatial/Euclidean2D/Polygon2DTests.cs
  2. 2
      src/Numerics/Random/RandomSeed.cs
  3. 44
      src/Numerics/Spatial/Euclidean2D/Point2D.cs
  4. 31
      src/Numerics/Spatial/Euclidean2D/PolyLine2D.cs
  5. 89
      src/Numerics/Spatial/Euclidean2D/Polygon2D.cs
  6. 44
      src/Numerics/Spatial/Euclidean2D/Vector2D.cs
  7. 26
      src/Numerics/Spatial/Euclidean3D/Circle3D.cs
  8. 13
      src/Numerics/Spatial/Euclidean3D/CoordinateSystem3D.cs
  9. 2
      src/Numerics/Spatial/Euclidean3D/Line3D.cs
  10. 28
      src/Numerics/Spatial/Euclidean3D/Plane3D.cs
  11. 28
      src/Numerics/Spatial/Euclidean3D/Point3D.cs
  12. 31
      src/Numerics/Spatial/Euclidean3D/PolyLine3D.cs
  13. 26
      src/Numerics/Spatial/Euclidean3D/Ray3D.cs
  14. 33
      src/Numerics/Spatial/Euclidean3D/UnitVector3D.cs
  15. 29
      src/Numerics/Spatial/Euclidean3D/Vector3D.cs
  16. 177
      src/Numerics/Spatial/Internal/HashCode.cs
  17. 63
      src/Numerics/Spatial/Internal/Parser.cs

8
src/Numerics.Tests/Spatial/Euclidean2D/Polygon2DTests.cs

@ -55,7 +55,7 @@ namespace MathNet.Numerics.Tests.Spatial.Euclidean2D
// being duplicates, the point at the beginning of the list is removed // being duplicates, the point at the beginning of the list is removed
var polygon = TestPolygon2(); var polygon = TestPolygon2();
var checkList = new List<Point2D> { new Point2D(0.25, 0.5), new Point2D(1, 1), new Point2D(-1, 1), new Point2D(0.5, -0.5), new Point2D(0, 0) }; var checkList = new List<Point2D> { new Point2D(0.25, 0.5), new Point2D(1, 1), new Point2D(-1, 1), new Point2D(0.5, -0.5), new Point2D(0, 0) };
CollectionAssert.AreEqual(checkList, polygon); CollectionAssert.AreEqual(checkList, polygon.Vertices);
} }
[TestCase(0.5, 0, true)] [TestCase(0.5, 0, true)]
@ -128,7 +128,7 @@ namespace MathNet.Numerics.Tests.Spatial.Euclidean2D
} }
*/ */
var pointsNotOnConvexHull = testPoints.Except(hullCounterClockwise); var pointsNotOnConvexHull = testPoints.Except(hullCounterClockwise.Vertices);
foreach (var pointNotOnConvexHull in pointsNotOnConvexHull) foreach (var pointNotOnConvexHull in pointsNotOnConvexHull)
{ {
var pointIsInsideConvexHull = hullCounterClockwise.EnclosesPoint(pointNotOnConvexHull); var pointIsInsideConvexHull = hullCounterClockwise.EnclosesPoint(pointNotOnConvexHull);
@ -140,7 +140,7 @@ namespace MathNet.Numerics.Tests.Spatial.Euclidean2D
// convex hull is the actual convex hull, which means the original one wasn't! // convex hull is the actual convex hull, which means the original one wasn't!
foreach (var pointToRemove in counterClockwiseVertices) foreach (var pointToRemove in counterClockwiseVertices)
{ {
var convexHullWithPointRemoved = new Polygon2D(hullCounterClockwise.Except(new[] { pointToRemove })); var convexHullWithPointRemoved = new Polygon2D(hullCounterClockwise.Vertices.Except(new[] { pointToRemove }));
var pointIsInsideConvexHull = var pointIsInsideConvexHull =
convexHullWithPointRemoved.EnclosesPoint(pointToRemove); convexHullWithPointRemoved.EnclosesPoint(pointToRemove);
Assert.That(pointIsInsideConvexHull, Is.Not.True); Assert.That(pointIsInsideConvexHull, Is.Not.True);
@ -156,7 +156,7 @@ namespace MathNet.Numerics.Tests.Spatial.Euclidean2D
var expected = new Polygon2D(expectedPoints); var expected = new Polygon2D(expectedPoints);
var thinned = poly.ReduceComplexity(0.00001); var thinned = poly.ReduceComplexity(0.00001);
CollectionAssert.AreEqual(expected, thinned); CollectionAssert.AreEqual(expected.Vertices, thinned.Vertices);
} }
private static Polygon2D TestPolygon1() private static Polygon2D TestPolygon1()

2
src/Numerics/Random/RandomSeed.cs

@ -28,7 +28,7 @@ namespace MathNet.Numerics.Random
} }
/// <summary> /// <summary>
/// Provides a seed based on an internal random number generator (crypto if available), time and unique GUIDs. /// Provides a seed based on the internal crypto random number generator.
/// WARNING: There is only medium randomness in this seed, but quick repeated /// WARNING: There is only medium randomness in this seed, but quick repeated
/// calls will result in different seed values. Do not use for cryptography! /// calls will result in different seed values. Do not use for cryptography!
/// </summary> /// </summary>

44
src/Numerics/Spatial/Euclidean2D/Point2D.cs

@ -39,50 +39,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
this.Y = y; this.Y = y;
} }
/// <summary>
/// Initializes a new instance of the <see cref="Point2D"/> struct.
/// Creates a point r from origin rotated a counterclockwise from X-Axis
/// </summary>
/// <param name="r">distance from origin</param>
/// <param name="a">the angle</param>
[Obsolete("This constructor will be removed, use FromPolar. Made obsolete 2017-12-03.")]
public Point2D(double r, Angle a)
: this(r * Math.Cos(a.Radians), r * Math.Sin(a.Radians))
{
if (r < 0)
{
throw new ArgumentOutOfRangeException(nameof(r), r, "Expected a radius greater than or equal to zero.");
}
}
/// <summary>
/// Initializes a new instance of the <see cref="Point2D"/> struct.
/// Creates a point from a list of coordinates (x, y)
/// </summary>
/// <param name="data">a pair of coordinates in the order x, y</param>
/// <exception cref="ArgumentException">Exception thrown if more than 2 coordinates are passed</exception>
[Obsolete("This constructor will be removed. Made obsolete 2017-12-03.")]
public Point2D(IEnumerable<double> data)
: this(data.ToArray())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Point2D"/> struct.
/// Creates a point from a list of coordinates (x, y)
/// </summary>
/// <param name="data">a pair of coordinates in the order x, y</param>
/// <exception cref="ArgumentException">Exception thrown if more than 2 coordinates are passed</exception>
[Obsolete("This constructor will be removed. Made obsolete 2017-12-03.")]
public Point2D(double[] data)
: this(data[0], data[1])
{
if (data.Length != 2)
{
throw new ArgumentException("data.Length != 2!");
}
}
/// <summary> /// <summary>
/// Gets a point at the origin (0,0) /// Gets a point at the origin (0,0)
/// </summary> /// </summary>

31
src/Numerics/Spatial/Euclidean2D/PolyLine2D.cs

@ -1,5 +1,4 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.Contracts; using System.Diagnostics.Contracts;
using System.Linq; using System.Linq;
@ -11,7 +10,7 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
/// The PolyLine2D class represents a 2D curve in space made up of line segments joined end-to-end, and is /// The PolyLine2D class represents a 2D curve in space made up of line segments joined end-to-end, and is
/// stored as a sequential list of 2D points. /// stored as a sequential list of 2D points.
/// </summary> /// </summary>
public class PolyLine2D : IEnumerable<Point2D>, IEquatable<PolyLine2D> public class PolyLine2D : IEquatable<PolyLine2D>
{ {
/// <summary> /// <summary>
/// Internal storage for the points /// Internal storage for the points
@ -28,12 +27,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
this.points = new List<Point2D>(points); this.points = new List<Point2D>(points);
} }
/// <summary>
/// Gets the number of points in the polyline
/// </summary>
[Obsolete("Use VertexCount instead, obsolete since 2018-01-12")]
public int Count => this.points.Count;
/// <summary> /// <summary>
/// Gets the number of vertices in the polyline. /// Gets the number of vertices in the polyline.
/// </summary> /// </summary>
@ -58,14 +51,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
} }
} }
/// <summary>
/// Returns a point in the polyline by index number
/// </summary>
/// <param name="key">The index of a point</param>
/// <returns>The indexed point</returns>
[Obsolete("Use Vertices instead, obsolete since 2018-01-12")]
public Point2D this[int key] => this.points[key];
/// <summary> /// <summary>
/// Returns a value that indicates whether each pair of elements in two specified lines is equal. /// Returns a value that indicates whether each pair of elements in two specified lines is equal.
/// </summary> /// </summary>
@ -253,20 +238,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
return HashCode.CombineMany(this.points); return HashCode.CombineMany(this.points);
} }
/// <inheritdoc />
[Obsolete("Use Vertices instead, obsolete since 2018-01-12")]
public IEnumerator<Point2D> GetEnumerator()
{
return this.points.GetEnumerator();
}
/// <inheritdoc />
[Obsolete("Use Vertices instead, obsolete since 2018-01-12")]
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
/// <summary> /// <summary>
/// Reduce the complexity of a manifold of points represented as an IEnumerable of Point2D objects. /// Reduce the complexity of a manifold of points represented as an IEnumerable of Point2D objects.
/// This algorithm goes through each point in the manifold and computes the error that would be introduced /// This algorithm goes through each point in the manifold and computes the error that would be introduced

89
src/Numerics/Spatial/Euclidean2D/Polygon2D.cs

@ -11,7 +11,7 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
/// <summary> /// <summary>
/// Class to represent a closed polygon. /// Class to represent a closed polygon.
/// </summary> /// </summary>
public class Polygon2D : IEnumerable<Point2D>, IEquatable<Polygon2D> public class Polygon2D : IEquatable<Polygon2D>
{ {
/// <summary> /// <summary>
/// A list of vertices. /// A list of vertices.
@ -55,12 +55,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
} }
} }
/// <summary>
/// Gets the number of vertices in the polygon.
/// </summary>
[Obsolete("Use VertexCount instead, obsolete since 6/12/2017")]
public int Count => this.points.Count;
/// <summary> /// <summary>
/// Gets a list of vertices /// Gets a list of vertices
/// </summary> /// </summary>
@ -99,39 +93,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
/// </summary> /// </summary>
public int VertexCount => this.points.Count; public int VertexCount => this.points.Count;
/// <summary>
/// A index into the list of vertices
/// </summary>
/// <param name="key">An index for the vertex number</param>
/// <returns>A Vertex</returns>
[Obsolete("Use Vertices instead, obsolete since 6/12/2017")]
public Point2D this[int key] => this.points[key];
/// <summary>
/// Adds a vector to the each point on the polygon
/// </summary>
/// <param name="shift">The vector to add</param>
/// <param name="poly">The polygon</param>
/// <returns>A new <see cref="Polygon2D"/> at the adjusted points</returns>
[Obsolete("Use Translate instance method instead, obsolete since 6/12/2017")]
public static Polygon2D operator +(Vector2D shift, Polygon2D poly)
{
var newPoints = from p in poly select p + shift;
return new Polygon2D(newPoints);
}
/// <summary>
/// Adds a vector to the each point on the polygon
/// </summary>
/// <param name="poly">The polygon</param>
/// <param name="shift">The vector to add</param>
/// <returns>A new <see cref="Polygon2D"/> at the adjusted points</returns>
[Obsolete("Use Translate instance method instead, obsolete since 6/12/2017")]
public static Polygon2D operator +(Polygon2D poly, Vector2D shift)
{
return shift + poly;
}
/// <summary> /// <summary>
/// Returns a value that indicates whether each point in two specified polygons is equal. /// Returns a value that indicates whether each point in two specified polygons is equal.
/// </summary> /// </summary>
@ -168,32 +129,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
return a.points.Any(b.EnclosesPoint) || b.points.Any(a.EnclosesPoint); return a.points.Any(b.EnclosesPoint) || b.points.Any(a.EnclosesPoint);
} }
/// <summary>
/// Determine whether or not a point is inside a polygon using the intersection counting
/// method. Return true if the point is contained, false if it is not. Points which lie
/// on the edge are not counted as inside the polygon.
/// </summary>
/// <param name="p">A point</param>
/// <param name="poly">A polygon</param>
/// <returns>True if the point is inside the polygon; otherwise false.</returns>
[Obsolete("Use instance method EnclosesPoint instead, obsolete since 6/12/2017")]
public static bool IsPointInPolygon(Point2D p, Polygon2D poly)
{
// Algorithm from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
// translated into C#
var c = false;
for (int i = 0, j = poly.Count - 1; i < poly.Count; j = i++)
{
if (((poly[i].Y > p.Y) != (poly[j].Y > p.Y)) &&
(p.X < ((poly[j].X - poly[i].X) * (p.Y - poly[i].Y) / (poly[j].Y - poly[i].Y)) + poly[i].X))
{
c = !c;
}
}
return c;
}
/// <summary> /// <summary>
/// Using algorithm from Ouellet - https://www.codeproject.com/Articles/1210225/Fast-and-improved-D-Convex-Hull-algorithm-and-its, take an IEnumerable of Point2Ds and computes the /// Using algorithm from Ouellet - https://www.codeproject.com/Articles/1210225/Fast-and-improved-D-Convex-Hull-algorithm-and-its, take an IEnumerable of Point2Ds and computes the
/// two dimensional convex hull, returning it as a Polygon2D object. /// two dimensional convex hull, returning it as a Polygon2D object.
@ -261,7 +196,7 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
/// <returns>A polygon</returns> /// <returns>A polygon</returns>
public Polygon2D ReduceComplexity(double singleStepTolerance) public Polygon2D ReduceComplexity(double singleStepTolerance)
{ {
return new Polygon2D(PolyLine2D.ReduceComplexity(this.ToPolyLine2D(), singleStepTolerance)); return new Polygon2D(PolyLine2D.ReduceComplexity(this.ToPolyLine2D().Vertices, singleStepTolerance).Vertices);
} }
/// <summary> /// <summary>
@ -316,26 +251,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
return new PolyLine2D(points); return new PolyLine2D(points);
} }
/// <summary>
/// Returns an enumerator for the vertices
/// </summary>
/// <returns>An enumerator for the vertices</returns>
[Obsolete("Use Vertices instead, obsolete since 6/12/2017")]
public IEnumerator<Point2D> GetEnumerator()
{
return this.points.GetEnumerator();
}
/// <summary>
/// Returns an enumerator for the vertices
/// </summary>
/// <returns>An enumerator for the vertices</returns>
[Obsolete("Use Vertices instead, obsolete since 6/12/2017")]
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
/// <summary> /// <summary>
/// Returns a value to indicate if a pair of polygons are equal /// Returns a value to indicate if a pair of polygons are equal
/// </summary> /// </summary>

44
src/Numerics/Spatial/Euclidean2D/Vector2D.cs

@ -1,8 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts; using System.Diagnostics.Contracts;
using System.Globalization; using System.Globalization;
using System.Linq;
using System.Xml; using System.Xml;
using System.Xml.Schema; using System.Xml.Schema;
using System.Xml.Serialization; using System.Xml.Serialization;
@ -38,48 +36,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
this.Y = y; this.Y = y;
} }
/// <summary>
/// Initializes a new instance of the <see cref="Vector2D"/> struct.
/// Creates a vector with length r rotated a counterclockwise from X-Axis
/// </summary>
/// <param name="r">The radius</param>
/// <param name="a">The angle</param>
[Obsolete("This constructor will be removed, use FromPolar. Made obsolete 2017-12-03.")]
//// ReSharper disable once UnusedMember.Global
public Vector2D(double r, Angle a)
: this(r * Math.Cos(a.Radians), r * Math.Sin(a.Radians))
{
if (r < 0)
{
throw new ArgumentOutOfRangeException(nameof(r), r, "Expected a radius greater than or equal to zero.");
}
}
/// <summary>
/// Initializes a new instance of the <see cref="Vector2D"/> struct.
/// </summary>
/// <param name="data">A list of 2 doubles</param>
[Obsolete("This constructor will be removed. Made obsolete 2017-12-03.")]
//// ReSharper disable once UnusedMember.Global
public Vector2D(IEnumerable<double> data)
: this(data.ToArray())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Vector2D"/> struct.
/// </summary>
/// <param name="data">A list of 2 doubles</param>
[Obsolete("This constructor will be removed. Made obsolete 2017-12-03.")]
public Vector2D(double[] data)
: this(data[0], data[1])
{
if (data.Length != 2)
{
throw new ArgumentException("data.Length != 2!");
}
}
/// <summary> /// <summary>
/// Gets a vector representing the X Axis /// Gets a vector representing the X Axis
/// </summary> /// </summary>

26
src/Numerics/Spatial/Euclidean3D/Circle3D.cs

@ -39,32 +39,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
this.Radius = radius; this.Radius = radius;
} }
/// <summary>
/// Initializes a new instance of the <see cref="Circle3D"/> struct.
/// Create a circle from the midpoint between two points, in a direction along a specified axis
/// </summary>
/// <param name="p1">First point on the circumference of the circle</param>
/// <param name="p2">Second point on the circumference of the circle</param>
/// <param name="axis">Direction of the plane in which the circle lies</param>
[Obsolete("This constructor will be removed, use factory method FromPointsAndAxis. Made obsolete 2017-12-05.")]
public Circle3D(Point3D p1, Point3D p2, UnitVector3D axis)
{
this = FromPointsAndAxis(p1, p2, axis);
}
/// <summary>
/// Initializes a new instance of the <see cref="Circle3D"/> struct.
/// Create a circle from three points which lie along its circumference.
/// </summary>
/// <param name="p1">The first point on the circle</param>
/// <param name="p2">The second point on the circle</param>
/// <param name="p3">The third point on the circle</param>
[Obsolete("This constructor will be removed, use factory method FromPoints. Made obsolete 2017-12-05.")]
public Circle3D(Point3D p1, Point3D p2, Point3D p3)
{
this = FromPoints(p1, p2, p3);
}
/// <summary> /// <summary>
/// Gets the diameter of the circle /// Gets the diameter of the circle
/// </summary> /// </summary>

13
src/Numerics/Spatial/Euclidean3D/CoordinateSystem3D.cs

@ -19,7 +19,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// <summary> /// <summary>
/// A local regex pattern for 3D items /// A local regex pattern for 3D items
/// </summary> /// </summary>
private static readonly string Item3DPattern = Parser.Vector3DPattern.Trim('^', '$'); private static readonly string Item3DPattern = string.Format(@"^ *\(?(?<x>{0}){1}(?<y>{0}){1}(?<z>{0})\)? *$", @"[+-]?\d*(?:[.,]\d+)?(?:[eE][+-]?\d+)?", @" *[,;] *").Trim('^', '$');
/// <summary> /// <summary>
/// A local regex pattern for a coordinate system /// A local regex pattern for a coordinate system
@ -558,17 +558,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
return new CoordinateSystem3D(this.Multiply(cs)); return new CoordinateSystem3D(this.Multiply(cs));
} }
/// <summary>
/// Transforms a line and returns the transformed.
/// </summary>
/// <param name="l">A line</param>
/// <returns>A transformed line</returns>
[Obsolete("Use LineSegment3D, Obsolete from 2017-12-10")]
public Line3D Transform(Line3D l)
{
return new Line3D(this.Transform(l.StartPoint), this.Transform(l.EndPoint));
}
/// <summary> /// <summary>
/// Transforms a line segment. /// Transforms a line segment.
/// </summary> /// </summary>

2
src/Numerics/Spatial/Euclidean3D/Line3D.cs

@ -76,7 +76,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
} }
/// <summary> /// <summary>
/// Returns a new <see cref="Line2D"/> from a pair of strings which represent points. /// Returns a new <see cref="Line3D"/> from a pair of strings which represent points.
/// See <see cref="Point3D.Parse(string, IFormatProvider)" /> for details on acceptable formats. /// See <see cref="Point3D.Parse(string, IFormatProvider)" /> for details on acceptable formats.
/// </summary> /// </summary>
/// <param name="startPoint">The string representation of the first point.</param> /// <param name="startPoint">The string representation of the first point.</param>

28
src/Numerics/Spatial/Euclidean3D/Plane3D.cs

@ -72,21 +72,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
{ {
} }
/// <summary>
/// Initializes a new instance of the <see cref="Plane3D"/> struct.
/// Creates a Plane that contains the three given points.
/// http://www.had2know.com/academics/equation-plane-through-3-points.html
/// </summary>
/// <param name="p1">The first point on the Plane.</param>
/// <param name="p2">The second point on the Plane.</param>
/// <param name="p3">The third point on the Plane.</param>
/// <returns>The Plane containing the three points.</returns>
[Obsolete("This constructor will be removed, use factory method Plane.FromPoints. Made obsolete 2017-12-05.")]
public Plane3D(Point3D p1, Point3D p2, Point3D p3)
{
this = FromPoints(p1, p2, p3);
}
/// <summary> /// <summary>
/// Gets the <see cref="Normal"/> x component. /// Gets the <see cref="Normal"/> x component.
/// </summary> /// </summary>
@ -169,17 +154,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
return Point3D.IntersectionOf(plane1, plane2, plane3); return Point3D.IntersectionOf(plane1, plane2, plane3);
} }
/// <summary>
/// Creates a Plane from its string representation
/// </summary>
/// <param name="s">The string representation of the Plane</param>
/// <returns>a new Plane</returns>
[Obsolete("Should not have been made public, removed on 9/12/2017")]
public static Plane3D Parse(string s)
{
return Parser.ParsePlane(s);
}
/// <summary> /// <summary>
/// Get the distance to the point along the <see cref="Normal"/> /// Get the distance to the point along the <see cref="Normal"/>
/// </summary> /// </summary>
@ -258,7 +232,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// </summary> /// </summary>
/// <param name="line3DToProject">The line to project</param> /// <param name="line3DToProject">The line to project</param>
/// <returns>A projected line</returns> /// <returns>A projected line</returns>
[Obsolete("Use LineSegment3D instead, obsolete from 2017-12-10")]
public Line3D Project(Line3D line3DToProject) public Line3D Project(Line3D line3DToProject)
{ {
var projectedStartPoint = this.Project(line3DToProject.StartPoint); var projectedStartPoint = this.Project(line3DToProject.StartPoint);
@ -354,7 +327,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// <param name="line">A line segment</param> /// <param name="line">A line segment</param>
/// <param name="tolerance">A tolerance (epsilon) to account for floating point error.</param> /// <param name="tolerance">A tolerance (epsilon) to account for floating point error.</param>
/// <returns>Intersection Point or null</returns> /// <returns>Intersection Point or null</returns>
[Obsolete("Use LineSegment3D instead, Obsolete from 2017-12-10")]
public Point3D? IntersectionWith(Line3D line, double tolerance = float.Epsilon) public Point3D? IntersectionWith(Line3D line, double tolerance = float.Epsilon)
{ {
if (line.Direction.IsPerpendicularTo(this.Normal, tolerance)) if (line.Direction.IsPerpendicularTo(this.Normal, tolerance))

28
src/Numerics/Spatial/Euclidean3D/Point3D.cs

@ -45,34 +45,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
this.Z = z; this.Z = z;
} }
/// <summary>
/// Initializes a new instance of the <see cref="Point3D"/> struct.
/// Creates a point from a list of coordinates (x, y, z)
/// </summary>
/// <param name="data">a list of coordinates in the order x, y, z</param>
/// <exception cref="ArgumentException">Exception thrown if anything other than 3 coordinates are passed</exception>
[Obsolete("This constructor will be removed. Made obsolete 2017-12-05.")]
public Point3D(IEnumerable<double> data)
: this(data.ToArray())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Point3D"/> struct.
/// Creates a point from a list of coordinates (x, y, z)
/// </summary>
/// <param name="data">a size 3 array of coordinates in the order x, y, z</param>
/// <exception cref="ArgumentException">Exception thrown if anything other than 3 coordinates are passed</exception>
[Obsolete("This constructor will be removed. Made obsolete 2017-12-05.")]
public Point3D(double[] data)
: this(data[0], data[1], data[2])
{
if (data.Length != 3)
{
throw new ArgumentException("Size must be 3");
}
}
/// <summary> /// <summary>
/// Gets a point at the origin /// Gets a point at the origin
/// </summary> /// </summary>

31
src/Numerics/Spatial/Euclidean3D/PolyLine3D.cs

@ -1,5 +1,4 @@
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.Contracts; using System.Diagnostics.Contracts;
using System.Linq; using System.Linq;
@ -10,7 +9,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// <summary> /// <summary>
/// A PolyLine is an ordered series of line segments in space represented as list of connected Point3Ds. /// A PolyLine is an ordered series of line segments in space represented as list of connected Point3Ds.
/// </summary> /// </summary>
public class PolyLine3D : IEnumerable<Point3D>, IEquatable<PolyLine3D> public class PolyLine3D : IEquatable<PolyLine3D>
{ {
/// <summary> /// <summary>
/// An internal list of points /// An internal list of points
@ -27,12 +26,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
this.points = new List<Point3D>(points); this.points = new List<Point3D>(points);
} }
/// <summary>
/// Gets an integer representing the number of Point3D objects in the polyline
/// </summary>
[Obsolete("Use VertexCount instead, obsolete since 2018-01-12")]
public int Count => this.points.Count;
/// <summary> /// <summary>
/// Gets the number of vertices in the polyline. /// Gets the number of vertices in the polyline.
/// </summary> /// </summary>
@ -57,14 +50,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
} }
} }
/// <summary>
/// Returns a point in the polyline by index number
/// </summary>
/// <param name="key">The index of a point</param>
/// <returns>The indexed point</returns>
[Obsolete("Use Vertices instead, obsolete since 2018-01-12")]
public Point3D this[int key] => this.points[key];
/// <summary> /// <summary>
/// Returns a value that indicates whether each pair of elements in two specified lines is equal. /// Returns a value that indicates whether each pair of elements in two specified lines is equal.
/// </summary> /// </summary>
@ -224,20 +209,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
return HashCode.CombineMany(this.points); return HashCode.CombineMany(this.points);
} }
/// <inheritdoc />
[Obsolete("Use Vertices instead, obsolete since 2018-01-12")]
public IEnumerator<Point3D> GetEnumerator()
{
return this.points.GetEnumerator();
}
/// <inheritdoc />
[Obsolete("Use Vertices instead, obsolete since 2018-01-12")]
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
/// <summary> /// <summary>
/// Returns the length of the polyline by summing the lengths of the individual segments /// Returns the length of the polyline by summing the lengths of the individual segments
/// </summary> /// </summary>

26
src/Numerics/Spatial/Euclidean3D/Ray3D.cs

@ -92,32 +92,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
return new Ray3D(Point3D.Parse(point), UnitVector3D.Parse(direction)); return new Ray3D(Point3D.Parse(point), UnitVector3D.Parse(direction));
} }
/// <summary>
/// Parses a string in the format: 'p:{1, 2, 3} v:{0, 0, 1}' to a Ray3D
/// This is mainly meant for tests
/// </summary>
/// <param name="s">a string representing the ray</param>
/// <returns>a ray</returns>
[Obsolete("Should not have been made public. Mode Obsolete 2017-12-09")]
public static Ray3D Parse(string s)
{
return Parser.ParseRay3D(s);
}
/// <summary>
/// Returns the shortest line from a point to the ray
/// </summary>
/// <param name="point3D">A point.</param>
/// <returns>A line segment from the point to the closest point on the ray</returns>
[Pure]
[Obsolete("Use ShortestLineTo, Obsolete from 2017-12-11")]
public Line3D LineTo(Point3D point3D)
{
var v = this.ThroughPoint.VectorTo(point3D);
var alongVector = v.ProjectOn(this.Direction);
return new Line3D(this.ThroughPoint + alongVector, point3D);
}
/// <summary> /// <summary>
/// Returns the shortest line from a point to the ray /// Returns the shortest line from a point to the ray
/// </summary> /// </summary>

33
src/Numerics/Spatial/Euclidean3D/UnitVector3D.cs

@ -1,8 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts; using System.Diagnostics.Contracts;
using System.Globalization; using System.Globalization;
using System.Linq;
using System.Xml; using System.Xml;
using System.Xml.Schema; using System.Xml.Schema;
using System.Xml.Serialization; using System.Xml.Serialization;
@ -39,8 +37,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// <param name="x">The x component.</param> /// <param name="x">The x component.</param>
/// <param name="y">The y component.</param> /// <param name="y">The y component.</param>
/// <param name="z">The z component.</param> /// <param name="z">The z component.</param>
[Obsolete("This constructor will be made private, prefer the factory method Create. Made obsolete 2017-12-05.")] private UnitVector3D(double x, double y, double z)
public UnitVector3D(double x, double y, double z)
{ {
if (double.IsNaN(x) || double.IsInfinity(x)) if (double.IsNaN(x) || double.IsInfinity(x))
{ {
@ -68,30 +65,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
this.Z = z / norm; this.Z = z / norm;
} }
/// <summary>
/// Initializes a new instance of the <see cref="UnitVector3D"/> struct.
/// </summary>
/// <param name="data">A list of 3 points</param>
[Obsolete("This constructor will be removed. Made obsolete 2017-12-05.")]
public UnitVector3D(IEnumerable<double> data)
: this(data.ToArray())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="UnitVector3D"/> struct.
/// </summary>
/// <param name="data">A list of 3 points</param>
[Obsolete("This constructor will be removed. Made obsolete 2017-12-05.")]
public UnitVector3D(double[] data)
: this(data[0], data[1], data[2])
{
if (data.Length != 3)
{
throw new ArgumentException("Size must be 3");
}
}
/// <summary> /// <summary>
/// Gets the X axis /// Gets the X axis
/// </summary> /// </summary>
@ -601,7 +574,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// </summary> /// </summary>
/// <param name="v">a vector to subtract</param> /// <param name="v">a vector to subtract</param>
/// <returns>A new vector</returns> /// <returns>A new vector</returns>
[Obsolete("Use - instead")] [Pure]
public Vector3D Subtract(UnitVector3D v) public Vector3D Subtract(UnitVector3D v)
{ {
return new Vector3D(this.X - v.X, this.Y - v.Y, this.Z - v.Z); return new Vector3D(this.X - v.X, this.Y - v.Y, this.Z - v.Z);
@ -612,7 +585,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// </summary> /// </summary>
/// <param name="v">a vector to add</param> /// <param name="v">a vector to add</param>
/// <returns>A new vector</returns> /// <returns>A new vector</returns>
[Obsolete("Use + instead")] [Pure]
public Vector3D Add(UnitVector3D v) public Vector3D Add(UnitVector3D v)
{ {
return new Vector3D(this.X + v.X, this.Y + v.Y, this.Z + v.Z); return new Vector3D(this.X + v.X, this.Y + v.Y, this.Z + v.Z);

29
src/Numerics/Spatial/Euclidean3D/Vector3D.cs

@ -1,8 +1,6 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts; using System.Diagnostics.Contracts;
using System.Globalization; using System.Globalization;
using System.Linq;
using System.Xml; using System.Xml;
using System.Xml.Schema; using System.Xml.Schema;
using System.Xml.Serialization; using System.Xml.Serialization;
@ -45,30 +43,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
this.Z = z; this.Z = z;
} }
/// <summary>
/// Initializes a new instance of the <see cref="Vector3D"/> struct.
/// </summary>
/// <param name="data">A list of 3 doubles</param>
[Obsolete("This constructor will be removed. Made obsolete 2017-12-05.")]
public Vector3D(IEnumerable<double> data)
: this(data.ToArray())
{
}
/// <summary>
/// Initializes a new instance of the <see cref="Vector3D"/> struct.
/// </summary>
/// <param name="data">A list of 3 doubles</param>
[Obsolete("This constructor will be removed. Made obsolete 2017-12-05.")]
public Vector3D(double[] data)
: this(data[0], data[1], data[2])
{
if (data.Length != 3)
{
throw new ArgumentException("Size must be 3");
}
}
/// <summary> /// <summary>
/// Gets an invalid vector with no values /// Gets an invalid vector with no values
/// </summary> /// </summary>
@ -454,7 +428,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// </summary> /// </summary>
/// <param name="v">a vector to subtract</param> /// <param name="v">a vector to subtract</param>
/// <returns>A new vector</returns> /// <returns>A new vector</returns>
[Obsolete("Use - instead")] [Pure]
public Vector3D Subtract(Vector3D v) public Vector3D Subtract(Vector3D v)
{ {
return new Vector3D(this.X - v.X, this.Y - v.Y, this.Z - v.Z); return new Vector3D(this.X - v.X, this.Y - v.Y, this.Z - v.Z);
@ -465,7 +439,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// </summary> /// </summary>
/// <param name="v">a vector to add</param> /// <param name="v">a vector to add</param>
/// <returns>A new vector</returns> /// <returns>A new vector</returns>
[Obsolete("Use + instead")]
[Pure] [Pure]
public Vector3D Add(Vector3D v) public Vector3D Add(Vector3D v)
{ {

177
src/Numerics/Spatial/Internal/HashCode.cs

@ -1,6 +1,6 @@
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.Runtime.CompilerServices;
using System.ComponentModel; using MathNet.Numerics.Random;
namespace MathNet.Numerics.Spatial.Internal namespace MathNet.Numerics.Spatial.Internal
{ {
@ -56,9 +56,9 @@ namespace MathNet.Numerics.Spatial.Internal
/// <summary> /// <summary>
/// Generates a hashcode /// Generates a hashcode
/// </summary> /// </summary>
internal struct HashCode internal static class HashCode
{ {
private static readonly uint s_seed = GenerateGlobalSeed(); private static readonly uint Seed = GenerateGlobalSeed();
private const uint Prime1 = 2654435761U; private const uint Prime1 = 2654435761U;
private const uint Prime2 = 2246822519U; private const uint Prime2 = 2246822519U;
@ -66,15 +66,10 @@ namespace MathNet.Numerics.Spatial.Internal
private const uint Prime4 = 668265263U; private const uint Prime4 = 668265263U;
private const uint Prime5 = 374761393U; private const uint Prime5 = 374761393U;
private uint _v1, _v2, _v3, _v4;
private uint _queue1, _queue2, _queue3;
private uint _length;
private static uint GenerateGlobalSeed() private static uint GenerateGlobalSeed()
{ {
// NOTE: Modified from original unsafe implementation. Might be better to use a more random seed. // NOTE: Modified from original unsafe implementation.
System.Random r = new System.Random(); int seed = RandomSeed.Robust();
int seed = r.Next();
return unchecked((uint)seed); return unchecked((uint)seed);
} }
@ -319,20 +314,26 @@ namespace MathNet.Numerics.Spatial.Internal
return (int)hash; return (int)hash;
} }
// [MethodImpl(MethodImplOptions.AggressiveInlining)] #if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
private static uint Rol(uint value, int count) private static uint Rol(uint value, int count)
=> (value << count) | (value >> (32 - count)); => (value << count) | (value >> (32 - count));
// [MethodImpl(MethodImplOptions.AggressiveInlining)] #if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
private static void Initialize(out uint v1, out uint v2, out uint v3, out uint v4) private static void Initialize(out uint v1, out uint v2, out uint v3, out uint v4)
{ {
v1 = s_seed + Prime1 + Prime2; v1 = Seed + Prime1 + Prime2;
v2 = s_seed + Prime2; v2 = Seed + Prime2;
v3 = s_seed; v3 = Seed;
v4 = s_seed - Prime1; v4 = Seed - Prime1;
} }
// [MethodImpl(MethodImplOptions.AggressiveInlining)] #if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
private static uint Round(uint hash, uint input) private static uint Round(uint hash, uint input)
{ {
hash += input * Prime2; hash += input * Prime2;
@ -341,14 +342,18 @@ namespace MathNet.Numerics.Spatial.Internal
return hash; return hash;
} }
// [MethodImpl(MethodImplOptions.AggressiveInlining)] #if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
private static uint QueueRound(uint hash, uint queuedValue) private static uint QueueRound(uint hash, uint queuedValue)
{ {
hash += queuedValue * Prime3; hash += queuedValue * Prime3;
return Rol(hash, 17) * Prime4; return Rol(hash, 17) * Prime4;
} }
// [MethodImpl(MethodImplOptions.AggressiveInlining)] #if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
private static uint MixState(uint v1, uint v2, uint v3, uint v4) private static uint MixState(uint v1, uint v2, uint v3, uint v4)
{ {
return Rol(v1, 1) + Rol(v2, 7) + Rol(v3, 12) + Rol(v4, 18); return Rol(v1, 1) + Rol(v2, 7) + Rol(v3, 12) + Rol(v4, 18);
@ -356,10 +361,12 @@ namespace MathNet.Numerics.Spatial.Internal
private static uint MixEmptyState() private static uint MixEmptyState()
{ {
return s_seed + Prime5; return Seed + Prime5;
} }
// [MethodImpl(MethodImplOptions.AggressiveInlining)] #if !NET40
[MethodImpl(MethodImplOptions.AggressiveInlining)]
#endif
private static uint MixFinal(uint hash) private static uint MixFinal(uint hash)
{ {
hash ^= hash >> 15; hash ^= hash >> 15;
@ -369,129 +376,5 @@ namespace MathNet.Numerics.Spatial.Internal
hash ^= hash >> 16; hash ^= hash >> 16;
return hash; return hash;
} }
public void Add<T>(T value)
{
Add(value?.GetHashCode() ?? 0);
}
public void Add<T>(T value, IEqualityComparer<T> comparer)
{
Add(comparer != null ? comparer.GetHashCode(value) : (value?.GetHashCode() ?? 0));
}
private void Add(int value)
{
// The original xxHash works as follows:
// 0. Initialize immediately. We can't do this in a struct (no
// default ctor).
// 1. Accumulate blocks of length 16 (4 uints) into 4 accumulators.
// 2. Accumulate remaining blocks of length 4 (1 uint) into the
// hash.
// 3. Accumulate remaining blocks of length 1 into the hash.
// There is no need for #3 as this type only accepts ints. _queue1,
// _queue2 and _queue3 are basically a buffer so that when
// ToHashCode is called we can execute #2 correctly.
// We need to initialize the xxHash32 state (_v1 to _v4) lazily (see
// #0) nd the last place that can be done if you look at the
// original code is just before the first block of 16 bytes is mixed
// in. The xxHash32 state is never used for streams containing fewer
// than 16 bytes.
// To see what's really going on here, have a look at the Combine
// methods.
var val = (uint)value;
// Storing the value of _length locally shaves of quite a few bytes
// in the resulting machine code.
uint previousLength = _length++;
uint position = previousLength % 4;
// Switch can't be inlined.
if (position == 0)
_queue1 = val;
else if (position == 1)
_queue2 = val;
else if (position == 2)
_queue3 = val;
else // position == 3
{
if (previousLength == 3)
Initialize(out _v1, out _v2, out _v3, out _v4);
_v1 = Round(_v1, _queue1);
_v2 = Round(_v2, _queue2);
_v3 = Round(_v3, _queue3);
_v4 = Round(_v4, val);
}
}
public int ToHashCode()
{
// Storing the value of _length locally shaves of quite a few bytes
// in the resulting machine code.
uint length = _length;
// position refers to the *next* queue position in this method, so
// position == 1 means that _queue1 is populated; _queue2 would have
// been populated on the next call to Add.
uint position = length % 4;
// If the length is less than 4, _v1 to _v4 don't contain anything
// yet. xxHash32 treats this differently.
uint hash = length < 4 ? MixEmptyState() : MixState(_v1, _v2, _v3, _v4);
// _length is incremented once per Add(Int32) and is therefore 4
// times too small (xxHash length is in bytes, not ints).
hash += length * 4;
// Mix what remains in the queue
// Switch can't be inlined right now, so use as few branches as
// possible by manually excluding impossible scenarios (position > 1
// is always false if position is not > 0).
if (position > 0)
{
hash = QueueRound(hash, _queue1);
if (position > 1)
{
hash = QueueRound(hash, _queue2);
if (position > 2)
hash = QueueRound(hash, _queue3);
}
}
hash = MixFinal(hash);
return (int)hash;
}
#pragma warning disable 0809
// Obsolete member 'memberA' overrides non-obsolete member 'memberB'.
// Disallowing GetHashCode and Equals is by design
// * We decided to not override GetHashCode() to produce the hash code
// as this would be weird, both naming-wise as well as from a
// behavioral standpoint (GetHashCode() should return the object's
// hash code, not the one being computed).
// * Even though ToHashCode() can be called safely multiple times on
// this implementation, it is not part of the contract. If the
// implementation has to change in the future we don't want to worry
// about people who might have incorrectly used this type.
[Obsolete("HashCode is a mutable struct and should not be compared with other HashCodes. Use ToHashCode to retrieve the computed hash code.", error: true)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode() => throw new NotSupportedException("GetHasCode not supported");
[Obsolete("HashCode is a mutable struct and should not be compared with other HashCodes.", error: true)]
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj) => throw new NotSupportedException("Equals is not supported");
#pragma warning restore 0809
} }
} }

63
src/Numerics/Spatial/Internal/Parser.cs

@ -1,63 +0,0 @@
using System;
using System.Globalization;
using System.Text.RegularExpressions;
using MathNet.Numerics.Spatial.Euclidean3D;
#pragma warning disable SA1600 // Elements must be documented
namespace MathNet.Numerics.Spatial.Internal
{
[Obsolete("This should not have been public, will be removed in a future version. Made obsolete 2017-12-03")]
internal static class Parser
{
public const string SeparatorPattern = @" *[,;] *";
public static readonly string DoublePattern = @"[+-]?\d*(?:[.,]\d+)?(?:[eE][+-]?\d+)?";
public static readonly string Vector3DPattern = string.Format(@"^ *\(?(?<x>{0}){1}(?<y>{0}){1}(?<z>{0})\)? *$", DoublePattern, SeparatorPattern);
public static readonly string Vector2DPattern = string.Format(@"^ *\(?(?<x>{0}){1}(?<y>{0})?\)? *$", DoublePattern, SeparatorPattern);
public static readonly string Item3DPattern = Vector3DPattern.Trim('^', '$');
public static readonly string PlanePointVectorPattern = string.Format(@"^ *p: *{{(?<p>{0})}} *v: *{{(?<v>{0})}} *$", Item3DPattern);
public static readonly string PlaneAbcdPattern = string.Format(@"^ *\(?(?<a>{0}){1}(?<b>{0}){1}(?<c>{0}){1}(?<d>{0})\)? *$", DoublePattern, SeparatorPattern);
public static double ParseDouble(Group @group)
{
if (@group.Captures.Count != 1)
{
throw new ArgumentException("Expected single capture");
}
return ParseDouble(@group.Value);
}
public static double ParseDouble(string s)
{
return double.Parse(s.Replace(',', '.'), CultureInfo.InvariantCulture);
}
public static Plane3D ParsePlane(string s)
{
var match = Regex.Match(s, PlanePointVectorPattern);
if (match.Success)
{
var p = Point3D.Parse(match.Groups["p"].Value);
var uv = UnitVector3D.Parse(match.Groups["v"].Value);
return new Plane3D(p, uv);
}
match = Regex.Match(s, PlaneAbcdPattern);
{
var a = ParseDouble(match.Groups["a"]);
var b = ParseDouble(match.Groups["b"]);
var c = ParseDouble(match.Groups["c"]);
var d = ParseDouble(match.Groups["d"]);
return new Plane3D(a, b, c, d);
}
}
public static Ray3D ParseRay3D(string s)
{
var match = Regex.Match(s, PlanePointVectorPattern);
var p = Point3D.Parse(match.Groups["p"].Value);
var uv = UnitVector3D.Parse(match.Groups["v"].Value);
return new Ray3D(p, uv);
}
}
}
Loading…
Cancel
Save