Giter VIP home page Giter VIP logo

mathnet-spatial's People

Contributors

bradtglass avatar cdrnet avatar csjune avatar diluculo avatar emostafaali avatar f-frhs avatar imlex avatar jakehedlund avatar jkalias avatar jnyrup avatar johanlarsson avatar jones-adam avatar luisllamasbinaburo avatar maghoumi avatar malin2223 avatar mattj23 avatar mymike00 avatar osbordh avatar rsinnig avatar superusercode avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mathnet-spatial's Issues

Consider to implement fixed matrix types

Fixed matrices with concrete variables and explicit loop-free algorithms could be much faster than inheriting from Math.NET Numerics' DenseMatrix, which is not particularly efficient in this scenario.

  • Transform Matrices
  • CoordinateSystem

Fixed matrices could also be immutable if it makes sense.

@JohanLarsson what do you think on this?

What is outstanding for 1.0.0?

Its not clear what is in the way of bringing mathnet-spatial out of pre-release status.
I'm using it in a couple projects at the moment, and am presonally quite satisfied with it.

If I had insight into what is holding back rolling over to v1.0.0, I might be inclined to help take down some issues.

PolyLine2D/3D and Polygon2D classes

In my work I make common use of 2D and 3D polylines (a series of 2d or 3d points connected by line segments) and 2D polygons (similar to a polyline except that the first and last points are connected, enclosing an area).

I've written classes for my own use that handle these particular constructs and support basic operations, such as computation of length and area, projection of points onto them, convex hulls, etc, as well as unit tests for these operations.

Is this something that fits within the scope of Mathnet.Spatial? If so, if I were to create a branch with these features in it would there be interest in reviewing it?

Ray2D?

Is there a reason why there is no Ray2D class?

Update NuGet package

Hey, I don't know much about NuGet other than my package is older than this version. Can we update it somehow?

Consider offering XML serialization as separate product

The project I'm using mathnet spatial for uses json for serialization instead of xml.
It isn't ideal that my project takes on an xml dependency that is never used.

Can serialization be broken out into a separate nuget package?

Improvements to LineTo on Line3D and Line2D

The Line3D and Line2D structs have a LineTo() method which projects a given point onto a line and then returns the line from the projected point to the given point.

/// <summary>
/// Returns the shortes line to a point
/// </summary>
/// <param name="p"></param>
/// <param name="mustStartBetweenStartAndEnd">If false the startpoint can be on the line extending beyond the start and endpoint of the line</param>
/// <returns></returns>
public Line3D LineTo(Point3D p, bool mustStartBetweenStartAndEnd)
{
    Vector3D v = this.StartPoint.VectorTo(p);
    double dotProduct = v.DotProduct(this.Direction);
    if (mustStartBetweenStartAndEnd)
    {
        if (dotProduct < 0)
        {
            dotProduct = 0;
        }

        var l = this.Length;
        if (dotProduct > l)
        {
            dotProduct = l;
        }
    }

    var alongVector = dotProduct * this.Direction;
    return new Line3D(this.StartPoint + alongVector, p);
}

However, if the point lies sufficiently close to the line, the projected point will be close enough to the given point that the equality comparison returns true, and an ArgumentException will be thrown. Because projecting a point onto a line is a useful operation, another method can be extracted and the resulting code would look like this:

/// <summary>
/// Returns the shortes line to a point
/// </summary>
/// <param name="p"></param>
/// <param name="mustStartBetweenStartAndEnd">If false the startpoint can be on the line extending beyond the start and endpoint of the line</param>
/// <returns></returns>
public Line3D LineTo(Point3D p, bool mustStartBetweenStartAndEnd)
{
    return new Line3D(this.ClosestPointTo(p, mustStartBetweenStartAndEnd), p);
}

