Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linesegment orthogonal point #926

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

RichMacDonald
Copy link
Contributor

Added an "orthogonal point" to LineSegment. Equivalent to closestPoint when it exists in the interior of the LineSegment. Null when the orthogonal point would be outside the LineSegment, i.e., projectionFactor < 0 or > 1.

@dr-jts
Copy link
Contributor

dr-jts commented Nov 7, 2022

This PR seems to eliminate the usage of LineSegment.project(p, pf) introduced in #924. Should it be removed?

@RichMacDonald
Copy link
Contributor Author

This PR seems to eliminate the usage of LineSegment.project(p, pf) introduced in #924. Should it be removed?

This PR was developed separately from $924, because I was not sure about pull request order. And there was a conflict between my pull requests.

I have merged the two together and pushed again. This branch should contain both changes.

* @param skip0 If true, do not check p0. Client will have determined this is redundant.
* @return a Coordinate which is the closest point on the line segment to the point p
*/
public Coordinate closestPoint(Coordinate p, boolean skip0)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a use case for this method?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See the caller in the pull request. For the DistanceOp point-linesegment calculation, each linesegment shares an endpoint. The existing code checks each linesegment in sequence and possibly both endpoints of the linesegment. So the shared endpoints could be checked twice, unnecessarily.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How much of a performance improvement does this create?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably better to localize this method to the DistanceOp class

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably better to localize this method to the DistanceOp class

There is your use case for orthogonalPoint.

@dr-jts
Copy link
Contributor

dr-jts commented Nov 8, 2022

What is the use case for orthogonalPoint?

@dr-jts
Copy link
Contributor

dr-jts commented Nov 8, 2022

This PR introduces another method overload of closestPoint. That should be mentioned in the description.

And is there really a use case for that method?

@dr-jts
Copy link
Contributor

dr-jts commented Nov 8, 2022

I'm not keen on introducing new methods which don't seem to have a broadly applicable semantics or use case. If you need them for you own code you can easily subclass LineSegment, or make some external functions.

@RichMacDonald
Copy link
Contributor Author

What is the use case for orthogonalPoint?

Checking the line when the endpoints have already been checked by some other means. In geospatial applications endpoint checking is relatively straightforward, while lines require map-projections (distortions) which are a lot slower.

@@ -428,7 +428,7 @@ private void computeMinDistance(LineString line, Point pt,
if (dist < minDistance) {
minDistance = dist;
LineSegment seg = new LineSegment(coord0[i], coord0[i + 1]);
Coordinate segClosestPoint = seg.closestPoint(coord);
Coordinate segClosestPoint = seg.closestPoint(coord, i > 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're looking to scavenge performance, perhaps this functionality should be provided as a static function? Probably on LineSegment. I've been thinking that many of the LineSegment methods could also be provided as static functions, for one-off use cases.

It really needs some performance testing, though - too easy to prematurely optimize.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have 10 LineSegments, each getting closer to the point, then the current code does 10 point-to-line and 11+10=19 point-to-point calculations. Each intermediate point is calculated twice. There should only be 10 point-to-line and 11 point-to-point calculations.

Pertinent to your other comment, I agree the skip0 boolean is an obscure solution. Better for the DistanceOp to explicitly do the point-to-line and point-to-point calculations separately, with point-to-line being of the form orthgonalPoint-to-line.

And static functions also make sense. You don't need to instantiate a LineSegment just to do a calculation then throw it away. Bad for the garbage-collector. Now if LineSegments and their attributes were declared final, then maybe they would be comparable, but that isn't currently an option.

The code below is problematic as well, because it first does the calculation without instances in Distance.pointToSegment() and then repeats the calculation with instances seg.closestPoint. If you separate point-to-point and orthogonalPoint-to-line, I think you can eliminate the duplication.

double dist = Distance.pointToSegment( coord, coord0[i], coord0[i + 1] );
if (dist < minDistance) {
minDistance = dist;
LineSegment seg = new LineSegment(coord0[i], coord0[i + 1]);
Coordinate segClosestPoint = seg.closestPoint(coord); //This is the same calculation as Distance.pointToSegment!
}

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

Successfully merging this pull request may close these issues.

2 participants