-
Notifications
You must be signed in to change notification settings - Fork 442
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
base: master
Are you sure you want to change the base?
Linesegment orthogonal point #926
Conversation
This PR seems to eliminate the usage of |
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) |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 was a problem hiding this comment.
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.
What is the use case for |
This PR introduces another method overload of And is there really a use case for that method? |
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 |
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!
}
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.