/// <summary>
/// Return the closest point on the line to a given point.
/// </summary>
/// <param name="p">The point to find the closest point on the line to</param>
/// <param name="mustBeOnSegment">If true, the returned point will lie between the start and end point of this line.  If false, it will be the point projected onto the line.</param>
/// <returns></returns>
public Point3D ClosestPointTo(Point3D p, bool mustBeOnSegment)
{
    Vector3D v = this.StartPoint.VectorTo(p);
    double dotProduct = v.DotProduct(this.Direction);
    if (mustBeOnSegment)
    {
        if (dotProduct < 0)
        {
            dotProduct = 0;
        }

        var l = this.Length;
        if (dotProduct > l)
        {
            dotProduct = l;
        }
    }

    var alongVector = dotProduct * this.Direction;
    return this.StartPoint + alongVector;
}

...which would allow use of the technique without first testing the point.

If nobody objects to the changes I will do them for Line2D and Line3D and submit a pull request.

Point3D references in Point2D

Logically a 2D point shouldn't have knowledge of higher dimensions. If a library user wishes to convert a 2D point into a 3D point it is more likely they would wish to project the point onto a plane in 3D space which is not handled by this function.

I therefor propose to obsolete the method ToPoint3D method and the Point3D operators.

How to build using fake?

I have managed to build packages using:
Command: $(SolutionDir)build.cmd
Argumants: NuGet all
Initial directory: $(SolutionDir)

Question is what needs to be changed and where before building.
Assembly version is written in a bunch of places. Is RELEASENOTES.md the origin?

External Serialization?

Currently types like Point2D implement IXmlSerializable and also include helper fields like SerializeAsElements.

I tend to prefer external serialization approaches, i.e. an external serializer that can format specific objects or collections of them into XML, binary or other formats. Fields like SerializeAsElements would no longer be needed. To my understanding there already is a partially external serializer to a custom text format.

  • What is the motivation for implementing IXmlSerializable?
  • Is there a specific scenario that requires this?

IsParallelTo method for Line2D (and Line3D)

Per discussion in the issue19 thread, is this what you're thinking?

        /// <summary>
        /// Compute the intersection between two lines
        /// </summary>
        /// <param name="other">The other line to compute the intersection with</param>
        /// <returns>The point at the intersection of two lines, or null if the lines are parallel.</returns>
        public Point2D? IntersectWith(Line2D other)
        {
            if (this.IsParallelTo(other))
                return null;

            // http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
            Point2D p = this.StartPoint;
            Point2D q = other.StartPoint;
            Vector2D r = this.StartPoint.VectorTo(this.EndPoint);
            Vector2D s = other.StartPoint.VectorTo(other.EndPoint);

            double t = (q - p).CrossProduct(s) / (r.CrossProduct(s));

            return p + t * r;
        }

        /// <summary>
        /// Checks to determine whether or not two lines are parallel to each other, using the cross product
        /// </summary>
        /// <param name="other">The other line to check this one against</param>
        /// <returns>True if the lines are parallel, false if they are not</returns>
        public bool IsParallelTo(Line2D other)
        {
            return Math.Abs(this.Direction.CrossProduct(other.Direction)) < double.Epsilon;
        }

I'll happily update it and write some unit tests.

Methods should be marked as pure

To reproduce:
Create a field like this:
private static readonly UnitVector3D DefaultDirection = new UnitVector3D(0, 1, 1);

If you then access it using
DefaultDirection.Negate()
you get a warning from VisualStudio/Resharper:
'Impure method is called for a readonly field of value type'

I guess the method is pure and therefore perhaps it would be possible to give a hint using the [Pure] attribute?
https://msdn.microsoft.com/en-us/library/system.diagnostics.contracts.pureattribute(v=vs.110).aspx

New Shape: Triangle2D

Proposed new shape triangle. There are many specific features and optimisations for triangles which could be implemented here.

Polygon2D.GetConvexHullFromPoints sometimes returns incorrect convex hull

I was trying to test my own convex hull algorithm by comparing its result with Polygon2D.GetConvexHullFromPoints, and I think I have discovered a case where the latter returns an incorrect result. The unit test below reproduces it, and I have attached a spreadsheet that plots the points, the convex hull returned by GetConvexHullFromPoints, and what should be the actual convex hull.
MathNet ConvexHull tests.xlsx

