abstract class AbstractSegment extends Object implements Segment, Vector, Iterable<Segment>
Segments in this project. Each AbstractSegment
may be split into two other AbstractSegments, yielding a
recursive composition, implemented as a Composite pattern, with this
abstract class defining the "Component" participant. Concrete
implementations of this class participate either as "Leaf" or as
"Composite", depending on whether or not fragments (children) exist.
This class implements the Iterable interface such that
iteration is performed on all Leafs in the composition. In other words,
the iterator touches every fragment created by splitting. For example, if
this segment has been split exactly once, the iterator touches 2 fragments;
if this segment has been split twice, the iterator touches 3 fragments. If
this segment has never been split, the iterator touches only 1 fragment,
which is this segment itself. The iterator always touches at least 1
fragment. Note that fragments are Segments themselves.
Because of this it is easy to have loops touch every fragment of this segment, even if it was split many times:
for (Segment fragment : segment) { ... }
| Modifier and Type | Class and Description |
|---|---|
(package private) static class |
AbstractSegment.Fragment
A
Segment implementation representing incomplete
fragments of segments read from source data. |
(package private) class |
AbstractSegment.FragmentIterator
An iterator to perform a depth-first traversal of the Composite tree
below this segment, returning all Leafs.
|
| Modifier and Type | Field and Description |
|---|---|
protected Node |
end |
protected AbstractSegment[] |
fragments
The children of this Composite in the composition (if any).
|
(package private) static double |
MIN_FRAGMENT_LENGTH |
protected Node |
start |
FULL_CIRCLE, RIGHT_ANGLE, SEMI_CIRCLE| Constructor and Description |
|---|
AbstractSegment(Node start,
Node end) |
| Modifier and Type | Method and Description |
|---|---|
void |
addBestLeftMatch(Segment bestMatch) |
void |
addBestRightMatch(Segment bestMatch) |
Vector |
aligned(Vector v)
Compares this vector to the specified vector with regards to their
convergence.
|
void |
analyse(Analyser visitor) |
double |
bearing()
The angle from grid north to the vector's direction, measured clockwise.
|
(package private) double |
bearingDegrees() |
int |
compareTo(Segment other) |
double |
distance()
The distance of the two nodes.
|
double |
easting()
The ordinate (horizontal / longitudinal) aspect of the vector's
coordinate representation.
|
Node |
end() |
Node |
findPerpendicularFoot(Node node) |
boolean |
isAligned(Vector v)
Compares this vector's bearing to the specified vector's bearing.
|
Iterator<Segment> |
iterator()
An iterator over all segments, including any fragments this
segment may have been split up into.
|
Node |
midPoint()
A node located exactly half-way between the two nodes.
|
double |
northing()
The abscissa (vertical / latitudinal) aspect of the vector's
coordinate representation.
|
Node |
other(Node node)
The opposite node of the pair.
|
protected abstract AbstractSegment |
parent()
The parent of this object in the composition tree.
|
double |
relativeBearing(Vector v)
The angle from this vector's direction to the specified vector's
direction, measured counterclockwise or clockwise, whichever is nearer.
|
(package private) void |
reverse() |
Vector |
reversed()
Returns a reversed representation of this vector.
|
SourceSegment |
root() |
boolean |
shouldIgnore()
Whether this
Segment was split into two new
Segments. |
void |
splitAt(Node node,
SplitQueueListener listener)
Split this
Segment at the given node. |
void |
splitCloseParallels(SplitQueueListener listener) |
Collection<Segment> |
splitTargets() |
Node |
start() |
String |
toString() |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, waitforEach, spliteratorprotected Node start
protected Node end
protected AbstractSegment[] fragments
null iff this object does not represent a Composite, but a
Leaf. A split converts this object from a Leaf into a Composite by
assigning a non-null value to this field; in particular, a split creates
exactly two fragments, thus an array of size 2 must be assigned.static final double MIN_FRAGMENT_LENGTH
public SourceSegment root()
protected abstract AbstractSegment parent()
null if this object is the root of the tree.nullpublic boolean shouldIgnore()
SegmentSegment was split into two new
Segments.
The SPLITTEN algorithm is defined to remove the original segment that was split into two parts from the collection of line parts to be split. Keeping the original would only duplicate work as the splitting is based on nodes, and both of the original's nodes are also present in its two parts after it was split. Rather than removing (which would likely be expensive), we introduce a simple flag to skip any line part that has already been split.
shouldIgnore in interface SegmentSegment.splitAt(Node,SplitQueueListener)public Node midPoint()
NodePairpublic void splitCloseParallels(SplitQueueListener listener)
splitCloseParallels in interface Segmentpublic Collection<Segment> splitTargets()
splitTargets in interface Segmentpublic Node findPerpendicularFoot(Node node)
findPerpendicularFoot in interface Segmentpublic void splitAt(Node node, SplitQueueListener listener)
SegmentSegment at the given node. This
Segment will be marked as having been split so that it
will be ignored by future processing steps. The split will be reported
to the split queue listener so that the two fragments created by the
split can again be used for splitting.splitAt in interface SegmentSegment.shouldIgnore()public Iterator<Segment> iterator()
iterator in interface Iterable<Segment>AbstractSegment,
AbstractSegment.FragmentIteratorpublic void addBestLeftMatch(Segment bestMatch)
addBestLeftMatch in interface Segmentpublic void addBestRightMatch(Segment bestMatch)
addBestRightMatch in interface Segmentpublic int compareTo(Segment other)
compareTo in interface Comparable<Segment>public Node other(Node node)
NodePairpublic double easting()
Vectorpublic double northing()
Vectorpublic double distance()
NodePairpublic double bearing()
VectorMath.
For example, if a vector pointed to the west, this method would return 3/2 π (equal to 270°).
It is strongly recommended for implementations to return bearings normalised to the interval [0, 2 π), but clients should not depend upon this behaviour.
bearing in interface VectorSimpleVector.normaliseAbsoluteBearing(double),
Bearing (Wikipedia)double bearingDegrees()
public double relativeBearing(Vector v)
relativeBearing in interface Vectorv - the vector to calculate the bearing of in relation to this
vector0.0 if v is zero-lengthSimpleVector.normaliseRelativeBearing(double),
Relative bearing (Wikipedia)public Vector reversed()
Vectorvoid reverse()
public Vector aligned(Vector v)
Vector
return isAligned(v) ? clone() : reversed();
If the vectors already are aligned, implementations are free to return
either this itself or another Vector object of
equivalent value, at their option.aligned in interface Vectorv - the vector to be compared with this onevVector.isAligned(de.thaw.comb.util.Vector)public boolean isAligned(Vector v)
Vector
Implementations might use code that basically produces the same result
as the following line does:
The result of this method if the vectors are orthogonal is undefined.
return Math.abs( relativeBearing(v) ) < RIGHT_ANGLE;
isAligned in interface Vectorv - the vector to be compared with this oneVector.relativeBearing(de.thaw.comb.util.Vector)