Imagine a LineSegment
class that represents a line segment using two arbitrary endpoints.
Should the constructor throw if it is passed two approximately equal endpoints? Obviously this would require some arbitrary floating point comparison. For example, test the Euclidean distance between the endpoints is less than ε.
An advantage is users aren’t going to get nonsense answers to certain questions if they construct a LineSegment
with floating point noise, or two points that “should” be equal but diverged due to error in floating point calculations. For example, it would otherwise be dangerous if the user asked the direction a line segment was pointed.
A disadvantage is that the class now needs to try to encapsulate and maintain this requirement on the state of the two endpoints. Moving an endpoint of the LineSegment
would have the potential to throw.
Imagine a PolyLine
class that uses these LineSegment
under the hood. If the user wants to insert a new point in the PolyLine
it could throw if that point is within ε of another point. Would a SafeInsert
need to delete all nearby points? Could users tolerate a SafeInsert
that potentially reduced the size of their PolyLine? Even deleting a point could throw, because it could bring together two approximately equal points.
The alternative to throwing in the constructors is to skip validation, and rely on users to call a Douglas-Peucker or related algorithm if there is risk their LineSegment
or PolyLine
data would provide unreasonable answers. Users would provide their own ε when they used this function.
Is anyone familiar with existing implementations of LineSegment
or PolyLine
classes that prefer one approach to the other?