abstract class AbstractSegment extends Object implements Segment, Vector, Iterable<Segment>
Segment
s in this project. Each AbstractSegment
may be split into two other AbstractSegment
s, 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 Segment
s 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
Segment s. |
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, wait
forEach, spliterator
protected 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.null
public boolean shouldIgnore()
Segment
Segment
was split into two new
Segment
s.
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 Segment
Segment.splitAt(Node,SplitQueueListener)
public Node midPoint()
NodePair
public void splitCloseParallels(SplitQueueListener listener)
splitCloseParallels
in interface Segment
public Collection<Segment> splitTargets()
splitTargets
in interface Segment
public Node findPerpendicularFoot(Node node)
findPerpendicularFoot
in interface Segment
public void splitAt(Node node, SplitQueueListener listener)
Segment
Segment
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 Segment
Segment.shouldIgnore()
public Iterator<Segment> iterator()
iterator
in interface Iterable<Segment>
AbstractSegment
,
AbstractSegment.FragmentIterator
public void addBestLeftMatch(Segment bestMatch)
addBestLeftMatch
in interface Segment
public void addBestRightMatch(Segment bestMatch)
addBestRightMatch
in interface Segment
public int compareTo(Segment other)
compareTo
in interface Comparable<Segment>
public Node other(Node node)
NodePair
public double easting()
Vector
public double northing()
Vector
public double distance()
NodePair
public double bearing()
Vector
Math
.
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 Vector
SimpleVector.normaliseAbsoluteBearing(double)
,
Bearing (Wikipedia)double bearingDegrees()
public double relativeBearing(Vector v)
relativeBearing
in interface Vector
v
- 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()
Vector
void 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 Vector
v
- the vector to be compared with this onev
Vector.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 Vector
v
- the vector to be compared with this oneVector.relativeBearing(de.thaw.comb.util.Vector)