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
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) };
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()

2
src/Numerics/Random/RandomSeed.cs

@ -28,7 +28,7 @@ namespace MathNet.Numerics.Random
}
/// <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
/// calls will result in different seed values. Do not use for cryptography!
/// </summary>

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

@ -39,50 +39,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
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>
/// Gets a point at the origin (0,0)
/// </summary>

31
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.
/// </summary>
public class PolyLine2D : IEnumerable<Point2D>, IEquatable<PolyLine2D>
public class PolyLine2D : IEquatable<PolyLine2D>
{
/// <summary>
/// Internal storage for the points
@ -28,12 +27,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
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>
/// Gets the number of vertices in the polyline.
/// </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>
/// Returns a value that indicates whether each pair of elements in two specified lines is equal.
/// </summary>
@ -253,20 +238,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
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>
/// 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

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

@ -11,7 +11,7 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
/// <summary>
/// Class to represent a closed polygon.
/// </summary>
public class Polygon2D : IEnumerable<Point2D>, IEquatable<Polygon2D>
public class Polygon2D : IEquatable<Polygon2D>
{
/// <summary>
/// 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>
/// Gets a list of vertices
/// </summary>
@ -99,39 +93,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
/// </summary>
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>
/// Returns a value that indicates whether each point in two specified polygons is equal.
/// </summary>
@ -168,32 +129,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
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>
/// 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
/// <returns>A polygon</returns>
public Polygon2D ReduceComplexity(double singleStepTolerance)
{
return new Polygon2D(PolyLine2D.ReduceComplexity(this.ToPolyLine2D(), singleStepTolerance));
return new Polygon2D(PolyLine2D.ReduceComplexity(this.ToPolyLine2D().Vertices, singleStepTolerance).Vertices);
}
/// <summary>
@ -316,26 +251,6 @@ namespace MathNet.Numerics.Spatial.Euclidean2D
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>
/// Returns a value to indicate if a pair of polygons are equal
/// </summary>

44
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;
}
/// <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>
/// Gets a vector representing the X Axis
/// </summary>

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

@ -39,32 +39,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
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>
/// Gets the diameter of the circle
/// </summary>

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

@ -19,7 +19,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// <summary>
/// A local regex pattern for 3D items
/// </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>
/// A local regex pattern for a coordinate system
@ -558,17 +558,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
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>
/// Transforms a line segment.
/// </summary>

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

@ -76,7 +76,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
}
/// <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.
/// </summary>
/// <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>
/// Gets the <see cref="Normal"/> x component.
/// </summary>
@ -169,17 +154,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
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>
/// Get the distance to the point along the <see cref="Normal"/>
/// </summary>
@ -258,7 +232,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// </summary>
/// <param name="line3DToProject">The line to project</param>
/// <returns>A projected line</returns>
[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
/// <param name="line">A line segment</param>
/// <param name="tolerance">A tolerance (epsilon) to account for floating point error.</param>
/// <returns>Intersection Point or null</returns>
[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))

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

@ -45,34 +45,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
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>
/// Gets a point at the origin
/// </summary>

31
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
/// <summary>
/// A PolyLine is an ordered series of line segments in space represented as list of connected Point3Ds.
/// </summary>
public class PolyLine3D : IEnumerable<Point3D>, IEquatable<PolyLine3D>
public class PolyLine3D : IEquatable<PolyLine3D>
{
/// <summary>
/// An internal list of points
@ -27,12 +26,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
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>
/// Gets the number of vertices in the polyline.
/// </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>
/// Returns a value that indicates whether each pair of elements in two specified lines is equal.
/// </summary>
@ -224,20 +209,6 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
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>
/// Returns the length of the polyline by summing the lengths of the individual segments
/// </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));
}
/// <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>
/// Returns the shortest line from a point to the ray
/// </summary>

33
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
/// <param name="x">The x component.</param>
/// <param name="y">The y 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.")]
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;
}
/// <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>
/// Gets the X axis
/// </summary>
@ -601,7 +574,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// </summary>
/// <param name="v">a vector to subtract</param>
/// <returns>A new vector</returns>
[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
/// </summary>
/// <param name="v">a vector to add</param>
/// <returns>A new vector</returns>
[Obsolete("Use + instead")]
[Pure]
public Vector3D Add(UnitVector3D v)
{
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.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;
}
/// <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>
/// Gets an invalid vector with no values
/// </summary>
@ -454,7 +428,7 @@ namespace MathNet.Numerics.Spatial.Euclidean3D
/// </summary>
/// <param name="v">a vector to subtract</param>
/// <returns>A new vector</returns>
[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
/// </summary>
/// <param name="v">a vector to add</param>
/// <returns>A new vector</returns>
[Obsolete("Use + instead")]
[Pure]
public Vector3D Add(Vector3D v)
{

177
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
/// <summary>
/// Generates a hashcode
/// </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 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>(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