Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Is there any need for different metrics to allow the user to specify how they want distance measured? #231

TacetDiscipulus started this conversation in Ideas
Discussion options

As it is the specified tolerance is compared against against each coordinate individually, almost a Manhattan metric, Does anyone have any input on adding the ability to allow a user to specify the metric of their choice? When I first saw the code I was a little surprised that tolerance was not compared against the Euclidean distance between points. It could be added without breaking code by adding an enum value as an additional parameter to the Equals functions that defaults to the current method but would allow a user to specify whatever metric they choose.

I'm not versed enough to even know for sure if the floating point type pass the triangle inequality for sure, I just don't know enough about the IEEE standard and how rounding errors would effect this.

You must be logged in to vote

Replies: 2 comments 5 replies

Comment options

To clarify the world of open source and community collaboration is brand new to me. Anything I worked on before was proprietary. So if this have posted this in the wrong place or I should go about this another way, fill me in.

To clarify my initial comment I was thinking about something like this.

public static class Metric
{
 public static double DistanceTo(Point2D p1, Point2D p2, MetricType metric)
 {
 switch (metric)
 {
 case Euclidean:
 return DistanceToEuclidean(p1, p2);
 case Manhattan:
 return DistanceToManhattan(p1, p2);
 ....
 }
 private static double DistanceToEuclidean(Point2D p1, Point p2)
 {
 return Math.Sqrt( (p1.X - p2.X)*(p1.X - p.X) +(p1.Y - p2.Y)*(p1.Y - p.Y));
 }
 private static double DistanceToManhattan(Point2D p1, Point p2)
 {
 return Math.Abs(p1.X - p2.X) + Math.Abs(p1.Y - p2.Y) 
 }
}

then include

pubic enum MetricType
{
 Euclidean,
 Manhattan,
 Chebyshev,
 Discrete,
 LP_1,
 LP_2,
 ...
}

I think it can be implemented by adding another parameter to any function computing or comparing point to point distances provided it defaults to the current behavior.

For example

For Point2D

