diff --git a/src/Numerics.Tests/Spatial/Euclidean2D/Polygon2DTests.cs b/src/Numerics.Tests/Spatial/Euclidean2D/Polygon2DTests.cs index ea6b7608..df26edcd 100644 --- a/src/Numerics.Tests/Spatial/Euclidean2D/Polygon2DTests.cs +++ b/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 var polygon = TestPolygon2(); var checkList = new List { 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)] @@ -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) { 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! foreach (var pointToRemove in counterClockwiseVertices) { - var convexHullWithPointRemoved = new Polygon2D(hullCounterClockwise.Except(new[] { pointToRemove })); + var convexHullWithPointRemoved = new Polygon2D(hullCounterClockwise.Vertices.Except(new[] { pointToRemove })); var pointIsInsideConvexHull = convexHullWithPointRemoved.EnclosesPoint(pointToRemove); Assert.That(pointIsInsideConvexHull, Is.Not.True); @@ -156,7 +156,7 @@ namespace MathNet.Numerics.Tests.Spatial.Euclidean2D var expected = new Polygon2D(expectedPoints); var thinned = poly.ReduceComplexity(0.00001); - CollectionAssert.AreEqual(expected, thinned); + CollectionAssert.AreEqual(expected.Vertices, thinned.Vertices); } private static Polygon2D TestPolygon1() diff --git a/src/Numerics/Random/RandomSeed.cs b/src/Numerics/Random/RandomSeed.cs index fb8b89b8..a060b3bb 100644 --- a/src/Numerics/Random/RandomSeed.cs +++ b/src/Numerics/Random/RandomSeed.cs @@ -28,7 +28,7 @@ namespace MathNet.Numerics.Random } /// - /// 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 /// calls will result in different seed values. Do not use for cryptography! /// diff --git a/src/Numerics/Spatial/Euclidean2D/Point2D.cs b/src/Numerics/Spatial/Euclidean2D/Point2D.cs index cc83508a..5adda75f 100644 --- a/src/Numerics/Spatial/Euclidean2D/Point2D.cs +++ b/src/Numerics/Spatial/Euclidean2D/Point2D.cs @@ -39,50 +39,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D this.Y = y; } - /// - /// Initializes a new instance of the struct. - /// Creates a point r from origin rotated a counterclockwise from X-Axis - /// - /// distance from origin - /// the angle - [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."); - } - } - - /// - /// Initializes a new instance of the struct. - /// Creates a point from a list of coordinates (x, y) - /// - /// a pair of coordinates in the order x, y - /// Exception thrown if more than 2 coordinates are passed - [Obsolete("This constructor will be removed. Made obsolete 2017-12-03.")] - public Point2D(IEnumerable data) - : this(data.ToArray()) - { - } - - /// - /// Initializes a new instance of the struct. - /// Creates a point from a list of coordinates (x, y) - /// - /// a pair of coordinates in the order x, y - /// Exception thrown if more than 2 coordinates are passed - [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!"); - } - } - /// /// Gets a point at the origin (0,0) /// diff --git a/src/Numerics/Spatial/Euclidean2D/PolyLine2D.cs b/src/Numerics/Spatial/Euclidean2D/PolyLine2D.cs index 1191dda3..7e698a99 100644 --- a/src/Numerics/Spatial/Euclidean2D/PolyLine2D.cs +++ b/src/Numerics/Spatial/Euclidean2D/PolyLine2D.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics.Contracts; 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 /// stored as a sequential list of 2D points. /// - public class PolyLine2D : IEnumerable, IEquatable + public class PolyLine2D : IEquatable { /// /// Internal storage for the points @@ -28,12 +27,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D this.points = new List(points); } - /// - /// Gets the number of points in the polyline - /// - [Obsolete("Use VertexCount instead, obsolete since 2018-01-12")] - public int Count => this.points.Count; - /// /// Gets the number of vertices in the polyline. /// @@ -58,14 +51,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D } } - /// - /// Returns a point in the polyline by index number - /// - /// The index of a point - /// The indexed point - [Obsolete("Use Vertices instead, obsolete since 2018-01-12")] - public Point2D this[int key] => this.points[key]; - /// /// Returns a value that indicates whether each pair of elements in two specified lines is equal. /// @@ -253,20 +238,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D return HashCode.CombineMany(this.points); } - /// - [Obsolete("Use Vertices instead, obsolete since 2018-01-12")] - public IEnumerator GetEnumerator() - { - return this.points.GetEnumerator(); - } - - /// - [Obsolete("Use Vertices instead, obsolete since 2018-01-12")] - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - /// /// 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 diff --git a/src/Numerics/Spatial/Euclidean2D/Polygon2D.cs b/src/Numerics/Spatial/Euclidean2D/Polygon2D.cs index daefc935..5e388e44 100644 --- a/src/Numerics/Spatial/Euclidean2D/Polygon2D.cs +++ b/src/Numerics/Spatial/Euclidean2D/Polygon2D.cs @@ -11,7 +11,7 @@ namespace MathNet.Numerics.Spatial.Euclidean2D /// /// Class to represent a closed polygon. /// - public class Polygon2D : IEnumerable, IEquatable + public class Polygon2D : IEquatable { /// /// A list of vertices. @@ -55,12 +55,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D } } - /// - /// Gets the number of vertices in the polygon. - /// - [Obsolete("Use VertexCount instead, obsolete since 6/12/2017")] - public int Count => this.points.Count; - /// /// Gets a list of vertices /// @@ -99,39 +93,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D /// public int VertexCount => this.points.Count; - /// - /// A index into the list of vertices - /// - /// An index for the vertex number - /// A Vertex - [Obsolete("Use Vertices instead, obsolete since 6/12/2017")] - public Point2D this[int key] => this.points[key]; - - /// - /// Adds a vector to the each point on the polygon - /// - /// The vector to add - /// The polygon - /// A new at the adjusted points - [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); - } - - /// - /// Adds a vector to the each point on the polygon - /// - /// The polygon - /// The vector to add - /// A new at the adjusted points - [Obsolete("Use Translate instance method instead, obsolete since 6/12/2017")] - public static Polygon2D operator +(Polygon2D poly, Vector2D shift) - { - return shift + poly; - } - /// /// Returns a value that indicates whether each point in two specified polygons is equal. /// @@ -168,32 +129,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D return a.points.Any(b.EnclosesPoint) || b.points.Any(a.EnclosesPoint); } - /// - /// 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. - /// - /// A point - /// A polygon - /// True if the point is inside the polygon; otherwise false. - [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; - } - /// /// 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. @@ -261,7 +196,7 @@ namespace MathNet.Numerics.Spatial.Euclidean2D /// A polygon public Polygon2D ReduceComplexity(double singleStepTolerance) { - return new Polygon2D(PolyLine2D.ReduceComplexity(this.ToPolyLine2D(), singleStepTolerance)); + return new Polygon2D(PolyLine2D.ReduceComplexity(this.ToPolyLine2D().Vertices, singleStepTolerance).Vertices); } /// @@ -316,26 +251,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D return new PolyLine2D(points); } - /// - /// Returns an enumerator for the vertices - /// - /// An enumerator for the vertices - [Obsolete("Use Vertices instead, obsolete since 6/12/2017")] - public IEnumerator GetEnumerator() - { - return this.points.GetEnumerator(); - } - - /// - /// Returns an enumerator for the vertices - /// - /// An enumerator for the vertices - [Obsolete("Use Vertices instead, obsolete since 6/12/2017")] - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - /// /// Returns a value to indicate if a pair of polygons are equal /// diff --git a/src/Numerics/Spatial/Euclidean2D/Vector2D.cs b/src/Numerics/Spatial/Euclidean2D/Vector2D.cs index 394c56f6..671b1a89 100644 --- a/src/Numerics/Spatial/Euclidean2D/Vector2D.cs +++ b/src/Numerics/Spatial/Euclidean2D/Vector2D.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Globalization; -using System.Linq; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; @@ -38,48 +36,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D this.Y = y; } - /// - /// Initializes a new instance of the struct. - /// Creates a vector with length r rotated a counterclockwise from X-Axis - /// - /// The radius - /// The angle - [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."); - } - } - - /// - /// Initializes a new instance of the struct. - /// - /// A list of 2 doubles - [Obsolete("This constructor will be removed. Made obsolete 2017-12-03.")] - //// ReSharper disable once UnusedMember.Global - public Vector2D(IEnumerable data) - : this(data.ToArray()) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// A list of 2 doubles - [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!"); - } - } - /// /// Gets a vector representing the X Axis /// diff --git a/src/Numerics/Spatial/Euclidean3D/Circle3D.cs b/src/Numerics/Spatial/Euclidean3D/Circle3D.cs index f2eaa2e3..0148b5b5 100644 --- a/src/Numerics/Spatial/Euclidean3D/Circle3D.cs +++ b/src/Numerics/Spatial/Euclidean3D/Circle3D.cs @@ -39,32 +39,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D this.Radius = radius; } - /// - /// Initializes a new instance of the struct. - /// Create a circle from the midpoint between two points, in a direction along a specified axis - /// - /// First point on the circumference of the circle - /// Second point on the circumference of the circle - /// Direction of the plane in which the circle lies - [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); - } - - /// - /// Initializes a new instance of the struct. - /// Create a circle from three points which lie along its circumference. - /// - /// The first point on the circle - /// The second point on the circle - /// The third point on the circle - [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); - } - /// /// Gets the diameter of the circle /// diff --git a/src/Numerics/Spatial/Euclidean3D/CoordinateSystem3D.cs b/src/Numerics/Spatial/Euclidean3D/CoordinateSystem3D.cs index a18b1aaa..f7843ea1 100644 --- a/src/Numerics/Spatial/Euclidean3D/CoordinateSystem3D.cs +++ b/src/Numerics/Spatial/Euclidean3D/CoordinateSystem3D.cs @@ -19,7 +19,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D /// /// A local regex pattern for 3D items /// - private static readonly string Item3DPattern = Parser.Vector3DPattern.Trim('^', '$'); + private static readonly string Item3DPattern = string.Format(@"^ *\(?(?{0}){1}(?{0}){1}(?{0})\)? *$", @"[+-]?\d*(?:[.,]\d+)?(?:[eE][+-]?\d+)?", @" *[,;] *").Trim('^', '$'); /// /// A local regex pattern for a coordinate system @@ -558,17 +558,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D return new CoordinateSystem3D(this.Multiply(cs)); } - /// - /// Transforms a line and returns the transformed. - /// - /// A line - /// A transformed line - [Obsolete("Use LineSegment3D, Obsolete from 2017-12-10")] - public Line3D Transform(Line3D l) - { - return new Line3D(this.Transform(l.StartPoint), this.Transform(l.EndPoint)); - } - /// /// Transforms a line segment. /// diff --git a/src/Numerics/Spatial/Euclidean3D/Line3D.cs b/src/Numerics/Spatial/Euclidean3D/Line3D.cs index 54b98e9b..61adc027 100644 --- a/src/Numerics/Spatial/Euclidean3D/Line3D.cs +++ b/src/Numerics/Spatial/Euclidean3D/Line3D.cs @@ -76,7 +76,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D } /// - /// Returns a new from a pair of strings which represent points. + /// Returns a new from a pair of strings which represent points. /// See for details on acceptable formats. /// /// The string representation of the first point. diff --git a/src/Numerics/Spatial/Euclidean3D/Plane3D.cs b/src/Numerics/Spatial/Euclidean3D/Plane3D.cs index 35db26a5..3ff91baf 100644 --- a/src/Numerics/Spatial/Euclidean3D/Plane3D.cs +++ b/src/Numerics/Spatial/Euclidean3D/Plane3D.cs @@ -72,21 +72,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D { } - /// - /// Initializes a new instance of the struct. - /// Creates a Plane that contains the three given points. - /// http://www.had2know.com/academics/equation-plane-through-3-points.html - /// - /// The first point on the Plane. - /// The second point on the Plane. - /// The third point on the Plane. - /// The Plane containing the three points. - [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); - } - /// /// Gets the x component. /// @@ -169,17 +154,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D return Point3D.IntersectionOf(plane1, plane2, plane3); } - /// - /// Creates a Plane from its string representation - /// - /// The string representation of the Plane - /// a new Plane - [Obsolete("Should not have been made public, removed on 9/12/2017")] - public static Plane3D Parse(string s) - { - return Parser.ParsePlane(s); - } - /// /// Get the distance to the point along the /// @@ -258,7 +232,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D /// /// The line to project /// A projected line - [Obsolete("Use LineSegment3D instead, obsolete from 2017-12-10")] public Line3D Project(Line3D line3DToProject) { var projectedStartPoint = this.Project(line3DToProject.StartPoint); @@ -354,7 +327,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D /// A line segment /// A tolerance (epsilon) to account for floating point error. /// Intersection Point or null - [Obsolete("Use LineSegment3D instead, Obsolete from 2017-12-10")] public Point3D? IntersectionWith(Line3D line, double tolerance = float.Epsilon) { if (line.Direction.IsPerpendicularTo(this.Normal, tolerance)) diff --git a/src/Numerics/Spatial/Euclidean3D/Point3D.cs b/src/Numerics/Spatial/Euclidean3D/Point3D.cs index 08bd6d19..3bf49e89 100644 --- a/src/Numerics/Spatial/Euclidean3D/Point3D.cs +++ b/src/Numerics/Spatial/Euclidean3D/Point3D.cs @@ -45,34 +45,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D this.Z = z; } - /// - /// Initializes a new instance of the struct. - /// Creates a point from a list of coordinates (x, y, z) - /// - /// a list of coordinates in the order x, y, z - /// Exception thrown if anything other than 3 coordinates are passed - [Obsolete("This constructor will be removed. Made obsolete 2017-12-05.")] - public Point3D(IEnumerable data) - : this(data.ToArray()) - { - } - - /// - /// Initializes a new instance of the struct. - /// Creates a point from a list of coordinates (x, y, z) - /// - /// a size 3 array of coordinates in the order x, y, z - /// Exception thrown if anything other than 3 coordinates are passed - [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"); - } - } - /// /// Gets a point at the origin /// diff --git a/src/Numerics/Spatial/Euclidean3D/PolyLine3D.cs b/src/Numerics/Spatial/Euclidean3D/PolyLine3D.cs index 8b0b3442..09c38ce3 100644 --- a/src/Numerics/Spatial/Euclidean3D/PolyLine3D.cs +++ b/src/Numerics/Spatial/Euclidean3D/PolyLine3D.cs @@ -1,5 +1,4 @@ using System; -using System.Collections; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; @@ -10,7 +9,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D /// /// A PolyLine is an ordered series of line segments in space represented as list of connected Point3Ds. /// - public class PolyLine3D : IEnumerable, IEquatable + public class PolyLine3D : IEquatable { /// /// An internal list of points @@ -27,12 +26,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D this.points = new List(points); } - /// - /// Gets an integer representing the number of Point3D objects in the polyline - /// - [Obsolete("Use VertexCount instead, obsolete since 2018-01-12")] - public int Count => this.points.Count; - /// /// Gets the number of vertices in the polyline. /// @@ -57,14 +50,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D } } - /// - /// Returns a point in the polyline by index number - /// - /// The index of a point - /// The indexed point - [Obsolete("Use Vertices instead, obsolete since 2018-01-12")] - public Point3D this[int key] => this.points[key]; - /// /// Returns a value that indicates whether each pair of elements in two specified lines is equal. /// @@ -224,20 +209,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D return HashCode.CombineMany(this.points); } - /// - [Obsolete("Use Vertices instead, obsolete since 2018-01-12")] - public IEnumerator GetEnumerator() - { - return this.points.GetEnumerator(); - } - - /// - [Obsolete("Use Vertices instead, obsolete since 2018-01-12")] - IEnumerator IEnumerable.GetEnumerator() - { - return this.GetEnumerator(); - } - /// /// Returns the length of the polyline by summing the lengths of the individual segments /// diff --git a/src/Numerics/Spatial/Euclidean3D/Ray3D.cs b/src/Numerics/Spatial/Euclidean3D/Ray3D.cs index dedb8d79..e8c98808 100644 --- a/src/Numerics/Spatial/Euclidean3D/Ray3D.cs +++ b/src/Numerics/Spatial/Euclidean3D/Ray3D.cs @@ -92,32 +92,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D return new Ray3D(Point3D.Parse(point), UnitVector3D.Parse(direction)); } - /// - /// Parses a string in the format: 'p:{1, 2, 3} v:{0, 0, 1}' to a Ray3D - /// This is mainly meant for tests - /// - /// a string representing the ray - /// a ray - [Obsolete("Should not have been made public. Mode Obsolete 2017-12-09")] - public static Ray3D Parse(string s) - { - return Parser.ParseRay3D(s); - } - - /// - /// Returns the shortest line from a point to the ray - /// - /// A point. - /// A line segment from the point to the closest point on the ray - [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); - } - /// /// Returns the shortest line from a point to the ray /// diff --git a/src/Numerics/Spatial/Euclidean3D/UnitVector3D.cs b/src/Numerics/Spatial/Euclidean3D/UnitVector3D.cs index 7b064f9c..02ce83b5 100644 --- a/src/Numerics/Spatial/Euclidean3D/UnitVector3D.cs +++ b/src/Numerics/Spatial/Euclidean3D/UnitVector3D.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Globalization; -using System.Linq; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; @@ -39,8 +37,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D /// The x component. /// The y component. /// The z component. - [Obsolete("This constructor will be made private, prefer the factory method Create. Made obsolete 2017-12-05.")] - public UnitVector3D(double x, double y, double z) + private UnitVector3D(double x, double y, double z) { if (double.IsNaN(x) || double.IsInfinity(x)) { @@ -68,30 +65,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D this.Z = z / norm; } - /// - /// Initializes a new instance of the struct. - /// - /// A list of 3 points - [Obsolete("This constructor will be removed. Made obsolete 2017-12-05.")] - public UnitVector3D(IEnumerable data) - : this(data.ToArray()) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// A list of 3 points - [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"); - } - } - /// /// Gets the X axis /// @@ -601,7 +574,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D /// /// a vector to subtract /// A new vector - [Obsolete("Use - instead")] + [Pure] public Vector3D Subtract(UnitVector3D v) { return new Vector3D(this.X - v.X, this.Y - v.Y, this.Z - v.Z); @@ -612,7 +585,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D /// /// a vector to add /// A new vector - [Obsolete("Use + instead")] + [Pure] public Vector3D Add(UnitVector3D v) { return new Vector3D(this.X + v.X, this.Y + v.Y, this.Z + v.Z); diff --git a/src/Numerics/Spatial/Euclidean3D/Vector3D.cs b/src/Numerics/Spatial/Euclidean3D/Vector3D.cs index ee4a301a..ad1b0a75 100644 --- a/src/Numerics/Spatial/Euclidean3D/Vector3D.cs +++ b/src/Numerics/Spatial/Euclidean3D/Vector3D.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Globalization; -using System.Linq; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; @@ -45,30 +43,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D this.Z = z; } - /// - /// Initializes a new instance of the struct. - /// - /// A list of 3 doubles - [Obsolete("This constructor will be removed. Made obsolete 2017-12-05.")] - public Vector3D(IEnumerable data) - : this(data.ToArray()) - { - } - - /// - /// Initializes a new instance of the struct. - /// - /// A list of 3 doubles - [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"); - } - } - /// /// Gets an invalid vector with no values /// @@ -454,7 +428,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D /// /// a vector to subtract /// A new vector - [Obsolete("Use - instead")] + [Pure] public Vector3D Subtract(Vector3D v) { return new Vector3D(this.X - v.X, this.Y - v.Y, this.Z - v.Z); @@ -465,7 +439,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D /// /// a vector to add /// A new vector - [Obsolete("Use + instead")] [Pure] public Vector3D Add(Vector3D v) { diff --git a/src/Numerics/Spatial/Internal/HashCode.cs b/src/Numerics/Spatial/Internal/HashCode.cs index 26fc67cc..4d676a05 100644 --- a/src/Numerics/Spatial/Internal/HashCode.cs +++ b/src/Numerics/Spatial/Internal/HashCode.cs @@ -1,6 +1,6 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using MathNet.Numerics.Random; namespace MathNet.Numerics.Spatial.Internal { @@ -56,9 +56,9 @@ namespace MathNet.Numerics.Spatial.Internal /// /// Generates a hashcode /// - 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 Prime2 = 2246822519U; @@ -66,15 +66,10 @@ namespace MathNet.Numerics.Spatial.Internal private const uint Prime4 = 668265263U; private const uint Prime5 = 374761393U; - private uint _v1, _v2, _v3, _v4; - private uint _queue1, _queue2, _queue3; - private uint _length; - private static uint GenerateGlobalSeed() { - // NOTE: Modified from original unsafe implementation. Might be better to use a more random seed. - System.Random r = new System.Random(); - int seed = r.Next(); + // NOTE: Modified from original unsafe implementation. + int seed = RandomSeed.Robust(); return unchecked((uint)seed); } @@ -319,20 +314,26 @@ namespace MathNet.Numerics.Spatial.Internal return (int)hash; } - // [MethodImpl(MethodImplOptions.AggressiveInlining)] +#if !NET40 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif private static uint Rol(uint value, int 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) { - v1 = s_seed + Prime1 + Prime2; - v2 = s_seed + Prime2; - v3 = s_seed; - v4 = s_seed - Prime1; + v1 = Seed + Prime1 + Prime2; + v2 = Seed + Prime2; + v3 = Seed; + v4 = Seed - Prime1; } - // [MethodImpl(MethodImplOptions.AggressiveInlining)] +#if !NET40 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif private static uint Round(uint hash, uint input) { hash += input * Prime2; @@ -341,14 +342,18 @@ namespace MathNet.Numerics.Spatial.Internal return hash; } - // [MethodImpl(MethodImplOptions.AggressiveInlining)] +#if !NET40 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif private static uint QueueRound(uint hash, uint queuedValue) { hash += queuedValue * Prime3; 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) { 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() { - return s_seed + Prime5; + return Seed + Prime5; } - // [MethodImpl(MethodImplOptions.AggressiveInlining)] +#if !NET40 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#endif private static uint MixFinal(uint hash) { hash ^= hash >> 15; @@ -369,129 +376,5 @@ namespace MathNet.Numerics.Spatial.Internal hash ^= hash >> 16; return hash; } - - public void Add(T value) - { - Add(value?.GetHashCode() ?? 0); - } - - public void Add(T value, IEqualityComparer 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 } } diff --git a/src/Numerics/Spatial/Internal/Parser.cs b/src/Numerics/Spatial/Internal/Parser.cs deleted file mode 100644 index bd744ea4..00000000 --- a/src/Numerics/Spatial/Internal/Parser.cs +++ /dev/null @@ -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(@"^ *\(?(?{0}){1}(?{0}){1}(?{0})\)? *$", DoublePattern, SeparatorPattern); - public static readonly string Vector2DPattern = string.Format(@"^ *\(?(?{0}){1}(?{0})?\)? *$", DoublePattern, SeparatorPattern); - public static readonly string Item3DPattern = Vector3DPattern.Trim('^', '$'); - public static readonly string PlanePointVectorPattern = string.Format(@"^ *p: *{{(?

{0})}} *v: *{{(?{0})}} *$", Item3DPattern); - public static readonly string PlaneAbcdPattern = string.Format(@"^ *\(?(?{0}){1}(?{0}){1}(?{0}){1}(?{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); - } - } -}