private static void calculateConnectorNodeEffects(
NodeWorldObject nodeRepresentation,
MapWaySegment line1, MapWaySegment line2,
boolean inbound1, boolean inbound2) {
NetworkWaySegmentWorldObject renderable1 =
((NetworkWaySegmentWorldObject)line1.getPrimaryRepresentation());
NetworkWaySegmentWorldObject renderable2 =
((NetworkWaySegmentWorldObject)line2.getPrimaryRepresentation());
VisibleConnectorNodeWorldObject visibleConnectorRep = null;
if (nodeRepresentation instanceof VisibleConnectorNodeWorldObject) {
visibleConnectorRep =
(VisibleConnectorNodeWorldObject)nodeRepresentation;
}
/* calculate cut as angle bisector between the two lines */
VectorXZ inVector = line1.getDirection();
VectorXZ outVector = line2.getDirection();
if (!inbound1) { inVector = inVector.invert(); }
if (inbound2) { outVector = outVector.invert(); }
VectorXZ cutVector;
if (inVector.equals(outVector)) { //TODO: allow for some small difference?
cutVector = outVector.rightNormal();
} else {
cutVector = outVector.subtract(inVector);
cutVector = cutVector.normalize();
}
//make sure that cutVector points to the right, which is equivalent to:
//y component of the cross product (inVector x cutVector) is positive.
//If this isn't the case, invert the cut vector.
if (inVector.z * cutVector.x - inVector.x * cutVector.z <= 0) {
cutVector = cutVector.invert();
}
/* set calculated cut vector */
if (inbound1) {
renderable1.setEndCutVector(cutVector);
} else {
renderable1.setStartCutVector(cutVector.invert());
}
if (inbound2) {
renderable2.setEndCutVector(cutVector.invert());
} else {
renderable2.setStartCutVector(cutVector);
}
/* perform calculations necessary for connectors
* whose representation requires space */
double connectorLength = 0;
if (visibleConnectorRep != null) {
connectorLength = visibleConnectorRep.getLength();
}
if (connectorLength > 0) {
/* move connected lines to make room for the node's representation */
//connected node of line1 is moved orthogonally to the cut vector
VectorXZ offset1 = cutVector.rightNormal();
offset1 = offset1.mult(connectorLength / 2);
if (inbound1) {
renderable1.setEndOffset(offset1);
} else {
renderable1.setStartOffset(offset1);
}
//node of line2 is moved into the opposite direction
VectorXZ offset2 = offset1.invert();
if (inbound2) {
renderable2.setEndOffset(offset2);
} else {
renderable2.setStartOffset(offset2);
}
/* provide information to node's representation */
if (nodeRepresentation instanceof VisibleConnectorNodeWorldObject) {
VisibleConnectorNodeWorldObject connectorRep =
(VisibleConnectorNodeWorldObject)nodeRepresentation;
VectorXZ connectedPos1;
VectorXZ connectedPos2;
if (inbound1) {
connectedPos1 = line1.getEndNode().getPos();
} else {
connectedPos1 = line1.getStartNode().getPos();
}
if (inbound2) {
connectedPos2 = line2.getEndNode().getPos();
} else {
connectedPos2 = line2.getStartNode().getPos();
}
connectorRep.setInformation(
cutVector,
connectedPos1.add(offset1),
connectedPos2.add(offset2),
renderable1.getWidth(),
renderable2.getWidth());
}
//TODO: if done properly, this might affect NOT ONLY the directly adjacent lines