 public double DistanceTo(Point2D otherPoint, MetricType metric = MetricType.Euclidean)
 { 
 return Metric.DistanceTo(p1, p2, metric) 
 }

Anyone see any value in this or is this too much for this library and NetTopologySuite is the place to go if you need this sort of fine
grained control?

You must be logged in to vote
1 reply
Comment options

jkalias Apr 23, 2023
Collaborator

To clarify the world of open source and community collaboration is brand new to me. Anything I worked on before was proprietary. So if this have posted this in the wrong place or I should go about this another way, fill me in.

I think this is the right place here. This feels more like a discussion rather than a bug or enhancement issue.

Comment options

I am not really familiar with NetTopologySuite and where it's used.

It seems we have a discrepancy here, in which one the one hand we calculate distances based on the Euclidean metric but we use the tolerance for equality comparison in a Manhattan-style metric.

I don't know where this might cause problems to be honest.

You must be logged in to vote
4 replies
Comment options

I have never used NetTopologSuite myself, but from what I have heard it is a powerful library and is one of the go to library for serious mathematics when using .NET.

I can imagine a few possibilities where it could could cause a problem. Suppose you are doing work that requires a very small and a very precise maximum tolerance, by using the Manhattan metric the tolerance could actually be larger which may cause a user to accept a result which their specifications dictate should be rejected.

Just general consistency throughout the library seems like a good idea to me. Maybe my initial idea of introducing a Metric class was a bit extreme as I don't really see too many other places where it would be useful. What are your thoughts on just changing the code so tolerances are compared against the the Euclidean distance?

My gut feeling is that most users would assume the Euclidean metric is being used, I would bet that a large portion of users have never even come across the concept of a metric space or there being different ways of defining the distance between two points, to them distance is intimately tied to Pythagoras theorem. Perhaps it's just me but it seems wrong to introduce a different measure of distance in one and only one place and then have it be different from what the user would naturally expect.

BTW I took a shot at fixing some of the serialization unit tests like protocol buffers and JSON, I didn't see any errors in the code and the code seems to match the documentation for the Newtonsoft JSON library perfectly. I did notice one odd thing, I believe it was the JSON tests for serializing Angle, Things were being serialized that should not have been (Sin, Cos, and Tan), which is probably related to deserialization failing when Angle only requires Radians and that's why the RoundTrip keeps returning an Ange with 0 Radians (the default I believe) and failing the test. I'll be right up front on this though, I have next to zero knowledge on subject, I'm just starting with C# and any serialization I have ever needed was in C++ and binary met my requirements, I am willing to learn though.

Comment options

jkalias May 5, 2023
Collaborator

Just general consistency throughout the library seems like a good idea to me. Maybe my initial idea of introducing a Metric class was a bit extreme as I don't really see too many other places where it would be useful. What are your thoughts on just changing the code so tolerances are compared against the the Euclidean distance?

Yes, I think your expectation is reasonable, and based on the principle of least surprise, we should change this. Would you mind sending a PR?

BTW I took a shot at fixing some of the serialization unit tests like protocol buffers and JSON, I didn't see any errors in the code and the code seems to match the documentation for the Newtonsoft JSON library perfectly. I did notice one odd thing, I believe it was the JSON tests for serializing Angle, Things were being serialized that should not have been (Sin, Cos, and Tan), which is probably related to deserialization failing when Angle only requires Radians and that's why the RoundTrip keeps returning an Ange with 0 Radians (the default I believe) and failing the test. I'll be right up front on this though, I have next to zero knowledge on subject, I'm just starting with C# and any serialization I have ever needed was in C++ and binary met my requirements, I am willing to learn though.

Serialization is another big mess, and there are already open issues with either XML or JSON. Since there is already an existing serialization branch, I'd rather keep things separated. My main concern is, that I don't see any interest in other maintainers actively addressing the existing issues, and I feel a bit like a lonely fighter.

Comment options

As I'm sure I've said, I'm just learning C# now and have never participated in a project hosted on GitHub, If you have the patience for those two things then then I would be happy to contribute. To be upfront about it, this seems like the perfect project for me to begin with, I have a some knowledge on the math end, the library is simple enough that even with my limited C# I should still be able to contribute without breaking everything, and finally I have put this library to good work so contributing seems fair. So if you want a collaborator, I'm in.

I have a few ideas that could be useful like vector projections, really a lot straight out of a first year linear algebra course could be useful. I haven't looked to deep into MathNet.Numerics.LinearAlgebra, it it possible some of my ideas already exists there.

I personally have a need for a decent function to test if three points are colinear, but so many of the results I've seen posted around StackOverflow and elsewhere just won't cut it. One method calculates the area of the triangle formed by the points and compares against a tolerance, this isn't the greatest if your points are separated by a significant distance as the area can be large if one point deviates from the line by a even the smallest distance. I thought about implementing a function that takes the three (or more) points and a tolerance, calculates the line of best fit then comparing R-squared against the tolerance but I wasn't sure how well that would have gone over.

Once I read how to send the PR I will do it. Like I said... totally new to GH,

Comment options

jkalias May 6, 2023
Collaborator

As I'm sure I've said, I'm just learning C# now and have never participated in a project hosted on GitHub, If you have the patience for those two things then then I would be happy to contribute. To be upfront about it, this seems like the perfect project for me to begin with, I have a some knowledge on the math end, the library is simple enough that even with my limited C# I should still be able to contribute without breaking everything, and finally I have put this library to good work so contributing seems fair. So if you want a collaborator, I'm in.

No worries, we all started from the same spot. I am also no expert, I just use the tools. This documentation will certainly bring you up to speed, as well as their own git client, it takes care of many things.

I would be happy to help.

I have a few ideas that could be useful like vector projections, really a lot straight out of a first year linear algebra course could be useful. I haven't looked to deep into MathNet.Numerics.LinearAlgebra, it it possible some of my ideas already exists there.

MathNET.Numerics is a generic numerics package, not specific to geometry, so I am not really sure that you will find there what you are looking for. It certainly is though quite powerful.

I personally have a need for a decent function to test if three points are colinear, but so many of the results I've seen posted around StackOverflow and elsewhere just won't cut it. One method calculates the area of the triangle formed by the points and compares against a tolerance, this isn't the greatest if your points are separated by a significant distance as the area can be large if one point deviates from the line by a even the smallest distance. I thought about implementing a function that takes the three (or more) points and a tolerance, calculates the line of best fit then comparing R-squared against the tolerance but I wasn't sure how well that would have gone over.

My approach would be to check the direction vectors created from these points. Say you have points p1, p2 and p3; then these span the directions p12 = p2 - p1 and p13 = p3 - p1. Then I would check that p12 is collinear (parallel or antiparallel) to p13.

Once I read how to send the PR I will do it. Like I said... totally new to GH,

Great! Have fun

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
Ideas
Labels
None yet

AltStyle によって変換されたページ (->オリジナル) /