package org.osm2world.core.map_data.data; import java.util.List; import org.osm2world.core.math.LineSegmentXZ; import org.osm2world.core.math.VectorXZ; import com.google.common.collect.ImmutableList; public class MapSegment { protected final MapNode startNode; protected final MapNode endNode; public MapSegment(MapNode startNode, MapNode endNode) { if (startNode == null || endNode == null) { throw new IllegalArgumentException(); } this.startNode = startNode; this.endNode = endNode; } public MapNode getStartNode() { return startNode; } public MapNode getEndNode() { return endNode; } public MapNode getOtherNode(MapNode node) { if (node == startNode) { return endNode; } else if (node == endNode) { return startNode; } else { throw new IllegalArgumentException("not a node of this segment"); } } public List<MapNode> getStartEndNodes() { return ImmutableList.of(startNode, endNode); } public LineSegmentXZ getLineSegment() { return new LineSegmentXZ(startNode.getPos(), endNode.getPos()); } /** caches the result for {@link #getDirection()} */ private VectorXZ direction = null; /** caches the result for {@link #getRightNormal()} */ private VectorXZ rightNormal = null; /** * returns a normalized vector indicating the line's horizontal direction */ public VectorXZ getDirection() { if (direction == null) { direction = endNode.getPos().subtract(startNode.getPos()); direction = direction.normalize(); //TODO: (performance) getDirection method in VectorXZ? } return direction; } /** * returns a the result of applying {@link VectorXZ#rightNormal()} * to vector returned by {@link #getDirection()} */ public VectorXZ getRightNormal() { if (rightNormal == null) { rightNormal = getDirection().rightNormal(); } return rightNormal; } /** * returns the center of the line */ public VectorXZ getCenter() { return (startNode.getPos().add(endNode.getPos())).mult(0.5); } /** * returns true if this MapSegment shares a node with another MapSegment */ public boolean isConnectedTo(MapSegment other) { return endNode == other.getStartNode() || endNode == other.getEndNode() || startNode == other.getStartNode() || startNode == other.getEndNode(); } /** * returns true if this MapSegment shares a node with a MapArea */ public boolean isConnectedTo(MapArea other) { return other.getBoundaryNodes().contains(startNode) || other.getBoundaryNodes().contains(endNode); } /** * returns true if this MapSegment shares both nodes with another MapSegment */ public boolean sharesBothNodes(MapSegment other) { return (endNode == other.getStartNode() && startNode == other.getEndNode()) || (endNode == other.getEndNode() && startNode == other.getStartNode()); } }