[Test]
public void MathNetConvexHullTest()
{
    // Arrange
    var somePoints = new List<Point2D>
    {
        new Point2D(-201.573, 100.940),
        new Point2D(197.083, 21.031),
        new Point2D(161.021, -29.414),
        new Point2D(114.223, -23.998),
        new Point2D(230.290, -68.246),
        new Point2D(-32.272, 182.239),
        new Point2D(-173.345, 72.736),
        new Point2D(-175.435, -176.273),
        new Point2D(90.810, -97.350),
        new Point2D(-196.942, 216.594),
        new Point2D(67.759, -162.464),
        new Point2D(67.454, -174.844),
        new Point2D(-89.116, 171.982),
        new Point2D(-18.421, 11.935),
        new Point2D(73.816, -180.169),
        new Point2D(-103.560, -36.297),
        new Point2D(-233.800, 194.296),
        new Point2D(-64.463, 166.811),
        new Point2D(-17.182, 83.403),
        new Point2D(-72.010, 219.944)
    };

    // Act
    var convexHull = Polygon2D.GetConvexHullFromPoints(somePoints);

    // Assert
    // first check: all the other points must be inside the convex hull
    var pointsNotOnConvexHull = somePoints.Except(convexHull);
    foreach (var pointNotOnConvexHull in pointsNotOnConvexHull)
    {
        var pointIsInsideConvexHull = Polygon2D.IsPointInPolygon(pointNotOnConvexHull, convexHull);
        Assert.That(pointIsInsideConvexHull);
    }

    // second check: if we remove any point from the convex hull and build a new convex hull
    // then that point should be outside the new convex hull; if it's inside then our new
    // convex hull is the actual convex hull, which means the original one wasn't!
    foreach (var pointToRemove in convexHull)
    {
        var convexHullWithPointRemoved = new Polygon2D(convexHull.Except(new[] { pointToRemove }));
        var pointIsInsideConvexHull =
            Polygon2D.IsPointInPolygon(pointToRemove, convexHullWithPointRemoved);
        Assert.That(pointIsInsideConvexHull, Is.Not.True);
    }
}

The points are just a random set of 20 points with co-ordinates between -500 and 500.

Formatting

I noticed you use no space between operators 1*2, I have R# set up as close to StyleCop's rules as I can. We should find a common formatting so we don't get noisy diffs.

  • Do you use Resharper?
  • Do you agree with StyleCops rules? I do not agree with all rules but have no problem adjusting uniform style > personal preference imo.

Review

The code is varying quality with CoordinateSystem the hairiest, don't hesitate to remove stuff that seems dumb. I'll move things to extension methods in our internal lib if needed.

  • Is public readonly fields a good idea? I was not sure but like the way it communicates immutability. Binding in wpf is an issue.
  • Refactoring to structs lead to really nasty code duplication, I just closed my eyes and copy pasted. Is there a nicer way to write it?
  • Test coverage & tests overall are perhaps not superclean. I'll try to add more tests.
  • /// comments are at very low frequency.

.Net 4.0

Hi

According to https://www.nuget.org/packages/MathNet.Spatial/ the NuGet-package should be installable with .Net 4.0. But when I tried to install it on a .Net 4.0-project with the commando
"Install-Package MathNet.Spatial -Pre"
the installation failed. After I changed the project to .Net 4.5, the installation succeeded.

Can you change the NuGet-package so that the installation works on a .Net 4.0-project? That would be very helpful.

Kind regards

Simon

CoordinateSystem Transformation Methods Behaving Unexpected

The methods Transform, TransformToCoordSys and TransformFromCoordSys of the CoordinateSystem class are behaving unexpected and are hard to understand.
Transform() seems to transform a point from the CoordinateSystem to the base system. This is not visible from either the method name or the comment ("Transforms a point and returns the transformed point").

The TransformFrom and TransformTo methods seem to do a proper transform but add the offset afterwards, which in my opinion does not make much sense. But maybe I'm missing something.

