mathnet / mathnet-spatial Goto Github PK
View Code? Open in Web Editor NEWMath.NET Spatial
Home Page: http://spatial.mathdotnet.com
License: MIT License
Math.NET Spatial
Home Page: http://spatial.mathdotnet.com
License: MIT License
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.
Fixed matrices could also be immutable if it makes sense.
@JohanLarsson what do you think on this?
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.
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?
Is there a reason why there is no Ray2D class?
Hey, I don't know much about NuGet other than my package is older than this version. Can we update it somehow?
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?
I looked but could not find it.
Would be nice to be able to use for the new Universal Windows framework. Thanks!
Is this really the right place for the two static functions
ChybyshevCosPoli
ChybyshevSinPoli
Which do not directly relate to quaternions?
[enhancement]
Add support for Sexagesimal format for creating angles
Angle.FromSexagesimal(int degrees, int minutes, double seconds)
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.
For the plane class, following constructor is documented:
Plane(Point3D p1, Point3D p2, Point3D p3)
but it is missing from the code.
Adds some nice features like pattern matching.
This results in a wrong ordering of the points on the convex hull.
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.
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?
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.
IXmlSerializable
?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.
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
Proposed new shape triangle. There are many specific features and optimisations for triangles which could be implemented here.
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.
See:
Maybe it makes sense to use their fixed-sized vectors, maybe not.
(low priority)
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.
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.
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
Is there a reason for
MathNet.Spatial.Euclidean.Matrix3D.RotationAround{X|Y}Axis(angle)
returning a DenseMatrix
and
MathNet.Spatial.Euclidean.Matrix3D.RotationAroundZAxis(angle)
returning a Matrix<double>
or is it just a typo?
I think Quaternions would fit very well to this library. We had one back in old Math.NET Iridium, maybe we can use it as a start.
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.
Proposed new shape for 3D Ellipsoid.
proposal for supporting arbitrary point meshes in 3D.
The offset is ignored in this method and similar ones:
https://github.com/mathnet/mathnet-spatial/blob/master/src/Spatial/Euclidean/CoordinateSystem.cs#L432
What you have to do is to convert the vector from (x,y,z) to (x,y,z,1) and multiply it with the matrix, then divide (x,y,z) with the value of w and return (x,y,z).
Hello guys,
first of all thank you for your effort on this project.
I was wondering if you had plans to release a signed version of spatial like numerics
https://www.nuget.org/packages/MathNet.Numerics.Signed/
Cheers,
Francois
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.
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?
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?
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
It seems odd for the points to include knowledge of the optional coordinatesystem when they are simply arbitrary points in space. The implementation of which is simply a call from the passed coordinate system in the first place.
I propose to obsolete these methods.
I would like to contribute some code for geometric intersection tests to this library as written about here in this article I wrote on GameDev.net.
I'm assuming of course that the project is intended for something like this.
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.
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.
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.
This would affect equality and it does not make any sense to have a direction property if it is unordered.
An alternative could perhaps be two types Line2D
and DirectedLine2D
might be confusing.
Proposal for a cone with support for obtaining conic sections.
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.
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?
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.
I'm working on a project where I need a Circle3D from three points. I will implement this and submit a pull request.
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
Proposed new shape Ellipse2D - a curve in a plane with two focal points.
I don't know this stuff well but don't see a huge downside to signing. @cdrnet
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.