Unfortunately there are no unit tests explaining the expected behaviour of these methods.

We are willing to contribute but at first we have to understand what is expected from the methods and if a change in interface or behaviour is acceptable.

Quaternion as Roll, Pitch And Yaw.

Whilst playing with quaternions, I have found this incredibly useful. Would being able to convert a quaternion to, and create a quaternion from RPY be useful for this library? The code I have for this is using the System.Numerics quaternions, but with some tweaks could slide nicely in here.

RPY coordinate system

I get the yaw,pitch,roll from robot, but the rotation order is rotation around X (roll) then around Y (pitch) and then around Z (yaw),the order of CoordinateSystem class is YPR,how can I get RPY coordinate in CoordinateSystem?

Expanding Plane Geometry

Hi,

I would like to expand Mathnet-spatial to include more aspects of plane geometry (2D). In particular adding support for different types of lines and shapes and make it a first class feature of the library. Since its a structural change to the library I thought it more polite to run it by you before sending a pull request

To this end I propose a few alterations to the namespace structure to create
Euclidean -> PlaneGeometry -> Shapes
-> Lines

Into shapes the idea is to progressively add various common shape constructs (ellipses, rectangles, triangles, etc). Into Lines would go support for various curve types (parabola, hyperbola, etc.)

A few breaking changes would be required such as renaming Line2D to LineSegment to avoid confusion with the geometric definition of a Line and moving existing 2D constructs into the new namespaces.

Perhaps it is easier to explain by showing what I suggest to change - https://github.com/AQuentin2033/mathnet-spatial/commit/c8a0b0f483d51285386320c891491945d789d8c9

Anyway would that work as a direction for you?

.NET Core support

The use of .net core is required, and will now become more important with visual studio 2017.

My personal requirement is to be able to use mathnet-spatial with docker so that we can scale up and down the number of calculation engines.

Note: this is currently blocked by:
mathnet/mathnet-numerics#386

But could be trialed in a branch by using the temporary solution in:
MathNet.Numerics.Core

Coordinate system Pitch, Roll, Yaw bug

After rotating a CSY (Coordinate System) around any of axis, by using e.g. CoordinateSystem.Pitch, CSY rotates successfully, rotation matrix contains correct values. After further rotating it with the same (or any other) angle, rotation matrix is not showing correct results, at least what I was expecting. It seems like it rotates again from the original state of a CSY, that it had before the first rotation. After the second rotation CSY again has as same rotation matrix as after the first rotation.

I have no idea how to use paket to update references

Here is what I tried:
.\tools\paket\paket update
Updated the packages but removed ref to mathnet.numerics from projects.

Locked version resolutions written to C:\Git\Third Party\mathnet-spatial\paket.lock

  • custom nodes for MathNet.Numerics ==> skipping
  • custom nodes for MathNet.Numerics ==> skipping

Think ^ has something to do with it.

Limits of floating point

Sorry this is a bit long but its a complex issue...

Currently in the library it is possible to specify a tolerance when comparing two points or two angles, but not for comparing two lines or two circles. In the case of the composites the comparisons always use the default equal operators, however due to rounding point errors this might mean ni a given context that two circles which should be considered the same are treated as different in the library. So somehow I should be able to specify what the tolerance is in every case where a comparison is done - however as a library user I potentially have no idea what kind of operations or calculations have gone into a given comparison, so I really have no idea what a good tolerance should be. If its just comparing values I have provided that is one thing, if its using the result of a calculation the library has performed for me, that's another. So this leaves me with a number of potentially broken scenarios where the library either offers me no help (by asking me for a tolerance I do not know enough to provide), or at worse hinders me (by ignoring tolerances altogether and potentially hiding the accumulating errors).

Perhaps the solution to this lies in looking at the problem from a different perspective.. Lets say I have a coordinate system which has a limit of resolution of 2 decimal places. After which in this particular context further precision is meaningless to me. Now I could go and preprocess every value entering and coming from the library to fit to my needs but it would be infinitely nicer if the library allowed me to specify in a single place the limits of resolution for my coordinate system (points and angles) and automatically adhered to it with any return or calculation it provided to me.
This kind of limit to the needed precision can easily be specified by the library user according to their particular context (and within the bounds of resolution of a double). While it doesn't specifically address the errors of floating point math, it does offer a context sensitive way to make it a less significant issue

I think the most obvious place for such a thing would be static properties on CoordinateSystem and have those types which use doubles to adhere to it on return values and comparisons (but keep using the full value internally for calculations). It could potentially allow either a fixed number of decimal places or a fixed number of overall digits to allow for maximum flexibility.

Anyway more than open to other suggestions if anyone can think of a better way to handle this.

New Shape: Quadrilateral2D

Proposed new shape Quadrilateral. A 4 sided, 4 angled shape.

This shape can offer specific implementations of methods which either do not generalize to polygons or which are more optimally implemented within the constraints of a 4 sided figure.

Geometrical figures

Hello. Is Math.NET Spatial is the proper place to add some geometrical figures such as cubes, spheres, cylinders etc?

I am working on multiple scientific projects and really tired of copying the definitions for all the basic geometry back and forth. Math.NET Spatial have all these great definitions for points and vectors, and that's cool already. But could we have the figures also?

I'm looking forward to contribute some stuff, but I am still in doubts about
a) whether Math.NET Spatial is the proper place to put this stuff
b) about the quality of my code - I am not the professional mathematician at all, I just have to work with some simple spatial definitions on a day to day basis.

What can you guys say? Maybe some ideas about what absolute minimal methods/definitions we should add to the figures or how the code should be structured (with inheritance from base Figure class or some another functional stuff)?

I am thinking about adding some basic stuff first (such as Box3D and Sphere3D maybe?) and adding the new methods (intersections/etc) based on the community feedback.

Maybe someone is already working on it?

Point3D ItersectionOf() typo

The Point3D class appears to have a typo in the IntersectionOf method name.

        public static Point3D ItersectionOf(Plane plane1, Plane plane2, Plane plane3)
        {
            var ray = plane1.IntersectionWith(plane2);
            return plane3.IntersectionWith(ray);
        }

        public static Point3D ItersectionOf(Plane plane, Ray3D ray)
        {
            return plane.IntersectionWith(ray);
        }

I fixed it in the method names and the unit tests in a fork, or I'll happily add renamed methods side-by-side to not break the semantics and add them to the unit tests if you'd like.

Circle3D from three points

I'm working on a project where I need a Circle3D from three points. I will implement this and submit a pull request.

Vector3D.AngleTo-implementation sometimes returns NaN

Hi

The following test fails:

  Vector3D v1 = new Vector3D(-1.0, -1.0, 1.0);
  Vector3D v2 = new Vector3D(-1.0, -1.0, 1.0);
  var angle = v1.AngleTo(v2);
  Assert.AreEqual(0, angle.Degrees);

For the two equal vectors, AngleTo returns an angle with NaN as value. The reason lies in the AngleTo-method of UnitVector3D:

    public Angle AngleTo(UnitVector3D v)
    {
        var dp = this.DotProduct(v);

        var angle = Math.Acos(dp);
        return new Angle(angle, AngleUnit.Radians);
    }

The dp-value is slightly above 1. This value is invalid for the Math.Acos-function which causes it to return NaN. The reason for the dp-value are rounding errors when the Vector3D-objects are converted into UnitVector3D-objects during the normalization.

The same error happens when the vectors are opposite, in that case dp is below -1.

A solution would be to check if dp is above 1 or below -1. In that case the angle must be 0° or 180°.

    public Angle AngleTo(UnitVector3D v)
    {
        var dp = this.DotProduct(v);

        if (dp > 1)
        {
          return Angle.FromDegrees(0);
        }
        if (dp < -1)
        {
          return Angle.FromDegrees(180);
        }

        var angle = Math.Acos(dp);
        return new Angle(angle, AngleUnit.Radians);
    }

Kind regards

Simon

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.